Skip to content

Commit

Permalink
[cgroupv2_freeze] 禁用 CONFIG_STATIC_USERMODEHELPER
Browse files Browse the repository at this point in the history
  • Loading branch information
lzghzr committed Jul 30, 2024
1 parent 67a4844 commit 8830f7b
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 7 deletions.
2 changes: 1 addition & 1 deletion cgroupv2_freeze/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
MYKPM_VERSION := 1.0.5
MYKPM_VERSION := 1.0.6

ifndef KP_DIR
KP_DIR = ../KernelPatch
Expand Down
8 changes: 6 additions & 2 deletions cgroupv2_freeze/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
为低版本内核添加 cgroup.freeze

## 更新记录
### 1.0.6
为高版本内核禁用 `CONFIG_STATIC_USERMODEHELPER`
### 1.0.5
补全uid模式, 不再需要附加模块
补全uid模式<br />
不再需要附加模块
### 1.0.4
使用其他方式替代所有内核版本判断条件,变更 task_struct->jobctl 获取方式
使用其他方式替代所有内核版本判断条件<br />
变更 task_struct->jobctl 获取方式
### 1.0.3
支持 4.19
### 1.0.2
Expand Down
5 changes: 5 additions & 0 deletions cgroupv2_freeze/cfv2_offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,8 @@ static inline struct cgroup* css_set_dfl_cgrp(struct css_set* cset) {
struct cgroup* cgrp = *(struct cgroup**)((uintptr_t)cset + css_set_dfl_cgrp_offset);
return cgrp;
}
// subprocess_info_argv
static inline char** subprocess_info_argv(struct subprocess_info* sub_info) {
char** argv = *(char***)((uintptr_t)sub_info + subprocess_info_argv_offset);
return argv;
}
65 changes: 61 additions & 4 deletions cgroupv2_freeze/cgroupv2_freeze.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ int kfunc_def(kstrtoint)(const char* s, unsigned int base, int* res);
char* kfunc_def(strim)(char* s);
// run_cmd
int kfunc_def(call_usermodehelper)(const char* path, char** argv, char** envp, int wait);
int kfunc_def(call_usermodehelper_exec)(struct subprocess_info* info, int wait);
static int* selinux_enforcing;
struct selinux_state* selinux_state;

// hook cgroup_addrm_files
static int (*cgroup_addrm_files)(struct cgroup_subsys_state* css, struct cgroup* cgrp, struct cftype cfts[], bool is_add);
Expand All @@ -79,7 +81,9 @@ signal_struct_group_exit_task_offset = UZERO, signal_struct_flags_offset = UZERO
seq_file_private_offset = UZERO,
freezer_state_offset = UZERO, cgroup_flags_offset = UZERO,
css_set_dfl_cgrp_offset = UZERO,
css_task_iter_start_ver5 = UZERO, cgroup_kn_lock_live_ver5 = UZERO, cftype_ver5 = UZERO, cgroup_base_files_ver5 = UZERO;
subprocess_info_path_offset = UZERO, subprocess_info_argv_offset = UZERO,
css_task_iter_start_ver5 = UZERO, cgroup_kn_lock_live_ver5 = UZERO, cftype_ver5 = UZERO, cgroup_base_files_ver5 = UZERO,
call_usermodehelper_enable = UZERO;
#include "cfv2_offsets.c"

// 为待冻结的 task 以及 cgroup 添加必要的标志
Expand Down Expand Up @@ -329,15 +333,39 @@ static void proc_pid_wchan_before(hook_fargs4_t* args, void* udata) {
}
}

static void call_usermodehelper_exec_before(hook_fargs1_t* args, void* udata) {
struct subprocess_info* sub_info = (struct subprocess_info*)args->arg0;
if (!sub_info || call_usermodehelper_enable == UZERO)
return;

char** argv = subprocess_info_argv(sub_info);
*(char**)((uintptr_t)sub_info + subprocess_info_path_offset) = argv[0];
}

static void run_cmd(char* cmd[]) {
char* envp[] = { "HOME=/", "PATH=/sbin:/bin", NULL };
bool sel = true;

call_usermodehelper_enable = IZERO;
if (selinux_enforcing) {
sel = *selinux_enforcing;
*selinux_enforcing = false;
} else {
sel = selinux_state->enforcing;
selinux_state->enforcing = false;
}

*selinux_enforcing = false;
for (int i = 0; cmd[i]; i++) {
char* argv[] = { "/bin/sh", "-c", cmd[i], NULL };
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
}
*selinux_enforcing = true;

call_usermodehelper_enable = UZERO;
if (selinux_enforcing) {
*selinux_enforcing = sel;
} else {
selinux_state->enforcing = sel;
}
}

static const char apm[] = "/data/adb/modules/";
Expand Down Expand Up @@ -639,6 +667,28 @@ static long calculate_offsets() {
if (css_set_dfl_cgrp_offset == UZERO) {
return -11;
}
// 获取 subprocess_info->path, subprocess_info->argv
uint32_t* call_usermodehelper_exec_src = (uint32_t*)kfunc(call_usermodehelper_exec);
for (u32 i = 0; i < 0x20; i++) {
#ifdef CONFIG_DEBUG
logkm("call_usermodehelper_exec %x %llx\n", i, call_usermodehelper_exec_src[i]);
#endif /* CONFIG_DEBUG */
if (call_usermodehelper_exec_src[i] == ARM64_RET) {
break;
} else if ((call_usermodehelper_exec_src[i] & MASK_LDR_64_Rn_X0) == INST_LDR_64_Rn_X0) {
uint64_t imm12 = bits32(call_usermodehelper_exec_src[i], 21, 10);
subprocess_info_path_offset = sign64_extend((imm12 << 0b11u), 16u);
subprocess_info_argv_offset = subprocess_info_path_offset + 0x8;
break;
}
}
#ifdef CONFIG_DEBUG
logkm("subprocess_info_path_offset=0x%llx\n", subprocess_info_path_offset);
logkm("subprocess_info_argv_offset=0x%llx\n", subprocess_info_argv_offset);
#endif /* CONFIG_DEBUG */
if (subprocess_info_path_offset == UZERO || subprocess_info_argv_offset == UZERO) {
return -11;
}

return 0;
}
Expand Down Expand Up @@ -674,7 +724,12 @@ static long inline_hook_init(const char* args, const char* event, void* __user r
kfunc_lookup_name(strim);

kfunc_lookup_name(call_usermodehelper);
lookup_name(selinux_enforcing);
kfunc_lookup_name(call_usermodehelper_exec);

selinux_enforcing = (typeof(selinux_enforcing))kallsyms_lookup_name("selinux_enforcing");
selinux_state = (typeof(selinux_state))kallsyms_lookup_name("selinux_state");
if (!selinux_enforcing && !selinux_state)
return -21;

lookup_name(cgroup_addrm_files);
lookup_name(cgroup_init_cftypes);
Expand Down Expand Up @@ -712,6 +767,7 @@ static long inline_hook_init(const char* args, const char* event, void* __user r
hook_func(__kernfs_create_file, 8, NULL, __kernfs_create_file_after, NULL);
}

hook_func(kf_call_usermodehelper_exec, 1, call_usermodehelper_exec_before, NULL, NULL);
if (!event || strcmp(event, "load-file")) {
hook_func(do_filp_open, 3, NULL, do_filp_open_after, NULL);
}
Expand All @@ -733,6 +789,7 @@ static long inline_hook_exit(void* __user reserved) {
unhook_func(cgroup_procs_write);
unhook_func(css_set_move_task);
unhook_func(__kernfs_create_file);
unhook_func(kf_call_usermodehelper_exec);
unhook_func(do_filp_open);

return 0;
Expand Down
12 changes: 12 additions & 0 deletions cgroupv2_freeze/cgroupv2_freeze.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,16 @@ struct open_flags {
int lookup_flags;
};

// security.h
struct selinux_state {
bool disabled;
bool enforcing;
bool checkreqprot;
bool initialized;
// unknow
};

// linux/umh.h
struct subprocess_info;

#endif /* __CGROUP_FREEZE_H */

0 comments on commit 8830f7b

Please sign in to comment.