pullout envp

This commit is contained in:
backslashxx
2025-09-24 09:05:45 +08:00
committed by ShirkNeko
parent ac05038e64
commit 6c145179d4

View File

@@ -424,23 +424,37 @@ bool ksu_is_safe_mode()
#ifdef CONFIG_KSU_KPROBES_HOOK #ifdef CONFIG_KSU_KPROBES_HOOK
static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs) static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
{ {
/*
asmlinkage int sys_execve(const char __user *filenamei,
const char __user *const __user *argv,
const char __user *const __user *envp, struct pt_regs *regs)
*/
struct pt_regs *real_regs = PT_REAL_REGS(regs); struct pt_regs *real_regs = PT_REAL_REGS(regs);
const char __user *filename_user = (const char __user *)PT_REGS_PARM1(real_regs); const char __user *filename_user = (const char __user *)PT_REGS_PARM1(real_regs);
const char __user *const __user *__argv = (const char __user *const __user *)PT_REGS_PARM2(real_regs); const char __user *const __user *__argv = (const char __user *const __user *)PT_REGS_PARM2(real_regs);
const char __user *const __user *__envp = (const char __user *const __user *)PT_REGS_PARM3(real_regs);
const char __user *arg1_user = NULL;
char path[32]; char path[32];
char argv1[32] = {0};
if (!filename_user) if (!filename_user)
return 0; return 0;
// filename stage
if (ksu_copy_from_user_retry(path, filename_user, sizeof(path))) if (ksu_copy_from_user_retry(path, filename_user, sizeof(path)))
return 0; return 0;
path[sizeof(path) - 1] = '\0'; path[sizeof(path) - 1] = '\0';
// not /system/bin/init, not /init, not /system/bin/app_process (64/32 thingy)
// we dont care !!
if (likely(strcmp(path, "/system/bin/init") && strcmp(path, "/init")
&& !strstarts(path, "/system/bin/app_process") ))
return 0;
// argv stage
char argv1[32] = {0};
// memzero_explicit(argv1, 32);
if (__argv) { if (__argv) {
const char __user *arg1_user = NULL;
// grab argv[1] pointer // grab argv[1] pointer
// this looks like // this looks like
/* /*
@@ -449,19 +463,82 @@ static int sys_execve_handler_pre(struct kprobe *p, struct pt_regs *regs)
* 0x1002 arg * 0x1002 arg
*/ */
if (ksu_copy_from_user_retry(&arg1_user, __argv + 1, sizeof(arg1_user))) if (ksu_copy_from_user_retry(&arg1_user, __argv + 1, sizeof(arg1_user)))
goto submit; // copy argv[1] pointer fail, probably no argv1 !! goto no_argv1; // copy argv[1] pointer fail, probably no argv1 !!
if (arg1_user) if (arg1_user)
ksu_copy_from_user_retry(argv1, arg1_user, sizeof(argv1)); ksu_copy_from_user_retry(argv1, arg1_user, sizeof(argv1));
} }
submit: no_argv1:
argv1[sizeof(argv1) - 1] = '\0'; argv1[sizeof(argv1) - 1] = '\0';
#ifdef CONFIG_KSU_DEBUG
pr_info("%s: filename: %s argv[1]:%s\n", __func__, path, argv1);
#endif
return ksu_handle_bprm_ksud(path, argv1, "no_envp", strlen("no_envp")); // envp stage
#define ENVP_MAX 256
char envp[ENVP_MAX] = {0};
char *dst = envp;
size_t envp_len = 0;
int i = 0; // to track user pointer offset from __envp
// memzero_explicit(envp, ENVP_MAX);
if (__envp) {
do {
const char __user *env_entry_user = NULL;
// this is also like argv above
/*
* 0x1001 PATH=/bin
* 0x1002 VARIABLE=value
* 0x1002 some_more_env_var=1
*/
// check if pointer exists
if (ksu_copy_from_user_retry(&env_entry_user, __envp + i, sizeof(env_entry_user)))
break;
// check if no more env entry
if (!env_entry_user)
break;
// probably redundant to while condition but ok
if (envp_len >= ENVP_MAX - 1)
break;
// copy strings from env_entry_user pointer that we collected
// also break if failed
if (ksu_copy_from_user_retry(dst, env_entry_user, ENVP_MAX - envp_len))
break;
// get the length of that new copy above
// get lngth of dst as far as ENVP_MAX - current collected envp_len
size_t len = strnlen(dst, ENVP_MAX - envp_len);
if (envp_len + len + 1 > ENVP_MAX)
break; // if more than 255 bytes, bail
dst[len] = '\0';
// collect total number of copied strings
envp_len = envp_len + len + 1;
// increment dst address since we need to put something on next iter
dst = dst + len + 1;
// pointer walk, __envp + i
i++;
} while (envp_len < ENVP_MAX);
}
/*
at this point, we shoul've collected envp from
* 0x1001 PATH=/bin
* 0x1002 VARIABLE=value
* 0x1002 some_more_env_var=1
to
* 0x1234 PATH=/bin\0VARIABLE=value\0some_more_env_var=1\0\0\0\0
*/
envp[ENVP_MAX - 1] = '\0';
#ifdef CONFIG_KSU_DEBUG
pr_info("%s: filename: %s argv[1]:%s envp_len: %zu\n", __func__, path, argv1, envp_len);
#endif
return ksu_handle_bprm_ksud(path, argv1, envp, envp_len);
} }
static int sys_read_handler_pre(struct kprobe *p, struct pt_regs *regs) static int sys_read_handler_pre(struct kprobe *p, struct pt_regs *regs)