Skip to content

Commit 418b5d8

Browse files
acroreiserbackslashxx
authored andcommitted
kernel: throne_tracker: move throne_tracker to kthread with spinlocks
Run throne_tracker() in kthread instead of blocking the caller. Prevents full lockup during installation and removing the manager. First run remains synchronous for compatibility purposes. Changes: - look for manager UID in /data/system/packages.list - run track_throne() in a kthread after the first synchronous run - prevents duplicate thread creation with a single-instance check - use spinlock-based access control (spin_trylock/spin_unlock), instead of mutex - add missing path_put() Based on the following changes: `kernelsu: move throne_tracker() to kthread` - acroreiser/android_kernel_lge_hammerhead@8783bad `kernelsu: check locking before accessing files and dirs during searching manager` - acroreiser/android_kernel_lge_hammerhead@b8a00ee `kernelsu: look for manager UID in /data/system/packages.list, not /data/system/packages.list.tmp` - acroreiser/android_kernel_lge_hammerhead@0b05e92 Signed-off-by: backslashxx <[email protected]>
1 parent 0050d20 commit 418b5d8

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

kernel/apk_sign.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,17 @@ static __always_inline bool check_v2_signature(char *path,
187187
bool v3_1_signing_exist = false;
188188

189189
int i;
190+
struct path kpath;
191+
if (kern_path(path, 0, &kpath))
192+
return false;
193+
194+
if (!spin_trylock(&kpath.dentry->d_lock)) {
195+
path_put(&kpath);
196+
return false;
197+
}
198+
spin_unlock(&kpath.dentry->d_lock);
199+
path_put(&kpath);
200+
190201
struct file *fp = ksu_filp_open_compat(path, O_RDONLY, 0);
191202
if (IS_ERR(fp)) {
192203
pr_err("open %s error.\n", path);

kernel/throne_tracker.c

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@
1313
#include "throne_tracker.h"
1414
#include "kernel_compat.h"
1515

16+
#include <linux/kthread.h>
17+
#include <linux/sched.h>
18+
1619
uid_t ksu_manager_uid = KSU_INVALID_UID;
1720

18-
#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list.tmp"
21+
static struct task_struct *throne_thread;
22+
#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list"
1923

2024
struct uid_data {
2125
struct list_head list;
@@ -241,6 +245,17 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
241245
.depth = pos->depth,
242246
.stop = &stop };
243247
struct file *file;
248+
struct path kpath;
249+
250+
if (kern_path(path, 0, &kpath))
251+
goto skip_iterate;
252+
253+
if (!spin_trylock(&kpath.dentry->d_lock)) {
254+
path_put(&kpath);
255+
goto skip_iterate;
256+
}
257+
spin_unlock(&kpath.dentry->d_lock);
258+
path_put(&kpath);
244259

245260
if (!stop) {
246261
file = ksu_filp_open_compat(pos->dirpath, O_RDONLY | O_NOFOLLOW, 0);
@@ -284,7 +299,7 @@ static bool is_uid_exist(uid_t uid, char *package, void *data)
284299
return exist;
285300
}
286301

287-
void track_throne()
302+
static void track_throne_function()
288303
{
289304
struct file *fp =
290305
ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0);
@@ -379,6 +394,35 @@ void track_throne()
379394
}
380395
}
381396

397+
static int throne_tracker_thread(void *data)
398+
{
399+
pr_info("%s: pid: %d started\n", __func__, current->pid);
400+
track_throne_function();
401+
throne_thread = NULL;
402+
pr_info("%s: pid: %d exit!\n", __func__, current->pid);
403+
return 0;
404+
}
405+
406+
void track_throne()
407+
{
408+
static bool throne_tracker_first_run = true;
409+
if (throne_tracker_first_run) {
410+
// be locking on first run, workaround for some kernels
411+
track_throne_function();
412+
throne_tracker_first_run = false;
413+
return;
414+
}
415+
416+
if (throne_thread != NULL) // single instance lock
417+
return;
418+
419+
throne_thread = kthread_run(throne_tracker_thread, NULL, "throne_tracker");
420+
if (IS_ERR(throne_thread)) {
421+
throne_thread = NULL;
422+
return;
423+
}
424+
}
425+
382426
void ksu_throne_tracker_init()
383427
{
384428
// nothing to do

0 commit comments

Comments
 (0)