Skip to content

Commit

Permalink
throne_tracker: avoid nested iterate_dir()
Browse files Browse the repository at this point in the history
Nested iterate_dir() within the same shared parent directory is an
unsupported behavior and may cause deadlock when other processes
access files under the same directory.

Avoid it by using a linked-list and processing it after directory
traversal is done.

[24928.245837] sysrq: Show Blocked State
[24928.247448] task:binder:1535_1   state:D stack:    0 pid: 1594 ppid:     1 flags:0x04000000
[24928.247462] Call trace:
[24928.247471] __switch_to+0x148/0x250
[24928.247480] __schedule+0x454/0x6ec
[24928.247488] schedule+0x7c/0x118
[24928.247498] rwsem_down_read_slowpath+0x4c0/0x9b8
[24928.247506] down_read_killable+0x3c/0x174
[24928.247519] iterate_dir+0x40/0x184
[24928.247528] __arm64_sys_getdents64+0x58/0x148
[24928.247540] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.247548] do_el0_svc+0x24/0x90
[24928.247559] el0_svc+0x10/0x1c
[24928.247567] el0_sync_handler+0xcc/0xe4
[24928.247576] el0_sync+0x1a0/0x1c0
[24928.247586] task:binder:1535_4   state:D stack:    0 pid: 2679 ppid:     1 flags:0x04000000
[24928.247597] Call trace:
[24928.247605] __switch_to+0x148/0x250
[24928.247613] __schedule+0x454/0x6ec
[24928.247621] schedule+0x7c/0x118
[24928.247629] rwsem_down_write_slowpath+0x44c/0xbd4
[24928.247637] down_write+0x94/0x138
[24928.247648] do_renameat2+0x1e4/0x4b4
[24928.247658] __arm64_sys_renameat2+0x68/0x84
[24928.247667] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.247675] do_el0_svc+0x24/0x90
[24928.247683] el0_svc+0x10/0x1c
[24928.247691] el0_sync_handler+0xcc/0xe4
[24928.247698] el0_sync+0x1a0/0x1c0
[24928.247706] task:binder:1535_5   state:D stack:    0 pid: 2680 ppid:     1 flags:0x04000000
[24928.247716] Call trace:
[24928.247724] __switch_to+0x148/0x250
[24928.247731] __schedule+0x454/0x6ec
[24928.247738] schedule+0x7c/0x118
[24928.247746] rwsem_down_read_slowpath+0x4c0/0x9b8
[24928.247753] down_read_killable+0x3c/0x174
[24928.247760] iterate_dir+0x40/0x184
[24928.247767] __arm64_sys_getdents64+0x58/0x148
[24928.247775] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.247783] do_el0_svc+0x24/0x90
[24928.247791] el0_svc+0x10/0x1c
[24928.247798] el0_sync_handler+0xcc/0xe4
[24928.247805] el0_sync+0x1a0/0x1c0
[24928.247815] task:binder:1535_9   state:D stack:    0 pid: 2684 ppid:     1 flags:0x04000000
[24928.247825] Call trace:
[24928.247832] __switch_to+0x148/0x250
[24928.247839] __schedule+0x454/0x6ec
[24928.247846] schedule+0x7c/0x118
[24928.247853] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.247860] down_read+0x3c/0x164
[24928.247869] lookup_slow+0x2c/0x60
[24928.247877] link_path_walk+0x31c/0x380
[24928.247884] path_lookupat+0x68/0x11c
[24928.247891] filename_lookup+0x88/0x17c
[24928.247901] vfs_statx+0x9c/0x1b0
[24928.247908] __arm64_sys_newfstatat+0x34/0x5c
[24928.247916] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.247924] do_el0_svc+0x24/0x90
[24928.247932] el0_svc+0x10/0x1c
[24928.247939] el0_sync_handler+0xcc/0xe4
[24928.247946] el0_sync+0x1a0/0x1c0
[24928.248384] task:AnrConsumer     state:D stack:    0 pid:12893 ppid:  1158 flags:0x04000800
[24928.248396] Call trace:
[24928.248403] __switch_to+0x148/0x250
[24928.248411] __schedule+0x454/0x6ec
[24928.248418] schedule+0x7c/0x118
[24928.248426] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.248433] down_read+0x3c/0x164
[24928.248440] lookup_slow+0x2c/0x60
[24928.248448] link_path_walk+0x31c/0x380
[24928.248456] path_lookupat+0x68/0x11c
[24928.248464] filename_lookup+0x88/0x17c
[24928.248474] user_statfs+0x44/0x1c4
[24928.248481] __arm64_sys_statfs+0x28/0x104
[24928.248490] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.248498] do_el0_svc+0x24/0x90
[24928.248506] el0_svc+0x10/0x1c
[24928.248514] el0_sync_handler+0xcc/0xe4
[24928.248520] el0_sync+0x1a0/0x1c0
[24928.249471] task:binder:4694_6   state:D stack:    0 pid: 7417 ppid:  1158 flags:0x04000800
[24928.249488] Call trace:
[24928.249502] __switch_to+0x148/0x250
[24928.249509] __schedule+0x454/0x6ec
[24928.249514] schedule+0x7c/0x118
[24928.249524] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.249531] down_read+0x3c/0x164
[24928.249538] lookup_slow+0x2c/0x60
[24928.249547] link_path_walk+0x31c/0x380
[24928.249554] path_openat+0x84/0xacc
[24928.249559] do_filp_open+0x6c/0xf8
[24928.249568] do_sys_openat2+0x7c/0x1e8
[24928.249576] __arm64_sys_openat+0x64/0x74
[24928.249584] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.249589] do_el0_svc+0x24/0x90
[24928.249632] el0_svc+0x10/0x1c
[24928.249640] el0_sync_handler+0xcc/0xe4
[24928.249645] el0_sync+0x1a0/0x1c0
[24928.250868] task:othing.launcher state:D stack:    0 pid:29301 ppid:  1158 flags:0x04000801
[24928.250880] Call trace:
[24928.250887] __switch_to+0x148/0x250
[24928.250894] __schedule+0x454/0x6ec
[24928.250899] schedule+0x7c/0x118
[24928.250905] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.250910] down_read+0x3c/0x164
[24928.250916] lookup_slow+0x2c/0x60
[24928.250922] link_path_walk+0x31c/0x380
[24928.250928] path_openat+0x84/0xacc
[24928.250934] do_filp_open+0x6c/0xf8
[24928.250941] do_sys_openat2+0x7c/0x1e8
[24928.250947] __arm64_sys_openat+0x64/0x74
[24928.250954] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.250959] do_el0_svc+0x24/0x90
[24928.250965] el0_svc+0x10/0x1c
[24928.250970] el0_sync_handler+0xcc/0xe4
[24928.250976] el0_sync+0x1a0/0x1c0
[24928.251020] task:BG Thread tiann#1    state:D stack:    0 pid: 9009 ppid:  1158 flags:0x04000800
[24928.251027] Call trace:
[24928.251033] __switch_to+0x148/0x250
[24928.251039] __schedule+0x454/0x6ec
[24928.251044] schedule+0x7c/0x118
[24928.251050] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.251056] down_read+0x3c/0x164
[24928.251062] lookup_slow+0x2c/0x60
[24928.251069] link_path_walk+0x31c/0x380
[24928.251075] path_openat+0x84/0xacc
[24928.251080] do_filp_open+0x6c/0xf8
[24928.251086] do_sys_openat2+0x7c/0x1e8
[24928.251092] __arm64_sys_openat+0x64/0x74
[24928.251098] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.251104] do_el0_svc+0x24/0x90
[24928.251111] el0_svc+0x10/0x1c
[24928.251116] el0_sync_handler+0xcc/0xe4
[24928.251121] el0_sync+0x1a0/0x1c0
[24928.253819] task:Thread-221      state:D stack:    0 pid:11089 ppid:  1158 flags:0x04000809
[24928.253838] Call trace:
[24928.253849] __switch_to+0x148/0x250
[24928.253857] __schedule+0x454/0x6ec
[24928.253866] schedule+0x7c/0x118
[24928.253873] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.253878] down_read+0x3c/0x164
[24928.253885] lookup_slow+0x2c/0x60
[24928.253895] link_path_walk+0x31c/0x380
[24928.253901] path_openat+0x84/0xacc
[24928.253907] do_filp_open+0x6c/0xf8
[24928.253914] do_sys_openat2+0x7c/0x1e8
[24928.253922] __arm64_sys_openat+0x64/0x74
[24928.253929] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.253934] do_el0_svc+0x24/0x90
[24928.253941] el0_svc+0x10/0x1c
[24928.253949] el0_sync_handler+0xcc/0xe4
[24928.253954] el0_sync+0x1a0/0x1c0
[24928.254415] task:kworker/u32:3   state:D stack:    0 pid:10599 ppid:     2 flags:0x00000008
[24928.254435] Workqueue: kernelsu_work_queue do_update_uid.llvm.10243150712685858777
[24928.254442] Call trace:
[24928.254449] __switch_to+0x148/0x250
[24928.254458] __schedule+0x454/0x6ec
[24928.254463] schedule+0x7c/0x118
[24928.254469] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.254475] down_read+0x3c/0x164
[24928.254481] path_openat+0x19c/0xacc
[24928.254487] do_filp_open+0x6c/0xf8
[24928.254493] filp_open+0x88/0xac
[24928.254501] ksu_filp_open_compat+0x2c/0x238
[24928.254507] my_actor+0x150/0x200
[24928.254516] f2fs_fill_dentries+0x18c/0x2b4
[24928.254522] f2fs_readdir.llvm.12898971218442528687+0x170/0x3c4
[24928.254528] iterate_dir+0xa0/0x184
[24928.254537] do_update_uid.llvm.10243150712685858777+0x2dc/0x2f8
[24928.254547] process_scheduled_works+0x1c8/0x550
[24928.254554] worker_thread+0x340/0x724
[24928.254561] kthread+0x13c/0x178
[24928.254566] ret_from_fork+0x10/0x30
[24928.254665] task:SysUiBg         state:D stack:    0 pid:12113 ppid:  1158 flags:0x04000800
[24928.254686] Call trace:
[24928.254698] __switch_to+0x148/0x250
[24928.254710] __schedule+0x454/0x6ec
[24928.254724] schedule+0x7c/0x118
[24928.254738] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.254750] down_read+0x3c/0x164
[24928.254762] lookup_slow+0x2c/0x60
[24928.254776] link_path_walk+0x31c/0x380
[24928.254789] path_openat+0x84/0xacc
[24928.254802] do_filp_open+0x6c/0xf8
[24928.254816] do_sys_openat2+0x7c/0x1e8
[24928.254824] __arm64_sys_openat+0x64/0x74
[24928.254831] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.254837] do_el0_svc+0x24/0x90
[24928.254843] el0_svc+0x10/0x1c
[24928.254852] el0_sync_handler+0xcc/0xe4
[24928.254857] el0_sync+0x1a0/0x1c0
[24928.254924] task:facebook.katana state:D stack:    0 pid:12407 ppid:  1158 flags:0x04000801
[24928.254932] Call trace:
[24928.254939] __switch_to+0x148/0x250
[24928.254945] __schedule+0x454/0x6ec
[24928.254950] schedule+0x7c/0x118
[24928.254957] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.254965] down_read+0x3c/0x164
[24928.254970] lookup_slow+0x2c/0x60
[24928.254977] link_path_walk+0x31c/0x380
[24928.254982] path_lookupat+0x68/0x11c
[24928.254987] filename_lookup+0x88/0x17c
[24928.254993] vfs_statx+0x9c/0x1b0
[24928.254999] __arm64_sys_newfstatat+0x34/0x5c
[24928.255009] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.255014] do_el0_svc+0x24/0x90
[24928.255020] el0_svc+0x10/0x1c
[24928.255027] el0_sync_handler+0xcc/0xe4
[24928.255032] el0_sync+0x1a0/0x1c0
[24928.255090] task:Thread-5        state:D stack:    0 pid:12798 ppid:  1158 flags:0x04000801
[24928.255099] Call trace:
[24928.255105] __switch_to+0x148/0x250
[24928.255111] __schedule+0x454/0x6ec
[24928.255120] schedule+0x7c/0x118
[24928.255126] rwsem_down_read_slowpath+0x5b8/0x9b8
[24928.255132] down_read+0x3c/0x164
[24928.255137] lookup_slow+0x2c/0x60
[24928.255144] link_path_walk+0x31c/0x380
[24928.255150] path_lookupat+0x68/0x11c
[24928.255155] filename_lookup+0x88/0x17c
[24928.255161] vfs_statx+0x9c/0x1b0
[24928.255166] __arm64_sys_newfstatat+0x34/0x5c
[24928.255174] el0_svc_common.llvm.14247025778268414372+0xa8/0x138
[24928.255183] do_el0_svc+0x24/0x90
[24928.255190] el0_svc+0x10/0x1c
[24928.255195] el0_sync_handler+0xcc/0xe4
[24928.255200] el0_sync+0x1a0/0x1c0

Signed-off-by: Juhyung Park <[email protected]>
  • Loading branch information
arter97 committed May 22, 2024
1 parent 4e3f03a commit 5c3237b
Showing 1 changed file with 56 additions and 31 deletions.
87 changes: 56 additions & 31 deletions kernel/throne_tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,17 @@ static void crown_manager(const char *apk, struct list_head *uid_data)
}
}

#define DATA_PATH_LEN 384 // 384 is enough for /data/app/<package>/base.apk

struct data_path {
char dirpath[DATA_PATH_LEN];
int depth;
struct list_head list;
};

struct my_dir_context {
struct dir_context ctx;
struct list_head *data_path_list;
char *parent_dir;
void *private_data;
int depth;
Expand All @@ -119,8 +128,7 @@ 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[384]; // 384 is enough for /data/app/<package>/base.apk
char dirpath[DATA_PATH_LEN];

if (!my_ctx) {
pr_err("Invalid context\n");
Expand All @@ -134,30 +142,25 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
if (!strncmp(name, "..", namelen) || !strncmp(name, ".", namelen))
return FILLDIR_ACTOR_CONTINUE; // Skip "." and ".."

if (snprintf(dirpath, sizeof(dirpath), "%s/%.*s", my_ctx->parent_dir,
namelen, name) >= sizeof(dirpath)) {
if (snprintf(dirpath, DATA_PATH_LEN, "%s/%.*s", my_ctx->parent_dir,
namelen, name) >= DATA_PATH_LEN) {
pr_err("Path too long: %s/%.*s\n", my_ctx->parent_dir, namelen,
name);
return FILLDIR_ACTOR_CONTINUE;
}

if (d_type == DT_DIR && my_ctx->depth > 0 &&
(my_ctx->stop && !*my_ctx->stop)) {
struct my_dir_context sub_ctx = { .ctx.actor = my_actor,
.parent_dir = dirpath,
.private_data =
my_ctx->private_data,
.depth = my_ctx->depth - 1,
.stop = my_ctx->stop };
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));
struct data_path *data = kmalloc(sizeof(struct data_path), GFP_ATOMIC);

if (!data) {
pr_err("Failed to allocate memory for %s\n", dirpath);
return FILLDIR_ACTOR_CONTINUE;
}

iterate_dir(file, &sub_ctx.ctx);
filp_close(file, NULL);
strscpy(data->dirpath, dirpath, DATA_PATH_LEN);
data->depth = my_ctx->depth - 1;
list_add_tail(&data->list, my_ctx->data_path_list);
} else {
if ((namelen == 8) && (strncmp(name, "base.apk", namelen) == 0)) {
bool is_manager = is_manager_apk(dirpath);
Expand All @@ -175,22 +178,44 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,

void search_manager(const char *path, int depth, struct list_head *uid_data)
{
struct file *file;
int stop = 0;
struct my_dir_context ctx = { .ctx.actor = my_actor,
.parent_dir = (char *)path,
.private_data = uid_data,
.depth = depth,
.stop = &stop };

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;
}
int i, stop = 0;
struct list_head data_path_list;
INIT_LIST_HEAD(&data_path_list);

// First depth
struct data_path data;
strscpy(data.dirpath, path, DATA_PATH_LEN);
data.depth = depth;
list_add_tail(&data.list, &data_path_list);

for (i = depth; i > 0; i--) {
struct data_path *pos, *n;

list_for_each_entry_safe(pos, n, &data_path_list, list) {
struct my_dir_context ctx = { .ctx.actor = my_actor,
.data_path_list = &data_path_list,
.parent_dir = pos->dirpath,
.private_data = uid_data,
.depth = pos->depth,
.stop = &stop };
struct file *file;

if (!stop) {
file = ksu_filp_open_compat(pos->dirpath, O_RDONLY | O_NOFOLLOW, 0);
if (IS_ERR(file)) {
pr_err("Failed to open directory: %s, err: %ld\n", pos->dirpath, PTR_ERR(file));
return;
}

iterate_dir(file, &ctx.ctx);
filp_close(file, NULL);
}

iterate_dir(file, &ctx.ctx);
filp_close(file, NULL);
list_del(&pos->list);
if (pos != &data)
kfree(pos);
}
}
}

static bool is_uid_exist(uid_t uid, char *package, void *data)
Expand Down

0 comments on commit 5c3237b

Please sign in to comment.