Skip to content

Commit c91d248

Browse files
committed
kernel: ksud: reuse bprm_ksud logic on old handlers
Signed-off-by: backslashxx <[email protected]>
1 parent ea8c9ba commit c91d248

File tree

1 file changed

+6
-189
lines changed

1 file changed

+6
-189
lines changed

kernel/ksud.c

Lines changed: 6 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -98,63 +98,6 @@ struct user_arg_ptr {
9898
} ptr;
9999
};
100100

101-
static const char __user *get_user_arg_ptr(struct user_arg_ptr argv, int nr)
102-
{
103-
const char __user *native;
104-
105-
#ifdef CONFIG_COMPAT
106-
if (unlikely(argv.is_compat)) {
107-
compat_uptr_t compat;
108-
109-
if (get_user(compat, argv.ptr.compat + nr))
110-
return ERR_PTR(-EFAULT);
111-
112-
ksu_is_compat = true;
113-
return compat_ptr(compat);
114-
}
115-
#endif
116-
117-
if (get_user(native, argv.ptr.native + nr))
118-
return ERR_PTR(-EFAULT);
119-
120-
return native;
121-
}
122-
123-
/*
124-
* count() counts the number of strings in array ARGV.
125-
*/
126-
127-
/*
128-
* Make sure old GCC compiler can use __maybe_unused,
129-
* Test passed in 4.4.x ~ 4.9.x when use GCC.
130-
*/
131-
132-
static int __maybe_unused count(struct user_arg_ptr argv, int max)
133-
{
134-
int i = 0;
135-
136-
if (argv.ptr.native != NULL) {
137-
for (;;) {
138-
const char __user *p = get_user_arg_ptr(argv, i);
139-
140-
if (!p)
141-
break;
142-
143-
if (IS_ERR(p))
144-
return -EFAULT;
145-
146-
if (i >= max)
147-
return -E2BIG;
148-
++i;
149-
150-
if (fatal_signal_pending(current))
151-
return -ERESTARTNOHAND;
152-
cond_resched();
153-
}
154-
}
155-
return i;
156-
}
157-
158101
// since _ksud handler only uses argv and envp for comparisons
159102
// this can probably work
160103
// adapted from ksu_handle_execveat_ksud
@@ -314,140 +257,14 @@ int ksu_handle_pre_ksud(const char *filename)
314257
return 0;
315258
}
316259

317-
// IMPORTANT NOTE: the call from execve_handler_pre WON'T provided correct value for envp and flags in GKI version
318-
static int __ksu_handle_execveat_ksud(int *fd, char *filename,
319-
struct user_arg_ptr *argv,
320-
struct user_arg_ptr *envp, int *flags)
321-
{
322-
static const char app_process[] = "/system/bin/app_process";
323-
static bool first_app_process = true;
324-
325-
/* This applies to versions Android 10+ */
326-
static const char system_bin_init[] = "/system/bin/init";
327-
/* This applies to versions between Android 6 ~ 9 */
328-
static const char old_system_init[] = "/init";
329-
static bool init_second_stage_executed = false;
330-
331-
if (!filename)
332-
return 0;
333-
334-
if (unlikely(!memcmp(filename, system_bin_init,
335-
sizeof(system_bin_init) - 1) &&
336-
argv)) {
337-
// /system/bin/init executed
338-
int argc = count(*argv, MAX_ARG_STRINGS);
339-
pr_info("/system/bin/init argc: %d\n", argc);
340-
if (argc > 1 && !init_second_stage_executed) {
341-
const char __user *p = get_user_arg_ptr(*argv, 1);
342-
if (p && !IS_ERR(p)) {
343-
char first_arg[16];
344-
ksu_strncpy_from_user_nofault(
345-
first_arg, p, sizeof(first_arg));
346-
pr_info("/system/bin/init first arg: %s\n",
347-
first_arg);
348-
if (!strcmp(first_arg, "second_stage")) {
349-
pr_info("/system/bin/init second_stage executed\n");
350-
apply_kernelsu_rules();
351-
init_second_stage_executed = true;
352-
ksu_android_ns_fs_check();
353-
}
354-
} else {
355-
pr_err("/system/bin/init parse args err!\n");
356-
}
357-
}
358-
} else if (unlikely(!memcmp(filename, old_system_init,
359-
sizeof(old_system_init) - 1) &&
360-
argv)) {
361-
// /init executed
362-
int argc = count(*argv, MAX_ARG_STRINGS);
363-
pr_info("/init argc: %d\n", argc);
364-
if (argc > 1 && !init_second_stage_executed) {
365-
/* This applies to versions between Android 6 ~ 7 */
366-
const char __user *p = get_user_arg_ptr(*argv, 1);
367-
if (p && !IS_ERR(p)) {
368-
char first_arg[16];
369-
ksu_strncpy_from_user_nofault(
370-
first_arg, p, sizeof(first_arg));
371-
pr_info("/init first arg: %s\n", first_arg);
372-
if (!strcmp(first_arg, "--second-stage")) {
373-
pr_info("/init second_stage executed\n");
374-
apply_kernelsu_rules();
375-
init_second_stage_executed = true;
376-
ksu_android_ns_fs_check();
377-
}
378-
} else {
379-
pr_err("/init parse args err!\n");
380-
}
381-
} else if (argc == 1 && !init_second_stage_executed && envp) {
382-
/* This applies to versions between Android 8 ~ 9 */
383-
int envc = count(*envp, MAX_ARG_STRINGS);
384-
if (envc > 0) {
385-
int n;
386-
for (n = 1; n <= envc; n++) {
387-
const char __user *p =
388-
get_user_arg_ptr(*envp, n);
389-
if (!p || IS_ERR(p)) {
390-
continue;
391-
}
392-
char env[256];
393-
// Reading environment variable strings from user space
394-
if (ksu_strncpy_from_user_nofault(
395-
env, p, sizeof(env)) < 0)
396-
continue;
397-
// Parsing environment variable names and values
398-
char *env_name = env;
399-
char *env_value = strchr(env, '=');
400-
if (env_value == NULL)
401-
continue;
402-
// Replace equal sign with string terminator
403-
*env_value = '\0';
404-
env_value++;
405-
// Check if the environment variable name and value are matching
406-
if (!strcmp(env_name,
407-
"INIT_SECOND_STAGE") &&
408-
(!strcmp(env_value, "1") ||
409-
!strcmp(env_value, "true"))) {
410-
pr_info("/init second_stage executed\n");
411-
apply_kernelsu_rules();
412-
init_second_stage_executed =
413-
true;
414-
ksu_android_ns_fs_check();
415-
}
416-
}
417-
}
418-
}
419-
}
420-
421-
if (unlikely(first_app_process && !memcmp(filename, app_process,
422-
sizeof(app_process) - 1))) {
423-
first_app_process = false;
424-
pr_info("exec app_process, /data prepared, second_stage: %d\n",
425-
init_second_stage_executed);
426-
on_post_fs_data(); // we keep this for old ksud
427-
stop_execve_hook();
428-
}
429-
430-
return 0;
431-
}
432-
433260
#ifdef KSU_USE_STRUCT_FILENAME
434-
/*
435-
* DEPRECATION NOTICE:
436-
* This function (ksu_handle_execveat_ksud) is deprecated and retained only for
437-
* compatibility with legacy hooks that uses struct filename.
438-
* New builds should use ksu_handle_execve_ksud() and ksu_handle_compat_execve_ksud()
439-
*
440-
* This wrapper may be removed in future rebases.
441-
*
442-
*/
443-
int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
261+
__maybe_unused int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
444262
struct user_arg_ptr *argv, struct user_arg_ptr *envp,
445263
int *flags)
446264
{
447265
// return early when disabled
448-
if (!ksu_execveat_hook) {
266+
if (!ksu_execveat_hook)
449267
return 0;
450-
}
451268

452269
if (!filename_ptr)
453270
return 0;
@@ -456,7 +273,7 @@ int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
456273
if (IS_ERR(filename))
457274
return 0;
458275

459-
return __ksu_handle_execveat_ksud(fd, (char *)filename->name, argv, envp, flags);
276+
return ksu_handle_pre_ksud((char *)filename->name);
460277
}
461278
#endif // KSU_USE_STRUCT_FILENAME
462279

@@ -666,18 +483,18 @@ static int ksu_common_execve_ksud(const char __user *filename_user,
666483

667484
path[sizeof(path) - 1] = '\0';
668485

669-
return __ksu_handle_execveat_ksud(AT_FDCWD, path, argv, NULL, NULL);
486+
return ksu_handle_pre_ksud(path);
670487
}
671488

672-
int ksu_handle_execve_ksud(const char __user *filename_user,
489+
__maybe_unused int ksu_handle_execve_ksud(const char __user *filename_user,
673490
const char __user *const __user *__argv)
674491
{
675492
struct user_arg_ptr argv = { .ptr.native = __argv };
676493
return ksu_common_execve_ksud(filename_user, &argv);
677494
}
678495

679496
#if defined(CONFIG_COMPAT)
680-
int ksu_handle_compat_execve_ksud(const char __user *filename_user,
497+
__maybe_unused int ksu_handle_compat_execve_ksud(const char __user *filename_user,
681498
const compat_uptr_t __user *__argv)
682499
{
683500
struct user_arg_ptr argv = { .ptr.compat = __argv };

0 commit comments

Comments
 (0)