kernel: prevent become manager when failed. close #1328

This commit is contained in:
weishu
2024-02-03 20:03:26 +08:00
parent eb02e42bc7
commit 07e475c5dc

View File

@@ -128,7 +128,8 @@ void escape_to_root(void)
// setup capabilities // setup capabilities
// we need CAP_DAC_READ_SEARCH becuase `/data/adb/ksud` is not accessible for non root process // we need CAP_DAC_READ_SEARCH becuase `/data/adb/ksud` is not accessible for non root process
// we add it here but don't add it to cap_inhertiable, it would be dropped automaticly after exec! // we add it here but don't add it to cap_inhertiable, it would be dropped automaticly after exec!
u64 cap_for_ksud = profile->capabilities.effective | CAP_DAC_READ_SEARCH; u64 cap_for_ksud =
profile->capabilities.effective | CAP_DAC_READ_SEARCH;
memcpy(&cred->cap_effective, &cap_for_ksud, memcpy(&cred->cap_effective, &cap_for_ksud,
sizeof(cred->cap_effective)); sizeof(cred->cap_effective));
memcpy(&cred->cap_inheritable, &profile->capabilities.effective, memcpy(&cred->cap_inheritable, &profile->capabilities.effective,
@@ -243,7 +244,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
#ifdef CONFIG_KSU_DEBUG #ifdef CONFIG_KSU_DEBUG
pr_err("become_manager: copy param err\n"); pr_err("become_manager: copy param err\n");
#endif #endif
return 0; goto block;
} }
// for user 0, it is /data/data // for user 0, it is /data/data
@@ -261,7 +262,7 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
if (startswith(param, (char *)prefix) != 0) { if (startswith(param, (char *)prefix) != 0) {
pr_info("become_manager: invalid param: %s\n", param); pr_info("become_manager: invalid param: %s\n", param);
return 0; goto block;
} }
// stat the param, app must have permission to do this // stat the param, app must have permission to do this
@@ -269,12 +270,13 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
struct path path; struct path path;
if (kern_path(param, LOOKUP_DIRECTORY, &path)) { if (kern_path(param, LOOKUP_DIRECTORY, &path)) {
pr_err("become_manager: kern_path err\n"); pr_err("become_manager: kern_path err\n");
return 0; goto block;
} }
if (path.dentry->d_inode->i_uid.val != current_uid().val) { uid_t inode_uid = path.dentry->d_inode->i_uid.val;
path_put(&path);
if (inode_uid != current_uid().val) {
pr_err("become_manager: path uid != current uid\n"); pr_err("become_manager: path uid != current uid\n");
path_put(&path); goto block;
return 0;
} }
char *pkg = param + strlen(prefix); char *pkg = param + strlen(prefix);
pr_info("become_manager: param pkg: %s\n", pkg); pr_info("become_manager: param pkg: %s\n", pkg);
@@ -284,8 +286,10 @@ int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) { if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
pr_err("become_manager: prctl reply error\n"); pr_err("become_manager: prctl reply error\n");
} }
return 0;
} }
path_put(&path); block:
last_failed_uid = current_uid().val;
return 0; return 0;
} }
@@ -569,11 +573,13 @@ int ksu_handle_setuid(struct cred *new, const struct cred *old)
// when we umount for such process, that is a disaster! // when we umount for such process, that is a disaster!
bool is_zygote_child = is_zygote(old->security); bool is_zygote_child = is_zygote(old->security);
if (!is_zygote_child) { if (!is_zygote_child) {
pr_info("handle umount ignore non zygote child: %d\n", current->pid); pr_info("handle umount ignore non zygote child: %d\n",
current->pid);
return 0; return 0;
} }
// umount the target mnt // umount the target mnt
pr_info("handle umount for uid: %d, pid: %d\n", new_uid.val, current->pid); pr_info("handle umount for uid: %d, pid: %d\n", new_uid.val,
current->pid);
// fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and // fixme: use `collect_mounts` and `iterate_mount` to iterate all mountpoint and
// filter the mountpoint whose target is `/data/adb` // filter the mountpoint whose target is `/data/adb`