@@ -62,10 +62,10 @@ static inline bool is_allow_su()
6262 // we are manager, allow!
6363 return true;
6464 }
65- return ksu_is_allow_uid (current_uid (). val );
65+ return ksu_is_allow_uid (ksu_current_uid () );
6666}
6767
68- static inline bool is_unsupported_app_uid (uid_t uid )
68+ static inline bool is_unsupported_uid (uid_t uid )
6969{
7070#define LAST_APPLICATION_UID 19999
7171 uid_t appid = uid % 100000 ;
@@ -120,7 +120,12 @@ static void setup_groups(struct root_profile *profile, struct cred *cred)
120120
121121static void disable_seccomp (void )
122122{
123- assert_spin_locked (& current -> sighand -> siglock );
123+ struct task_struct * tsk = get_current ();
124+
125+ pr_info ("%s++\n" , __func__ );
126+ spin_lock_irq (& tsk -> sighand -> siglock );
127+ assert_spin_locked (& tsk -> sighand -> siglock );
128+
124129 // disable seccomp
125130#if defined(CONFIG_GENERIC_ENTRY ) && \
126131 LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 11 , 0 )
@@ -130,40 +135,56 @@ static void disable_seccomp(void)
130135#endif
131136
132137#ifdef CONFIG_SECCOMP
133- current -> seccomp .mode = 0 ;
134- current -> seccomp .filter = NULL ;
138+ tsk -> seccomp .mode = 0 ;
139+ if (tsk -> seccomp .filter == NULL ) {
140+ pr_warn ("tsk->seccomp.filter is NULL already!\n" );
141+ goto out ;
142+ }
143+
144+ // 5.9+ have filter_count and use seccomp_filter_release
145+ #if LINUX_VERSION_CODE >= KERNEL_VERSION (5 , 9 , 0 )
146+ seccomp_filter_release (tsk );
147+ atomic_set (& tsk -> seccomp .filter_count , 0 );
135148#else
149+ put_seccomp_filter (tsk );
150+ tsk -> seccomp .filter = NULL ;
151+ #endif
136152#endif
153+
154+ out :
155+ spin_unlock_irq (& tsk -> sighand -> siglock );
156+ pr_info ("%s--\n" , __func__ );
137157}
138158
139159void escape_to_root (void )
140160{
141- struct cred * cred ;
142-
143- cred = prepare_creds ();
144- if (!cred ) {
161+ struct cred * newcreds = prepare_creds ();
162+ if (newcreds == NULL ) {
145163 pr_err ("%s: failed to allocate new cred.\n" , __func__ );
146164 return ;
147165 }
148166
149- if (cred -> euid . val == 0 ) {
167+ if (ksu_cred_euid ( newcreds ) == 0 ) {
150168 pr_warn ("Already root, don't escape!\n" );
151- abort_creds (cred );
169+ abort_creds (newcreds );
152170 return ;
153171 }
154172
155- struct root_profile * profile = ksu_get_root_profile (cred -> uid .val );
173+ struct root_profile * profile =
174+ ksu_get_root_profile (ksu_cred_uid (newcreds ));
175+
176+ ksu_cred_uid (newcreds ) = profile -> uid ;
177+ ksu_cred_suid (newcreds ) = profile -> uid ;
178+ ksu_cred_euid (newcreds ) = profile -> uid ;
179+ ksu_cred_fsuid (newcreds ) = profile -> uid ;
156180
157- cred -> uid . val = profile -> uid ;
158- cred -> suid . val = profile -> uid ;
159- cred -> euid . val = profile -> uid ;
160- cred -> fsuid . val = profile -> uid ;
181+ ksu_cred_gid ( newcreds ) = profile -> gid ;
182+ ksu_cred_fsgid ( newcreds ) = profile -> gid ;
183+ ksu_cred_sgid ( newcreds ) = profile -> gid ;
184+ ksu_cred_egid ( newcreds ) = profile -> gid ;
161185
162- cred -> gid .val = profile -> gid ;
163- cred -> fsgid .val = profile -> gid ;
164- cred -> sgid .val = profile -> gid ;
165- cred -> egid .val = profile -> gid ;
166- cred -> securebits = 0 ;
186+ // no wrapper, ignore it.
187+ newcreds -> securebits = 0 ;
167188
168189 BUILD_BUG_ON (sizeof (profile -> capabilities .effective ) !=
169190 sizeof (kernel_cap_t ));
@@ -173,23 +194,17 @@ void escape_to_root(void)
173194 // we add it here but don't add it to cap_inhertiable, it would be dropped automaticly after exec!
174195 u64 cap_for_ksud =
175196 profile -> capabilities .effective | CAP_DAC_READ_SEARCH ;
176- memcpy (& cred -> cap_effective , & cap_for_ksud ,
177- sizeof (cred -> cap_effective ));
178- memcpy (& cred -> cap_permitted , & profile -> capabilities .effective ,
179- sizeof (cred -> cap_permitted ));
180- memcpy (& cred -> cap_bset , & profile -> capabilities .effective ,
181- sizeof (cred -> cap_bset ));
182-
183- setup_groups (profile , cred );
184-
185- commit_creds (cred );
186-
187- // Refer to kernel/seccomp.c: seccomp_set_mode_strict
188- // When disabling Seccomp, ensure that current->sighand->siglock is held during the operation.
189- spin_lock_irq (& current -> sighand -> siglock );
197+ memcpy (& newcreds -> cap_effective , & cap_for_ksud ,
198+ sizeof (newcreds -> cap_effective ));
199+ memcpy (& newcreds -> cap_permitted , & profile -> capabilities .effective ,
200+ sizeof (newcreds -> cap_permitted ));
201+ memcpy (& newcreds -> cap_bset , & profile -> capabilities .effective ,
202+ sizeof (newcreds -> cap_bset ));
203+
204+ setup_groups (profile , newcreds );
205+ commit_creds (newcreds );
206+
190207 disable_seccomp ();
191- spin_unlock_irq (& current -> sighand -> siglock );
192-
193208 setup_selinux (profile -> selinux_domain );
194209}
195210
@@ -200,7 +215,7 @@ int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry)
200215 return 0 ;
201216 }
202217
203- if (current_uid (). val != 1000 ) {
218+ if (ksu_current_uid () != 1000 ) {
204219 // skip non system uid
205220 return 0 ;
206221 }
@@ -268,14 +283,14 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
268283 }
269284
270285 // TODO: find it in throne tracker!
271- uid_t current_uid_val = current_uid (). val ;
286+ uid_t current_uid_val = ksu_current_uid () ;
272287 uid_t manager_uid = ksu_get_manager_uid ();
273288 if (current_uid_val != manager_uid &&
274289 current_uid_val % 100000 == manager_uid ) {
275290 ksu_set_manager_uid (current_uid_val );
276291 }
277292
278- bool from_root = 0 == current_uid (). val ;
293+ bool from_root = 0 == ksu_current_uid () ;
279294 bool from_manager = is_manager ();
280295
281296 if (!from_root && !from_manager ) {
@@ -299,7 +314,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
299314
300315 if (arg2 == CMD_GRANT_ROOT ) {
301316 if (is_allow_su ()) {
302- pr_info ("allow root for: %d\n" , current_uid (). val );
317+ pr_info ("allow root for: %d\n" , ksu_current_uid () );
303318 escape_to_root ();
304319 if (copy_to_user (result , & reply_ok , sizeof (reply_ok ))) {
305320 pr_err ("grant_root: prctl reply error\n" );
@@ -511,13 +526,14 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
511526 return 0 ;
512527}
513528
514- static bool is_non_appuid (kuid_t uid )
529+ static bool is_appuid (kuid_t uid )
515530{
516531#define PER_USER_RANGE 100000
517532#define FIRST_APPLICATION_UID 10000
533+ #define LAST_APPLICATION_UID 19999
518534
519535 uid_t appid = uid .val % PER_USER_RANGE ;
520- return appid < FIRST_APPLICATION_UID ;
536+ return appid >= FIRST_APPLICATION_UID && appid <= LAST_APPLICATION_UID ;
521537}
522538
523539static bool should_umount (struct path * path )
@@ -528,7 +544,7 @@ static bool should_umount(struct path *path)
528544
529545 if (current -> nsproxy -> mnt_ns == init_nsproxy .mnt_ns ) {
530546 pr_info ("ignore global mnt namespace process: %d\n" ,
531- current_uid (). val );
547+ ksu_current_uid () );
532548 return false;
533549 }
534550
@@ -614,33 +630,29 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
614630 return 0 ;
615631 }
616632
617- if (is_non_appuid (new_uid )) {
618- #ifdef CONFIG_KSU_DEBUG
619- pr_info ("handle setuid ignore non application uid: %d\n" , new_uid .val );
620- #endif
633+ if (!is_appuid (new_uid ) || is_unsupported_uid (new_uid .val )) {
634+ // pr_info("handle setuid ignore non application or isolated uid: %d\n", new_uid.val);
621635 return 0 ;
622636 }
623637
624- // isolated process may be directly forked from zygote, always unmount
625- if (is_unsupported_app_uid (new_uid .val )) {
626- #ifdef CONFIG_KSU_DEBUG
627- pr_info ("handle umount for unsupported application uid: %d\n" , new_uid .val );
628- #endif
629- goto do_umount ;
638+ if (ksu_is_allow_uid (new_uid .val )) {
639+ // pr_info("handle setuid ignore allowed application: %d\n", new_uid.val);
640+ return 0 ;
630641 }
631642
632- if (ksu_is_allow_uid (new_uid .val )) {
643+ if (!ksu_uid_should_umount (new_uid .val )) {
644+ return 0 ;
645+ } else {
633646#ifdef CONFIG_KSU_DEBUG
634- pr_info ("handle setuid ignore allowed application : %d\n" , new_uid .val );
647+ pr_info ("uid : %d should not umount! \n" , current_uid () .val );
635648#endif
636- return 0 ;
637649 }
638650
639- do_umount :
640651 // check old process's selinux context, if it is not zygote, ignore it!
641652 // because some su apps may setuid to untrusted_app but they are in global mount namespace
642653 // when we umount for such process, that is a disaster!
643- if (!is_zygote (old -> security )) {
654+ bool is_zygote_child = is_zygote (old -> security );
655+ if (!is_zygote_child ) {
644656 pr_info ("handle umount ignore non zygote child: %d\n" ,
645657 current -> pid );
646658 return 0 ;
0 commit comments