@@ -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