Skip to content

Commit c61943b

Browse files
aviraxpLeCmnGend
authored andcommitted
throne_tracker: avoid cross fs access (tiann#2626)
Files in /data/app may be stacked on incremental fs, if user installs big apps from play store or adb shell. Performing I/O operation on it may results in long-time blocking. As KSU won't get installed in those ways, just avoid cross fs access. Authored-by: 5ec1cff <[email protected]> Signed-off-by: Wang Han <[email protected]>
1 parent 12d9490 commit c61943b

File tree

1 file changed

+30
-2
lines changed

1 file changed

+30
-2
lines changed

kernel/throne_tracker.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/string.h>
66
#include <linux/types.h>
77
#include <linux/version.h>
8+
#include <linux/namei.h>
89

910
#include "allowlist.h"
1011
#include "klog.h" // IWYU pragma: keep
@@ -119,6 +120,7 @@ struct my_dir_context {
119120
void *private_data;
120121
int depth;
121122
int *stop;
123+
struct super_block* root_sb;
122124
};
123125
// https://docs.kernel.org/filesystems/porting.html
124126
// filldir_t (readdir callbacks) calling conventions have changed. Instead of returning 0 or -E... it returns bool now. false means "no more" (as -E... used to) and true - "keep going" (as 0 in old calling conventions). Rationale: callers never looked at specific -E... values anyway. -> iterate_shared() instances require no changes at all, all filldir_t ones in the tree converted.
@@ -140,6 +142,8 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
140142
struct my_dir_context *my_ctx =
141143
container_of(ctx, struct my_dir_context, ctx);
142144
char dirpath[DATA_PATH_LEN];
145+
int err;
146+
struct path path;
143147

144148
if (!my_ctx) {
145149
pr_err("Invalid context\n");
@@ -166,6 +170,18 @@ FILLDIR_RETURN_TYPE my_actor(struct dir_context *ctx, const char *name,
166170
return FILLDIR_ACTOR_CONTINUE;
167171
}
168172

173+
err = kern_path(dirpath, 0, &path);
174+
175+
if (err) {
176+
pr_err("get dirpath %s err: %d\n", dirpath, err);
177+
return FILLDIR_ACTOR_CONTINUE;
178+
}
179+
180+
if (my_ctx->root_sb != path.dentry->d_inode->i_sb) {
181+
pr_info("skip cross fs: %s", dirpath);
182+
return FILLDIR_ACTOR_CONTINUE;
183+
}
184+
169185
if (d_type == DT_DIR && my_ctx->depth > 0 &&
170186
(my_ctx->stop && !*my_ctx->stop)) {
171187
struct data_path *data = kmalloc(sizeof(struct data_path), GFP_ATOMIC);
@@ -263,11 +279,20 @@ bool is_lock_held(const char *path)
263279

264280
void search_manager(const char *path, int depth, struct list_head *uid_data)
265281
{
266-
int i, stop = 0;
282+
int i, stop = 0, err;
267283
struct list_head data_path_list;
284+
struct path kpath;
285+
struct super_block* root_sb;
268286
INIT_LIST_HEAD(&data_path_list);
269287
unsigned long data_app_magic = 0;
270288

289+
err = kern_path(path, 0, &kpath);
290+
291+
if (err) {
292+
pr_err("get search root %s err: %d\n", path, err);
293+
return;
294+
}
295+
271296
// Initialize APK cache list
272297
struct apk_path_hash *pos, *n;
273298
list_for_each_entry(pos, &apk_path_hash_list, list) {
@@ -284,6 +309,8 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
284309
data.depth = depth;
285310
list_add_tail(&data.list, &data_path_list);
286311

312+
root_sb = kpath.dentry->d_inode->i_sb;
313+
287314
for (i = depth; i >= 0; i--) {
288315
struct data_path *pos, *n;
289316

@@ -293,7 +320,8 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
293320
.parent_dir = pos->dirpath,
294321
.private_data = uid_data,
295322
.depth = pos->depth,
296-
.stop = &stop };
323+
.stop = &stop,
324+
.root_sb = root_sb };
297325
struct file *file;
298326

299327
if (!stop) {

0 commit comments

Comments
 (0)