Skip to content

Commit 5ecad34

Browse files
committed
kernel: allowlist: escape persistent_allow_list to kthread
Signed-off-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
1 parent 0544f47 commit 5ecad34

1 file changed

Lines changed: 23 additions & 27 deletions

File tree

kernel/policy/allowlist.c

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/compiler_types.h>
1717
#include <linux/hashtable.h>
1818
#include <linux/kref.h>
19+
#include <linux/kthread.h>
1920

2021
#include "klog.h" // IWYU pragma: keep
2122
#include "ksu.h"
@@ -423,8 +424,7 @@ bool ksu_get_allow_list(int *array, u16 length, u16 *out_length, u16 *out_total,
423424
return true;
424425
}
425426

426-
// TODO: move to kernel thread or work queue
427-
static void do_persistent_allow_list(struct callback_head *_cb)
427+
static inline void do_persistent_allow_list()
428428
{
429429
u32 magic = FILE_MAGIC;
430430
u32 version = FILE_FORMAT_VERSION;
@@ -450,48 +450,44 @@ static void do_persistent_allow_list(struct callback_head *_cb)
450450
goto close_file;
451451
}
452452

453-
mutex_lock(&allowlist_mutex);
454453
hash_for_each (allow_list, i, p, list) {
455454
pr_info("save allow list, name: %s uid :%d, allow: %d\n", p->profile.key, p->profile.curr_uid,
456455
p->profile.allow_su);
457456

458457
kernel_write(fp, &p->profile, sizeof(p->profile), &off);
459458
}
460-
mutex_unlock(&allowlist_mutex);
461459

462460
close_file:
463461
filp_close(fp, 0);
464462
out:
465463
revert_creds(saved);
466-
kfree(_cb);
467464
}
468465

469-
void ksu_persistent_allow_list()
466+
static int persistent_allow_list_pre(void *data)
470467
{
471-
struct task_struct *tsk;
468+
if (IS_ENABLED(CONFIG_KSU_DEBUG)
469+
pr_info("do_persistent_allow_list: pid: %d started\n", current->pid);
470+
471+
/*
472+
* repurpose the mutex that was inside do_persistent_allow_list
473+
* this way we get a single instance access.
474+
* however, there is no need for mutex_trylock-fail-ret pattern for this one
475+
* we just let other threads to wait-stall
476+
*
477+
*/
478+
mutex_lock(&allowlist_mutex);
479+
do_persistent_allow_list();
480+
mutex_unlock(&allowlist_mutex);
472481

473-
rcu_read_lock();
474-
tsk = get_pid_task(find_vpid(1), PIDTYPE_PID);
475-
if (!tsk) {
476-
rcu_read_unlock();
477-
pr_err("save_allow_list find init task err\n");
478-
return;
479-
}
480-
rcu_read_unlock();
482+
if (IS_ENABLED(CONFIG_KSU_DEBUG)
483+
pr_info("do_persistent_allow_list: pid: %d exit\n", current->pid);
481484

482-
struct callback_head *cb = kzalloc(sizeof(struct callback_head), GFP_KERNEL);
483-
if (!cb) {
484-
pr_err("save_allow_list alloc cb err\b");
485-
goto put_task;
486-
}
487-
cb->func = do_persistent_allow_list;
488-
if (task_work_add(tsk, cb, TWA_RESUME)) {
489-
kfree(cb);
490-
pr_warn("save_allow_list add task_work failed\n");
491-
}
485+
return 0;
486+
}
492487

493-
put_task:
494-
put_task_struct(tsk);
488+
void ksu_persistent_allow_list()
489+
{
490+
kthread_run(persistent_allow_list_pre, NULL, "allowlist");
495491
}
496492

497493
void ksu_load_allow_list()

0 commit comments

Comments
 (0)