kernel: improve manager validation
This commit is contained in:
40
kernel/ksu.c
40
kernel/ksu.c
@@ -25,7 +25,7 @@
|
||||
#include "allowlist.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define KERNEL_SU_VERSION 5
|
||||
#define KERNEL_SU_VERSION 6
|
||||
|
||||
#define KERNEL_SU_OPTION 0xDEADBEEF
|
||||
|
||||
@@ -86,7 +86,7 @@ static bool is_manager() {
|
||||
return __manager_uid == current_uid().val;
|
||||
}
|
||||
|
||||
static bool become_manager() {
|
||||
static bool become_manager(char* pkg) {
|
||||
struct fdtable *files_table;
|
||||
int i = 0;
|
||||
struct path files_path;
|
||||
@@ -124,6 +124,11 @@ static bool become_manager() {
|
||||
if (startswith(cwd, "/data/app/") == 0 && endswith(cwd, "/base.apk") == 0) {
|
||||
// we have found the apk!
|
||||
pr_info("found apk: %s", cwd);
|
||||
if (!strstr(cwd, pkg)) {
|
||||
pr_info("apk path not match package name!\n");
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (is_manager_apk(cwd) == 0) {
|
||||
// check passed
|
||||
uid_t uid = current_uid().val;
|
||||
@@ -180,10 +185,37 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
|
||||
|
||||
if (arg2 == CMD_BECOME_MANAGER) {
|
||||
// someone wants to be root manager, just check it!
|
||||
bool success = become_manager();
|
||||
// arg3 should be `/data/data/<manager_package_name>`
|
||||
char param[128];
|
||||
const char* prefix = "/data/data/";
|
||||
if (copy_from_user(param, arg3, sizeof(param))) {
|
||||
pr_err("become_manager: copy param err\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startswith(param, (char*) prefix) != 0) {
|
||||
pr_info("become_manager: invalid param: %s\n", param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// stat the param, app must have permission to do this
|
||||
// otherwise it may fake the path!
|
||||
struct path path;
|
||||
if (kern_path(param, LOOKUP_DIRECTORY, &path)) {
|
||||
pr_err("become_manager: kern_path err\n");
|
||||
return 0;
|
||||
}
|
||||
if (path.dentry->d_inode->i_uid.val != current_uid().val) {
|
||||
pr_err("become_manager: path uid != current uid\n");
|
||||
return 0;
|
||||
}
|
||||
char* pkg = param + strlen(prefix);
|
||||
pr_info("become_manager: param pkg: %s\n", pkg);
|
||||
|
||||
bool success = become_manager(pkg);
|
||||
if (success) {
|
||||
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
|
||||
pr_err("prctl reply error\n");
|
||||
pr_err("become_manager: prctl reply error\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user