From eb24884684afffde9c10e636e07b8612a0958b2f Mon Sep 17 00:00:00 2001 From: weishu Date: Wed, 27 Mar 2024 11:51:41 +0800 Subject: [PATCH] kernel: alloc path on stack; don't follow symlink --- kernel/throne_tracker.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/kernel/throne_tracker.c b/kernel/throne_tracker.c index c5749defbc1d..f05cad495879 100644 --- a/kernel/throne_tracker.c +++ b/kernel/throne_tracker.c @@ -120,25 +120,26 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name, struct my_dir_context *my_ctx = container_of(ctx, struct my_dir_context, ctx); struct file *file; - char *dirpath; + char dirpath[384]; // 384 is enough for /data/app//base.apk if (!my_ctx) { pr_err("Invalid context\n"); return FILLDIR_ACTOR_STOP; } if (my_ctx->stop && *my_ctx->stop) { + pr_info("Stop searching\n"); return FILLDIR_ACTOR_STOP; } if (!strncmp(name, "..", namelen) || !strncmp(name, ".", namelen)) return FILLDIR_ACTOR_CONTINUE; // Skip "." and ".." - dirpath = kmalloc(PATH_MAX, GFP_KERNEL); - if (!dirpath) { - return FILLDIR_ACTOR_STOP; // Failed to obtain directory path + if (snprintf(dirpath, sizeof(dirpath), "%s/%.*s", my_ctx->parent_dir, + namelen, name) >= sizeof(dirpath)) { + pr_err("Path too long: %s/%.*s\n", my_ctx->parent_dir, namelen, + name); + return FILLDIR_ACTOR_CONTINUE; } - snprintf(dirpath, PATH_MAX, "%s/%.*s", my_ctx->parent_dir, namelen, - name); if (d_type == DT_DIR && my_ctx->depth > 0 && (my_ctx->stop && !*my_ctx->stop)) { @@ -148,7 +149,7 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name, my_ctx->private_data, .depth = my_ctx->depth - 1, .stop = my_ctx->stop }; - file = ksu_filp_open_compat(dirpath, O_RDONLY, 0); + file = ksu_filp_open_compat(dirpath, O_RDONLY | O_NOFOLLOW, 0); if (IS_ERR(file)) { pr_err("Failed to open directory: %s, err: %ld\n", dirpath, PTR_ERR(file)); @@ -185,7 +186,7 @@ void search_manager(const char *path, int depth, struct list_head *uid_data) .depth = depth, .stop = &stop }; - file = ksu_filp_open_compat(path, O_RDONLY, 0); + file = ksu_filp_open_compat(path, O_RDONLY | O_NOFOLLOW, 0); if (IS_ERR(file)) { pr_err("Failed to open directory: %s\n", path); return;