kernel: alloc path on stack; don't follow symlink
This commit is contained in:
@@ -120,25 +120,26 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
|
|||||||
struct my_dir_context *my_ctx =
|
struct my_dir_context *my_ctx =
|
||||||
container_of(ctx, struct my_dir_context, ctx);
|
container_of(ctx, struct my_dir_context, ctx);
|
||||||
struct file *file;
|
struct file *file;
|
||||||
char *dirpath;
|
char dirpath[384]; // 384 is enough for /data/app/<package>/base.apk
|
||||||
|
|
||||||
if (!my_ctx) {
|
if (!my_ctx) {
|
||||||
pr_err("Invalid context\n");
|
pr_err("Invalid context\n");
|
||||||
return FILLDIR_ACTOR_STOP;
|
return FILLDIR_ACTOR_STOP;
|
||||||
}
|
}
|
||||||
if (my_ctx->stop && *my_ctx->stop) {
|
if (my_ctx->stop && *my_ctx->stop) {
|
||||||
|
pr_info("Stop searching\n");
|
||||||
return FILLDIR_ACTOR_STOP;
|
return FILLDIR_ACTOR_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strncmp(name, "..", namelen) || !strncmp(name, ".", namelen))
|
if (!strncmp(name, "..", namelen) || !strncmp(name, ".", namelen))
|
||||||
return FILLDIR_ACTOR_CONTINUE; // Skip "." and ".."
|
return FILLDIR_ACTOR_CONTINUE; // Skip "." and ".."
|
||||||
|
|
||||||
dirpath = kmalloc(PATH_MAX, GFP_KERNEL);
|
if (snprintf(dirpath, sizeof(dirpath), "%s/%.*s", my_ctx->parent_dir,
|
||||||
if (!dirpath) {
|
namelen, name) >= sizeof(dirpath)) {
|
||||||
return FILLDIR_ACTOR_STOP; // Failed to obtain directory path
|
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 &&
|
if (d_type == DT_DIR && my_ctx->depth > 0 &&
|
||||||
(my_ctx->stop && !*my_ctx->stop)) {
|
(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,
|
my_ctx->private_data,
|
||||||
.depth = my_ctx->depth - 1,
|
.depth = my_ctx->depth - 1,
|
||||||
.stop = my_ctx->stop };
|
.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)) {
|
if (IS_ERR(file)) {
|
||||||
pr_err("Failed to open directory: %s, err: %ld\n",
|
pr_err("Failed to open directory: %s, err: %ld\n",
|
||||||
dirpath, PTR_ERR(file));
|
dirpath, PTR_ERR(file));
|
||||||
@@ -185,7 +186,7 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
|
|||||||
.depth = depth,
|
.depth = depth,
|
||||||
.stop = &stop };
|
.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)) {
|
if (IS_ERR(file)) {
|
||||||
pr_err("Failed to open directory: %s\n", path);
|
pr_err("Failed to open directory: %s\n", path);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user