diff --git a/cgroupv2_freeze/Makefile b/cgroupv2_freeze/Makefile
index 76959a1..16bd700 100644
--- a/cgroupv2_freeze/Makefile
+++ b/cgroupv2_freeze/Makefile
@@ -1,4 +1,4 @@
-MYKPM_VERSION := 1.0.5
+MYKPM_VERSION := 1.0.6
ifndef KP_DIR
KP_DIR = ../KernelPatch
diff --git a/cgroupv2_freeze/README.md b/cgroupv2_freeze/README.md
index ab83ef4..cf1c009 100644
--- a/cgroupv2_freeze/README.md
+++ b/cgroupv2_freeze/README.md
@@ -3,10 +3,14 @@
为低版本内核添加 cgroup.freeze
## 更新记录
+### 1.0.6
+为高版本内核禁用 `CONFIG_STATIC_USERMODEHELPER`
### 1.0.5
-补全uid模式, 不再需要附加模块
+补全uid模式
+不再需要附加模块
### 1.0.4
-使用其他方式替代所有内核版本判断条件,变更 task_struct->jobctl 获取方式
+使用其他方式替代所有内核版本判断条件
+变更 task_struct->jobctl 获取方式
### 1.0.3
支持 4.19
### 1.0.2
diff --git a/cgroupv2_freeze/cfv2_offsets.c b/cgroupv2_freeze/cfv2_offsets.c
index 4d36d2d..808a4b0 100644
--- a/cgroupv2_freeze/cfv2_offsets.c
+++ b/cgroupv2_freeze/cfv2_offsets.c
@@ -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;
+}
diff --git a/cgroupv2_freeze/cgroupv2_freeze.c b/cgroupv2_freeze/cgroupv2_freeze.c
index 4a21606..9d7aaed 100644
--- a/cgroupv2_freeze/cgroupv2_freeze.c
+++ b/cgroupv2_freeze/cgroupv2_freeze.c
@@ -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);
@@ -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 添加必要的标志
@@ -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/";
@@ -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;
}
@@ -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);
@@ -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);
}
@@ -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;
diff --git a/cgroupv2_freeze/cgroupv2_freeze.h b/cgroupv2_freeze/cgroupv2_freeze.h
index 057f332..8f4496e 100644
--- a/cgroupv2_freeze/cgroupv2_freeze.h
+++ b/cgroupv2_freeze/cgroupv2_freeze.h
@@ -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 */