44#include  <linux/err.h> 
55#include  <linux/init.h> 
66#include  <linux/init_task.h> 
7- #include  <linux/kallsyms.h> 
87#include  <linux/kernel.h> 
9- #include  <linux/kprobes.h> 
108#include  <linux/lsm_hooks.h> 
11- #include  <linux/mm.h> 
129#include  <linux/nsproxy.h> 
1310#include  <linux/path.h> 
1411#include  <linux/printk.h> 
15- #include  <linux/sched.h> 
16- #include  <linux/security.h> 
17- #include  <linux/stddef.h> 
1812#include  <linux/string.h> 
19- #include  <linux/types.h> 
2013#include  <linux/uaccess.h> 
2114#include  <linux/uidgid.h> 
2215#include  <linux/version.h> 
2316#include  <linux/mount.h> 
24- 
2517#include  <linux/fs.h> 
2618#include  <linux/namei.h> 
2719
28- #ifdef  MODULE 
29- #include  <linux/list.h> 
30- #include  <linux/irqflags.h> 
31- #include  <linux/mm_types.h> 
32- #include  <linux/rcupdate.h> 
33- #include  <linux/vmalloc.h> 
34- #endif 
35- 
3620#include  "allowlist.h" 
37- #include   "arch.h" 
21+ 
3822#include  "core_hook.h" 
3923#include  "klog.h"  // IWYU pragma: keep 
4024#include  "ksu.h" 
@@ -305,9 +289,6 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
305289			pr_err ("prctl reply error, cmd: %lu\n" , arg2 );
306290		}
307291		u32  version_flags  =  0 ;
308- #ifdef  MODULE 
309- 		version_flags  |= 0x1 ;
310- #endif 
311292		if  (arg4  && 
312293		    copy_to_user (arg4 , & version_flags , sizeof (version_flags ))) {
313294			pr_err ("prctl reply error, cmd: %lu\n" , arg2 );
@@ -644,69 +625,6 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
644625	return  0 ;
645626}
646627
647- // Init functons 
648- 
649- static  int  handler_pre (struct  kprobe  * p , struct  pt_regs  * regs )
650- {
651- 	struct  pt_regs  * real_regs  =  PT_REAL_REGS (regs );
652- 	int  option  =  (int )PT_REGS_PARM1 (real_regs );
653- 	unsigned long  arg2  =  (unsigned long )PT_REGS_PARM2 (real_regs );
654- 	unsigned long  arg3  =  (unsigned long )PT_REGS_PARM3 (real_regs );
655- 	// PRCTL_SYMBOL is the arch-specificed one, which receive raw pt_regs from syscall 
656- 	unsigned long  arg4  =  (unsigned long )PT_REGS_SYSCALL_PARM4 (real_regs );
657- 	unsigned long  arg5  =  (unsigned long )PT_REGS_PARM5 (real_regs );
658- 
659- 	return  ksu_handle_prctl (option , arg2 , arg3 , arg4 , arg5 );
660- }
661- 
662- static  struct  kprobe  prctl_kp  =  {
663- 	.symbol_name  =  PRCTL_SYMBOL ,
664- 	.pre_handler  =  handler_pre ,
665- };
666- 
667- static  int  renameat_handler_pre (struct  kprobe  * p , struct  pt_regs  * regs )
668- {
669- #if  LINUX_VERSION_CODE  >= KERNEL_VERSION (5 , 12 , 0 )
670- 	// https://elixir.bootlin.com/linux/v5.12-rc1/source/include/linux/fs.h 
671- 	struct  renamedata  * rd  =  PT_REGS_PARM1 (regs );
672- 	struct  dentry  * old_entry  =  rd -> old_dentry ;
673- 	struct  dentry  * new_entry  =  rd -> new_dentry ;
674- #else 
675- 	struct  dentry  * old_entry  =  (struct  dentry  * )PT_REGS_PARM2 (regs );
676- 	struct  dentry  * new_entry  =  (struct  dentry  * )PT_REGS_CCALL_PARM4 (regs );
677- #endif 
678- 
679- 	return  ksu_handle_rename (old_entry , new_entry );
680- }
681- 
682- static  struct  kprobe  renameat_kp  =  {
683- 	.symbol_name  =  "vfs_rename" ,
684- 	.pre_handler  =  renameat_handler_pre ,
685- };
686- 
687- __maybe_unused  int  ksu_kprobe_init (void )
688- {
689- 	int  rc  =  0 ;
690- 	rc  =  register_kprobe (& prctl_kp );
691- 
692- 	if  (rc ) {
693- 		pr_info ("prctl kprobe failed: %d.\n" , rc );
694- 		return  rc ;
695- 	}
696- 
697- 	rc  =  register_kprobe (& renameat_kp );
698- 	pr_info ("renameat kp: %d\n" , rc );
699- 
700- 	return  rc ;
701- }
702- 
703- __maybe_unused  int  ksu_kprobe_exit (void )
704- {
705- 	unregister_kprobe (& prctl_kp );
706- 	unregister_kprobe (& renameat_kp );
707- 	return  0 ;
708- }
709- 
710628static  int  ksu_task_prctl (int  option , unsigned long  arg2 , unsigned long  arg3 ,
711629			  unsigned long  arg4 , unsigned long  arg5 )
712630{
@@ -726,7 +644,6 @@ static int ksu_task_fix_setuid(struct cred *new, const struct cred *old,
726644	return  ksu_handle_setuid (new , old );
727645}
728646
729- #ifndef  MODULE 
730647static  struct  security_hook_list  ksu_hooks [] =  {
731648	LSM_HOOK_INIT (task_prctl , ksu_task_prctl ),
732649	LSM_HOOK_INIT (inode_rename , ksu_inode_rename ),
@@ -738,184 +655,7 @@ void __init ksu_lsm_hook_init(void)
738655	security_add_hooks (ksu_hooks , ARRAY_SIZE (ksu_hooks ), "ksu" );
739656}
740657
741- #else 
742- static  int  override_security_head (void  * head , const  void  * new_head , size_t  len )
743- {
744- 	unsigned long  base  =  (unsigned long )head  &  PAGE_MASK ;
745- 	unsigned long  offset  =  offset_in_page (head );
746- 
747- 	// this is impossible for our case because the page alignment 
748- 	// but be careful for other cases! 
749- 	BUG_ON (offset  +  len  >  PAGE_SIZE );
750- 	struct  page  * page  =  phys_to_page (__pa (base ));
751- 	if  (!page ) {
752- 		return  - EFAULT ;
753- 	}
754- 
755- 	void  * addr  =  vmap (& page , 1 , VM_MAP , PAGE_KERNEL );
756- 	if  (!addr ) {
757- 		return  - ENOMEM ;
758- 	}
759- 	local_irq_disable ();
760- 	memcpy (addr  +  offset , new_head , len );
761- 	local_irq_enable ();
762- 	vunmap (addr );
763- 	return  0 ;
764- }
765- 
766- static  void  free_security_hook_list (struct  hlist_head  * head )
767- {
768- 	struct  hlist_node  * temp ;
769- 	struct  security_hook_list  * entry ;
770- 
771- 	if  (!head )
772- 		return ;
773- 
774- 	hlist_for_each_entry_safe  (entry , temp , head , list ) {
775- 		hlist_del (& entry -> list );
776- 		kfree (entry );
777- 	}
778- 
779- 	kfree (head );
780- }
781- 
782- struct  hlist_head  * copy_security_hlist (struct  hlist_head  * orig )
783- {
784- 	struct  hlist_head  * new_head  =  kmalloc (sizeof (* new_head ), GFP_KERNEL );
785- 	if  (!new_head )
786- 		return  NULL ;
787- 
788- 	INIT_HLIST_HEAD (new_head );
789- 
790- 	struct  security_hook_list  * entry ;
791- 	struct  security_hook_list  * new_entry ;
792- 
793- 	hlist_for_each_entry  (entry , orig , list ) {
794- 		new_entry  =  kmalloc (sizeof (* new_entry ), GFP_KERNEL );
795- 		if  (!new_entry ) {
796- 			free_security_hook_list (new_head );
797- 			return  NULL ;
798- 		}
799- 
800- 		* new_entry  =  * entry ;
801- 
802- 		hlist_add_tail_rcu (& new_entry -> list , new_head );
803- 	}
804- 
805- 	return  new_head ;
806- }
807- 
808- #define  LSM_SEARCH_MAX  180 // This should be enough to iterate
809- static  void  * find_head_addr (void  * security_ptr , int  * index )
810- {
811- 	if  (!security_ptr ) {
812- 		return  NULL ;
813- 	}
814- 	struct  hlist_head  * head_start  = 
815- 		(struct  hlist_head  * )& security_hook_heads ;
816- 
817- 	for  (int  i  =  0 ; i  <  LSM_SEARCH_MAX ; i ++ ) {
818- 		struct  hlist_head  * head  =  head_start  +  i ;
819- 		struct  security_hook_list  * pos ;
820- 		hlist_for_each_entry  (pos , head , list ) {
821- 			if  (pos -> hook .capget  ==  security_ptr ) {
822- 				if  (index ) {
823- 					* index  =  i ;
824- 				}
825- 				return  head ;
826- 			}
827- 		}
828- 	}
829- 
830- 	return  NULL ;
831- }
832- 
833- #define  GET_SYMBOL_ADDR (sym )                                                   \
834- 	({                                                                     \
835- 		void *addr = kallsyms_lookup_name(#sym ".cfi_jt");             \
836- 		if (!addr) {                                                   \
837- 			addr = kallsyms_lookup_name(#sym);                     \
838- 		}                                                              \
839- 		addr;                                                          \
840- 	})
841- 
842- #define  KSU_LSM_HOOK_HACK_INIT (head_ptr , name , func )                           \
843- 	do {                                                                   \
844- 		static struct security_hook_list hook = {                      \
845- 			.hook = { .name = func }                               \
846- 		};                                                             \
847- 		hook.head = head_ptr;                                          \
848- 		hook.lsm = "ksu";                                              \
849- 		struct hlist_head *new_head = copy_security_hlist(hook.head);  \
850- 		if (!new_head) {                                               \
851- 			pr_err("Failed to copy security list: %s\n", #name);   \
852- 			break;                                                 \
853- 		}                                                              \
854- 		hlist_add_tail_rcu(&hook.list, new_head);                      \
855- 		if (override_security_head(hook.head, new_head,                \
856- 					   sizeof(*new_head))) {               \
857- 			free_security_hook_list(new_head);                     \
858- 			pr_err("Failed to hack lsm for: %s\n", #name);         \
859- 		}                                                              \
860- 	} while (0)
861- 
862- void  __init  ksu_lsm_hook_init (void )
863- {
864- 	void  * cap_prctl  =  GET_SYMBOL_ADDR (cap_task_prctl );
865- 	void  * prctl_head  =  find_head_addr (cap_prctl , NULL );
866- 	if  (prctl_head ) {
867- 		if  (prctl_head  !=  & security_hook_heads .task_prctl ) {
868- 			pr_warn ("prctl's address has shifted!\n" );
869- 		}
870- 		KSU_LSM_HOOK_HACK_INIT (prctl_head , task_prctl , ksu_task_prctl );
871- 	} else  {
872- 		pr_warn ("Failed to find task_prctl!\n" );
873- 	}
874- 
875- 	int  inode_killpriv_index  =  -1 ;
876- 	void  * cap_killpriv  =  GET_SYMBOL_ADDR (cap_inode_killpriv );
877- 	find_head_addr (cap_killpriv , & inode_killpriv_index );
878- 	if  (inode_killpriv_index  <  0 ) {
879- 		pr_warn ("Failed to find inode_rename, use kprobe instead!\n" );
880- 		register_kprobe (& renameat_kp );
881- 	} else  {
882- 		int  inode_rename_index  =  inode_killpriv_index  + 
883- 					 & security_hook_heads .inode_rename  - 
884- 					 & security_hook_heads .inode_killpriv ;
885- 		struct  hlist_head  * head_start  = 
886- 			(struct  hlist_head  * )& security_hook_heads ;
887- 		void  * inode_rename_head  =  head_start  +  inode_rename_index ;
888- 		if  (inode_rename_head  !=  & security_hook_heads .inode_rename ) {
889- 			pr_warn ("inode_rename's address has shifted!\n" );
890- 		}
891- 		KSU_LSM_HOOK_HACK_INIT (inode_rename_head , inode_rename ,
892- 				       ksu_inode_rename );
893- 	}
894- 	void  * cap_setuid  =  GET_SYMBOL_ADDR (cap_task_fix_setuid );
895- 	void  * setuid_head  =  find_head_addr (cap_setuid , NULL );
896- 	if  (setuid_head ) {
897- 		if  (setuid_head  !=  & security_hook_heads .task_fix_setuid ) {
898- 			pr_warn ("setuid's address has shifted!\n" );
899- 		}
900- 		KSU_LSM_HOOK_HACK_INIT (setuid_head , task_fix_setuid ,
901- 				       ksu_task_fix_setuid );
902- 	} else  {
903- 		pr_warn ("Failed to find task_fix_setuid!\n" );
904- 	}
905- 	smp_mb ();
906- }
907- #endif 
908- 
909658void  __init  ksu_core_init (void )
910659{
911660	ksu_lsm_hook_init ();
912661}
913- 
914- void  ksu_core_exit (void )
915- {
916- #ifdef  CONFIG_KPROBES 
917- 	pr_info ("ksu_core_kprobe_exit\n" );
918- 	// we dont use this now 
919- 	// ksu_kprobe_exit(); 
920- #endif 
921- }
0 commit comments