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