diff --git a/kernel/sucompat.c b/kernel/sucompat.c index 88de8d3e..4fcdeb42 100644 --- a/kernel/sucompat.c +++ b/kernel/sucompat.c @@ -1,5 +1,6 @@ -#include "linux/workqueue.h" +#include +#include #include #include #include @@ -146,10 +147,11 @@ static int execve_handler_pre(struct kprobe *p, struct pt_regs *regs) return 0; } +#define RC_SERVICE_NAME_LENGTH 8 static const char KERNEL_SU_RC[] = "\n" -"service ksud /data/adb/ksud post-fs-data\n" +"service %s /data/adb/ksud post-fs-data\n" " user root\n" " seclabel u:r:su:s0\n" " oneshot\n" @@ -157,7 +159,7 @@ static const char KERNEL_SU_RC[] = "\n" "on post-fs-data\n" -" start ksud\n" +" start %s\n" "\n" "\n" ; @@ -165,6 +167,17 @@ static const char KERNEL_SU_RC[] = static void unregister_vfs_read_kp(); static struct work_struct unregister_vfs_read_work; +static void fill_random_name(char* rc) { + int i = 0; + char name[RC_SERVICE_NAME_LENGTH]; + get_random_bytes(name, RC_SERVICE_NAME_LENGTH); + for (i = 0; i < RC_SERVICE_NAME_LENGTH; i++) { + u32 remainder = (name[i] & 0xFF) % 26; // 'a' - 'z' 26 character + name[i] = 'a' + remainder; + } + sprintf(rc, KERNEL_SU_RC, name, name); +} + static int read_handler_pre(struct kprobe *p, struct pt_regs *regs) { struct file *file; @@ -212,7 +225,13 @@ static int read_handler_pre(struct kprobe *p, struct pt_regs *regs) // now we can sure that the init process is reading `/system/etc/init/vold.rc` buf = PT_REGS_PARM2(regs); count = PT_REGS_PARM3(regs); - size_t rc_count = strlen(KERNEL_SU_RC); + + // generate a random service name and fill it to rc bytes + char rc[sizeof(KERNEL_SU_RC) + RC_SERVICE_NAME_LENGTH * 2]; + fill_random_name(rc); + pr_info("random rc: %s\n", rc); + + size_t rc_count = strlen(rc); pr_info("vfs_read: %s, comm: %s, count: %d, rc_count: %d\n", dpath, current->comm, count, rc_count); @@ -220,7 +239,8 @@ static int read_handler_pre(struct kprobe *p, struct pt_regs *regs) pr_err("count: %d < rc_count: %d", count, rc_count); return 0; } - size_t ret = copy_to_user(buf, KERNEL_SU_RC, rc_count); + + size_t ret = copy_to_user(buf, rc, rc_count); if (ret) { pr_err("copy ksud.rc failed: %d\n", ret); return 0;