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
462460close_file :
463461 filp_close (fp , 0 );
464462out :
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
497493void ksu_load_allow_list ()
0 commit comments