|
13 | 13 | #include "throne_tracker.h"
|
14 | 14 | #include "kernel_compat.h"
|
15 | 15 |
|
| 16 | +#include <linux/kthread.h> |
| 17 | +#include <linux/sched.h> |
| 18 | + |
16 | 19 | uid_t ksu_manager_uid = KSU_INVALID_UID;
|
17 | 20 |
|
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" |
19 | 23 |
|
20 | 24 | struct uid_data {
|
21 | 25 | struct list_head list;
|
@@ -243,6 +247,17 @@ void search_manager(const char *path, int depth, struct list_head *uid_data)
|
243 | 247 | .depth = pos->depth,
|
244 | 248 | .stop = &stop };
|
245 | 249 | struct file *file;
|
| 250 | + struct path kpath; |
| 251 | + |
| 252 | + if (kern_path(path, 0, &kpath)) |
| 253 | + goto skip_iterate; |
| 254 | + |
| 255 | + if (!spin_trylock(&kpath.dentry->d_lock)) { |
| 256 | + path_put(&kpath); |
| 257 | + goto skip_iterate; |
| 258 | + } |
| 259 | + spin_unlock(&kpath.dentry->d_lock); |
| 260 | + path_put(&kpath); |
246 | 261 |
|
247 | 262 | if (!stop) {
|
248 | 263 | file = ksu_filp_open_compat(pos->dirpath, O_RDONLY | O_NOFOLLOW, 0);
|
@@ -302,7 +317,7 @@ static bool is_uid_exist(uid_t uid, char *package, void *data)
|
302 | 317 | return exist;
|
303 | 318 | }
|
304 | 319 |
|
305 |
| -void track_throne() |
| 320 | +static void track_throne_function() |
306 | 321 | {
|
307 | 322 | struct file *fp =
|
308 | 323 | ksu_filp_open_compat(SYSTEM_PACKAGES_LIST_PATH, O_RDONLY, 0);
|
@@ -397,6 +412,37 @@ void track_throne()
|
397 | 412 | }
|
398 | 413 | }
|
399 | 414 |
|
| 415 | +static int throne_tracker_thread(void *data) |
| 416 | +{ |
| 417 | + pr_info("%s: pid: %d started\n", __func__, current->pid); |
| 418 | + track_throne_function(); |
| 419 | + throne_thread = NULL; |
| 420 | + smp_mb(); |
| 421 | + pr_info("%s: pid: %d exit!\n", __func__, current->pid); |
| 422 | + return 0; |
| 423 | +} |
| 424 | + |
| 425 | +void track_throne() |
| 426 | +{ |
| 427 | + static bool throne_tracker_first_run = true; |
| 428 | + if (throne_tracker_first_run) { |
| 429 | + // be locking on first run, workaround for some kernels |
| 430 | + track_throne_function(); |
| 431 | + throne_tracker_first_run = false; |
| 432 | + return; |
| 433 | + } |
| 434 | + |
| 435 | + smp_mb(); |
| 436 | + if (throne_thread != NULL) // single instance lock |
| 437 | + return; |
| 438 | + |
| 439 | + throne_thread = kthread_run(throne_tracker_thread, NULL, "throne_tracker"); |
| 440 | + if (IS_ERR(throne_thread)) { |
| 441 | + throne_thread = NULL; |
| 442 | + return; |
| 443 | + } |
| 444 | +} |
| 445 | + |
400 | 446 | void ksu_throne_tracker_init()
|
401 | 447 | {
|
402 | 448 | // nothing to do
|
|
0 commit comments