@@ -504,25 +504,6 @@ static bool is_appuid(kuid_t uid)
504504 return appid >= FIRST_APPLICATION_UID && appid <= LAST_APPLICATION_UID ;
505505}
506506
507- static bool should_umount (struct path * path )
508- {
509- if (!path ) {
510- return false;
511- }
512-
513- if (current -> nsproxy -> mnt_ns == init_nsproxy .mnt_ns ) {
514- pr_info ("ignore global mnt namespace process: %d\n" ,
515- current_uid ().val );
516- return false;
517- }
518-
519- if (path -> mnt && path -> mnt -> mnt_sb && path -> mnt -> mnt_sb -> s_type ) {
520- const char * fstype = path -> mnt -> mnt_sb -> s_type -> name ;
521- return strcmp (fstype , "overlay" ) == 0 ;
522- }
523- return false;
524- }
525-
526507#if LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 9 , 0 ) || defined(KSU_HAS_PATH_UMOUNT )
527508static void ksu_path_umount (const char * mnt , struct path * path , int flags )
528509{
@@ -546,7 +527,7 @@ static void ksu_sys_umount(const char *mnt, int flags)
546527}
547528#endif // KSU_HAS_PATH_UMOUNT
548529
549- static void try_umount (const char * mnt , bool check_mnt , int flags )
530+ static void try_umount (const char * mnt , int flags )
550531{
551532 struct path path ;
552533 int err = kern_path (mnt , 0 , & path );
@@ -560,12 +541,6 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
560541 return ;
561542 }
562543
563- // we are only interest in some specific mounts
564- if (check_mnt && !should_umount (& path )) {
565- path_put (& path );
566- return ;
567- }
568-
569544#if LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 9 , 0 ) || defined(KSU_HAS_PATH_UMOUNT )
570545 ksu_path_umount (mnt , & path , flags );
571546 // dont call path_put here!!
@@ -578,8 +553,16 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
578553#endif
579554}
580555
556+ struct mount_entry {
557+ char * umountable ;
558+ struct list_head list ;
559+ };
560+ LIST_HEAD (mount_list );
561+
581562int ksu_handle_setuid (struct cred * new , const struct cred * old )
582563{
564+ struct mount_entry * entry , * tmp ;
565+
583566 // this hook is used for umounting overlayfs for some uid, if there isn't any module mounted, just ignore it!
584567 if (!ksu_module_mounted ) {
585568 return 0 ;
@@ -624,33 +607,88 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
624607 current -> pid );
625608 return 0 ;
626609 }
627- #ifdef CONFIG_KSU_DEBUG
610+
628611 // umount the target mnt
629612 pr_info ("handle umount for uid: %d, pid: %d\n" , new_uid .val ,
630613 current -> pid );
631- #endif
632614
633- // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and
634- // filter the mountpoint whose target is `/data/adb`
635- try_umount ("/odm" , true, 0 );
636- try_umount ("/system" , true, 0 );
637- try_umount ("/vendor" , true, 0 );
638- try_umount ("/product" , true, 0 );
639- try_umount ("/system_ext" , true, 0 );
640- try_umount ("/data/adb/modules" , false, MNT_DETACH );
615+ list_for_each_entry_safe (entry , tmp , & mount_list , list ) {
616+ try_umount (entry -> umountable , MNT_DETACH );
617+ // don't free! keep on heap! this is used on subsequent setuid calls
618+ // if this is freed, we dont have anything to umount next
619+ // FIXME: might leak, refresh the list?
620+ }
641621
642- // try umount ksu temp path
643- try_umount ( "/debug_ramdisk" , false, MNT_DETACH );
622+ return 0 ;
623+ }
644624
625+ static int ksu_mount_monitor (const char * dev_name , const char * dirname , const char * type )
626+ {
627+
628+ char * device_name_copy = kstrdup (dev_name , GFP_KERNEL );
629+ char * fstype_copy = kstrdup (type , GFP_KERNEL );
630+ char * dirname_copy = kstrdup (dirname , GFP_KERNEL );
631+ const char * string_fstype = fstype_copy ? fstype_copy : "(null)" ;
632+ const char * string_devname = device_name_copy ? device_name_copy : "(null)" ;
633+ struct mount_entry * new_entry ;
634+
635+ if (unlikely (!dirname_copy )) // if dirname is null thats just questionable
636+ goto out ;
637+
638+ /*
639+ * feel free to add your own patterns
640+ * default one is just KSU devname or it starts with /data/adb/modules
641+ *
642+ * for devicenamme and fstype string comparisons, make sure to use string_fstype/string_devname as NULL is being allowed.
643+ * using device_name_copy, fstype_copy can lead to null pointer dereference.
644+ */
645+ if ((!strcmp (string_devname , "KSU" ))
646+ // || !strcmp(dirname_copy, "/system/etc/hosts") // this is an example
647+ || strstarts (dirname_copy , "/data/adb/modules" ) ) {
648+ new_entry = kmalloc (sizeof (* new_entry ), GFP_KERNEL );
649+ if (new_entry ) {
650+ new_entry -> umountable = kstrdup (dirname , GFP_KERNEL );
651+ list_add (& new_entry -> list , & mount_list );
652+ pr_info ("%s: devicename %s fstype: %s path: %s\n" , __func__ , string_devname , string_fstype , new_entry -> umountable );
653+ }
654+ }
655+ out :
656+ kfree (device_name_copy );
657+ kfree (fstype_copy );
658+ kfree (dirname_copy );
645659 return 0 ;
646660}
647661
662+ // for UL, hook on security.c ksu_sb_mount(dev_name, path, type, flags, data);
663+ int ksu_sb_mount (const char * dev_name , const struct path * path ,
664+ const char * type , unsigned long flags , void * data )
665+ {
666+ /*
667+ * 384 is what throne_tracker uses, something sensible even for /data/app
668+ * we can pattern match revanced mounts even.
669+ * we are not really interested on mountpoints that are longer than that
670+ * this is now up to the modder for tweaking
671+ */
672+ char buf [384 ];
673+ char * dir_name = d_path (path , buf , sizeof (buf ));
674+
675+ if (dir_name && dir_name != buf ) {
676+ #ifdef CONFIG_KSU_DEBUG
677+ pr_info ("security_sb_mount: devname: %s path: %s type: %s \n" , dev_name , dir_name , type );
678+ #endif
679+ return ksu_mount_monitor (dev_name , dir_name , type );
680+ } else {
681+ return 0 ;
682+ }
683+ }
684+
648685static int ksu_task_prctl (int option , unsigned long arg2 , unsigned long arg3 ,
649686 unsigned long arg4 , unsigned long arg5 )
650687{
651688 ksu_handle_prctl (option , arg2 , arg3 , arg4 , arg5 );
652689 return - ENOSYS ;
653690}
691+
654692// kernel 4.4 and 4.9
655693#if LINUX_VERSION_CODE < KERNEL_VERSION (4 , 10 , 0 ) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND )
656694static int ksu_key_permission (key_ref_t key_ref , const struct cred * cred ,
@@ -684,6 +722,7 @@ static struct security_hook_list ksu_hooks[] = {
684722 LSM_HOOK_INIT (task_prctl , ksu_task_prctl ),
685723 LSM_HOOK_INIT (inode_rename , ksu_inode_rename ),
686724 LSM_HOOK_INIT (task_fix_setuid , ksu_task_fix_setuid ),
725+ LSM_HOOK_INIT (sb_mount , ksu_sb_mount ),
687726#if LINUX_VERSION_CODE < KERNEL_VERSION (4 , 10 , 0 ) || defined (CONFIG_KSU_ALLOWLIST_WORKAROUND )
688727 LSM_HOOK_INIT (key_permission , ksu_key_permission )
689728#endif
0 commit comments