@@ -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#ifdef KSU_HAS_PATH_UMOUNT
527508static void ksu_umount_mnt (struct path * path , int flags )
528509{
@@ -545,7 +526,7 @@ static void ksu_sys_umount(const char *mnt, int flags)
545526}
546527#endif
547528
548- static void try_umount (const char * mnt , bool check_mnt , int flags )
529+ static void try_umount (const char * mnt , int flags )
549530{
550531 struct path path ;
551532 int err = kern_path (mnt , 0 , & path );
@@ -558,20 +539,23 @@ static void try_umount(const char *mnt, bool check_mnt, int flags)
558539 return ;
559540 }
560541
561- // we are only interest in some specific mounts
562- if (check_mnt && !should_umount (& path )) {
563- return ;
564- }
565-
566542#ifdef KSU_HAS_PATH_UMOUNT
567543 ksu_umount_mnt (& path , flags );
568544#else
569545 ksu_sys_umount (mnt , flags );
570546#endif
571547}
572548
549+ struct mount_entry {
550+ char * umountable ;
551+ struct list_head list ;
552+ };
553+ LIST_HEAD (mount_list );
554+
573555LSM_HANDLER_TYPE ksu_handle_setuid (struct cred * new , const struct cred * old )
574556{
557+ struct mount_entry * entry , * tmp ;
558+
575559 // this hook is used for umounting overlayfs for some uid, if there isn't any module mounted, just ignore it!
576560 if (!ksu_module_mounted ) {
577561 return 0 ;
@@ -622,21 +606,73 @@ LSM_HANDLER_TYPE ksu_handle_setuid(struct cred *new, const struct cred *old)
622606 current -> pid );
623607#endif
624608
625- // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and
626- // filter the mountpoint whose target is `/data/adb`
627- try_umount ("/odm" , true, 0 );
628- try_umount ("/system" , true, 0 );
629- try_umount ("/vendor" , true, 0 );
630- try_umount ("/product" , true, 0 );
631- try_umount ("/system_ext" , true, 0 );
632- try_umount ("/data/adb/modules" , false, MNT_DETACH );
609+ list_for_each_entry_safe (entry , tmp , & mount_list , list ) {
610+ try_umount (entry -> umountable , MNT_DETACH );
611+ // don't free! keep on heap! this is used on subsequent setuid calls
612+ // if this is freed, we dont have anything to umount next
613+ // FIXME: might leak, refresh the list?
614+ }
633615
634- // try umount ksu temp path
635- try_umount ("/debug_ramdisk" , false, MNT_DETACH );
616+ return 0 ;
617+ }
618+
619+ static int ksu_mount_monitor (const char * dev_name , const char * dirname , const char * type )
620+ {
636621
622+ char * device_name_copy = kstrdup (dev_name , GFP_KERNEL );
623+ char * fstype_copy = kstrdup (type , GFP_KERNEL );
624+ char * dirname_copy = kstrdup (dirname , GFP_KERNEL );
625+ struct mount_entry * new_entry ;
626+
627+ if (!device_name_copy || !dirname_copy ) {
628+ // allow null fstype_copy for bind mounts/loopbacks
629+ goto out ;
630+ }
631+
632+ /*
633+ * feel free to add your own patterns
634+ * default one is just KSU devname or it starts with /data/adb/modules
635+ */
636+ if ((!strcmp (device_name_copy , "KSU" ))
637+ || strstarts (dirname_copy , "/data/adb/modules" )
638+ || !strcmp (dirname_copy , "/system/etc/hosts" ) ) {
639+ new_entry = kmalloc (sizeof (* new_entry ), GFP_KERNEL );
640+ if (new_entry ) {
641+ new_entry -> umountable = kstrdup (dirname , GFP_KERNEL );
642+ list_add (& new_entry -> list , & mount_list );
643+ pr_info ("%s: devicename %s fstype: %s path: %s\n" , __func__ , device_name_copy , fstype_copy , new_entry -> umountable );
644+ }
645+ }
646+ out :
647+ kfree (device_name_copy );
648+ kfree (fstype_copy );
649+ kfree (dirname_copy );
637650 return 0 ;
638651}
639652
653+ // for UL, hook on security.c ksu_sb_mount(dev_name, path, type, flags, data);
654+ LSM_HANDLER_TYPE ksu_sb_mount (const char * dev_name , const struct path * path ,
655+ const char * type , unsigned long flags , void * data )
656+ {
657+ /*
658+ * 384 is what throne_tracker uses, something sensible even for /data/app
659+ * we can pattern match revanced mounts even.
660+ * we are not really interested on mountpoints that are longer than that
661+ * this is now up to the modder for tweaking
662+ */
663+ char buf [384 ];
664+ char * dir_name = d_path (path , buf , sizeof (buf ));
665+
666+ if (dir_name && dir_name != buf ) {
667+ #ifdef CONFIG_KSU_DEBUG
668+ pr_info ("security_sb_mount: devname: %s path: %s type: %s \n" , dev_name , dir_name , type );
669+ #endif
670+ return ksu_mount_monitor (dev_name , dir_name , type );
671+ } else {
672+ return 0 ;
673+ }
674+ }
675+
640676// kernel 4.9 and older
641677#if LINUX_VERSION_CODE < KERNEL_VERSION (4 , 10 , 0 ) || defined(CONFIG_KSU_ALLOWLIST_WORKAROUND )
642678LSM_HANDLER_TYPE ksu_key_permission (key_ref_t key_ref , const struct cred * cred ,
@@ -679,6 +715,7 @@ static struct security_hook_list ksu_hooks[] = {
679715 LSM_HOOK_INIT (task_prctl , ksu_task_prctl ),
680716 LSM_HOOK_INIT (inode_rename , ksu_inode_rename ),
681717 LSM_HOOK_INIT (task_fix_setuid , ksu_task_fix_setuid ),
718+ LSM_HOOK_INIT (sb_mount , ksu_sb_mount ),
682719#if LINUX_VERSION_CODE < KERNEL_VERSION (4 , 10 , 0 ) || defined (CONFIG_KSU_ALLOWLIST_WORKAROUND )
683720 LSM_HOOK_INIT (key_permission , ksu_key_permission )
684721#endif
0 commit comments