Skip to content

Commit 008b14a

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

File tree

1 file changed

+5
-179
lines changed

1 file changed

+5
-179
lines changed

kernel/ksud.c

Lines changed: 5 additions & 179 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
@@ -303,131 +246,14 @@ int ksu_handle_pre_ksud(const char *filename)
303246
return ksu_handle_bprm_ksud(filename, argv1, envp, envp_copy_len);
304247
}
305248

306-
// IMPORTANT NOTE: the call from execve_handler_pre WON'T provided correct value for envp and flags in GKI version
307-
static int __ksu_handle_execveat_ksud(int *fd, char *filename,
308-
struct user_arg_ptr *argv,
309-
struct user_arg_ptr *envp, int *flags)
310-
{
311-
static const char app_process[] = "/system/bin/app_process";
312-
static bool first_app_process = true;
313-
314-
/* This applies to versions Android 10+ */
315-
static const char system_bin_init[] = "/system/bin/init";
316-
/* This applies to versions between Android 6 ~ 9 */
317-
static const char old_system_init[] = "/init";
318-
static bool init_second_stage_executed = false;
319-
320-
if (!filename)
321-
return 0;
322-
323-
if (unlikely(!memcmp(filename, system_bin_init,
324-
sizeof(system_bin_init) - 1) &&
325-
argv)) {
326-
// /system/bin/init executed
327-
int argc = count(*argv, MAX_ARG_STRINGS);
328-
pr_info("/system/bin/init argc: %d\n", argc);
329-
if (argc > 1 && !init_second_stage_executed) {
330-
const char __user *p = get_user_arg_ptr(*argv, 1);
331-
if (p && !IS_ERR(p)) {
332-
char first_arg[16];
333-
ksu_strncpy_from_user_nofault(
334-
first_arg, p, sizeof(first_arg));
335-
pr_info("/system/bin/init first arg: %s\n",
336-
first_arg);
337-
if (!strcmp(first_arg, "second_stage")) {
338-
pr_info("/system/bin/init second_stage executed\n");
339-
apply_kernelsu_rules();
340-
init_second_stage_executed = true;
341-
ksu_android_ns_fs_check();
342-
}
343-
} else {
344-
pr_err("/system/bin/init parse args err!\n");
345-
}
346-
}
347-
} else if (unlikely(!memcmp(filename, old_system_init,
348-
sizeof(old_system_init) - 1) &&
349-
argv)) {
350-
// /init executed
351-
int argc = count(*argv, MAX_ARG_STRINGS);
352-
pr_info("/init argc: %d\n", argc);
353-
if (argc > 1 && !init_second_stage_executed) {
354-
/* This applies to versions between Android 6 ~ 7 */
355-
const char __user *p = get_user_arg_ptr(*argv, 1);
356-
if (p && !IS_ERR(p)) {
357-
char first_arg[16];
358-
ksu_strncpy_from_user_nofault(
359-
first_arg, p, sizeof(first_arg));
360-
pr_info("/init first arg: %s\n", first_arg);
361-
if (!strcmp(first_arg, "--second-stage")) {
362-
pr_info("/init second_stage executed\n");
363-
apply_kernelsu_rules();
364-
init_second_stage_executed = true;
365-
ksu_android_ns_fs_check();
366-
}
367-
} else {
368-
pr_err("/init parse args err!\n");
369-
}
370-
} else if (argc == 1 && !init_second_stage_executed && envp) {
371-
/* This applies to versions between Android 8 ~ 9 */
372-
int envc = count(*envp, MAX_ARG_STRINGS);
373-
if (envc > 0) {
374-
int n;
375-
for (n = 1; n <= envc; n++) {
376-
const char __user *p =
377-
get_user_arg_ptr(*envp, n);
378-
if (!p || IS_ERR(p)) {
379-
continue;
380-
}
381-
char env[256];
382-
// Reading environment variable strings from user space
383-
if (ksu_strncpy_from_user_nofault(
384-
env, p, sizeof(env)) < 0)
385-
continue;
386-
// Parsing environment variable names and values
387-
char *env_name = env;
388-
char *env_value = strchr(env, '=');
389-
if (env_value == NULL)
390-
continue;
391-
// Replace equal sign with string terminator
392-
*env_value = '\0';
393-
env_value++;
394-
// Check if the environment variable name and value are matching
395-
if (!strcmp(env_name,
396-
"INIT_SECOND_STAGE") &&
397-
(!strcmp(env_value, "1") ||
398-
!strcmp(env_value, "true"))) {
399-
pr_info("/init second_stage executed\n");
400-
apply_kernelsu_rules();
401-
init_second_stage_executed =
402-
true;
403-
ksu_android_ns_fs_check();
404-
}
405-
}
406-
}
407-
}
408-
}
409-
410-
if (unlikely(first_app_process && !memcmp(filename, app_process,
411-
sizeof(app_process) - 1))) {
412-
first_app_process = false;
413-
pr_info("exec app_process, /data prepared, second_stage: %d\n",
414-
init_second_stage_executed);
415-
on_post_fs_data(); // we keep this for old ksud
416-
stop_execve_hook();
417-
}
418-
419-
return 0;
420-
}
421-
422249
// keep this for manually hooked builds
423250
__maybe_unused int ksu_handle_execveat_ksud(int *fd, struct filename **filename_ptr,
424251
struct user_arg_ptr *argv, struct user_arg_ptr *envp,
425252
int *flags)
426253
{
427254
// return early when disabled
428-
if (!ksu_execveat_hook) {
255+
if (!ksu_execveat_hook)
429256
return 0;
430-
}
431257

432258
if (!filename_ptr)
433259
return 0;
@@ -436,7 +262,7 @@ __maybe_unused int ksu_handle_execveat_ksud(int *fd, struct filename **filename_
436262
if (IS_ERR(filename))
437263
return 0;
438264

439-
return __ksu_handle_execveat_ksud(fd, (char *)filename->name, argv, envp, flags);
265+
return ksu_handle_pre_ksud((char *)filename->name);
440266
}
441267

442268
static ssize_t (*orig_read)(struct file *, char __user *, size_t, loff_t *);
@@ -645,18 +471,18 @@ static int ksu_common_execve_ksud(const char __user *filename_user,
645471

646472
path[sizeof(path) - 1] = '\0';
647473

648-
return __ksu_handle_execveat_ksud(AT_FDCWD, path, argv, NULL, NULL);
474+
return ksu_handle_pre_ksud(path);
649475
}
650476

651-
int ksu_handle_execve_ksud(const char __user *filename_user,
477+
__maybe_unused int ksu_handle_execve_ksud(const char __user *filename_user,
652478
const char __user *const __user *__argv)
653479
{
654480
struct user_arg_ptr argv = { .ptr.native = __argv };
655481
return ksu_common_execve_ksud(filename_user, &argv);
656482
}
657483

658484
#if defined(CONFIG_COMPAT)
659-
int ksu_handle_compat_execve_ksud(const char __user *filename_user,
485+
__maybe_unused int ksu_handle_compat_execve_ksud(const char __user *filename_user,
660486
const compat_uptr_t __user *__argv)
661487
{
662488
struct user_arg_ptr argv = { .ptr.compat = __argv };

0 commit comments

Comments
 (0)