kernel: remove become_manager and minor refactors
This commit is contained in:
@@ -2,8 +2,7 @@ kernelsu-objs := ksu.o
|
|||||||
kernelsu-objs += allowlist.o
|
kernelsu-objs += allowlist.o
|
||||||
kernelsu-objs += apk_sign.o
|
kernelsu-objs += apk_sign.o
|
||||||
kernelsu-objs += sucompat.o
|
kernelsu-objs += sucompat.o
|
||||||
kernelsu-objs += uid_observer.o
|
kernelsu-objs += throne_tracker.o
|
||||||
kernelsu-objs += manager.o
|
|
||||||
kernelsu-objs += core_hook.o
|
kernelsu-objs += core_hook.o
|
||||||
kernelsu-objs += ksud.o
|
kernelsu-objs += ksud.o
|
||||||
kernelsu-objs += embed_ksud.o
|
kernelsu-objs += embed_ksud.o
|
||||||
|
|||||||
@@ -37,7 +37,8 @@
|
|||||||
#include "linux/vmalloc.h"
|
#include "linux/vmalloc.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "selinux/selinux.h"
|
#include "selinux/selinux.h"
|
||||||
#include "uid_observer.h"
|
#include "throne_tracker.h"
|
||||||
|
#include "throne_tracker.h"
|
||||||
#include "kernel_compat.h"
|
#include "kernel_compat.h"
|
||||||
|
|
||||||
static bool ksu_module_mounted = false;
|
static bool ksu_module_mounted = false;
|
||||||
@@ -199,7 +200,7 @@ int ksu_handle_rename(struct dentry *old_dentry, struct dentry *new_dentry)
|
|||||||
pr_info("renameat: %s -> %s, new path: %s\n", old_dentry->d_iname,
|
pr_info("renameat: %s -> %s, new path: %s\n", old_dentry->d_iname,
|
||||||
new_dentry->d_iname, buf);
|
new_dentry->d_iname, buf);
|
||||||
|
|
||||||
update_uid();
|
track_throne();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "core_hook.h"
|
#include "core_hook.h"
|
||||||
#include "klog.h" // IWYU pragma: keep
|
#include "klog.h" // IWYU pragma: keep
|
||||||
#include "ksu.h"
|
#include "ksu.h"
|
||||||
#include "uid_observer.h"
|
#include "throne_tracker.h"
|
||||||
|
|
||||||
static struct workqueue_struct *ksu_workqueue;
|
static struct workqueue_struct *ksu_workqueue;
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ int __init kernelsu_init(void)
|
|||||||
|
|
||||||
ksu_allowlist_init();
|
ksu_allowlist_init();
|
||||||
|
|
||||||
ksu_uid_observer_init();
|
ksu_throne_tracker_init();
|
||||||
|
|
||||||
#ifdef CONFIG_KPROBES
|
#ifdef CONFIG_KPROBES
|
||||||
ksu_enable_sucompat();
|
ksu_enable_sucompat();
|
||||||
@@ -74,7 +74,7 @@ void kernelsu_exit(void)
|
|||||||
{
|
{
|
||||||
ksu_allowlist_exit();
|
ksu_allowlist_exit();
|
||||||
|
|
||||||
ksu_uid_observer_exit();
|
ksu_throne_tracker_exit();
|
||||||
|
|
||||||
destroy_workqueue(ksu_workqueue);
|
destroy_workqueue(ksu_workqueue);
|
||||||
|
|
||||||
|
|||||||
102
kernel/manager.c
102
kernel/manager.c
@@ -1,102 +0,0 @@
|
|||||||
#include "linux/cred.h"
|
|
||||||
#include "linux/gfp.h"
|
|
||||||
#include "linux/slab.h"
|
|
||||||
#include "linux/uidgid.h"
|
|
||||||
#include "linux/version.h"
|
|
||||||
|
|
||||||
#include "linux/fdtable.h"
|
|
||||||
#include "linux/fs.h"
|
|
||||||
#include "linux/rcupdate.h"
|
|
||||||
|
|
||||||
#include "apk_sign.h"
|
|
||||||
#include "klog.h" // IWYU pragma: keep
|
|
||||||
#include "ksu.h"
|
|
||||||
#include "manager.h"
|
|
||||||
|
|
||||||
uid_t ksu_manager_uid = KSU_INVALID_UID;
|
|
||||||
|
|
||||||
bool become_manager(char *pkg)
|
|
||||||
{
|
|
||||||
struct fdtable *files_table;
|
|
||||||
int i = 0;
|
|
||||||
struct path files_path;
|
|
||||||
char *cwd;
|
|
||||||
char *buf;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
#ifdef KSU_MANAGER_PACKAGE
|
|
||||||
// pkg is `/<real package>`
|
|
||||||
if (strncmp(pkg + 1, KSU_MANAGER_PACKAGE,
|
|
||||||
sizeof(KSU_MANAGER_PACKAGE)) != 0) {
|
|
||||||
pr_info("manager package is inconsistent with kernel build: %s\n",
|
|
||||||
KSU_MANAGER_PACKAGE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// must be zygote's direct child, otherwise any app can fork a new process and
|
|
||||||
// open manager's apk
|
|
||||||
if (task_uid(current->real_parent).val != 0) {
|
|
||||||
pr_info("parent is not zygote!\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = (char *)kmalloc(PATH_MAX, GFP_ATOMIC);
|
|
||||||
if (!buf) {
|
|
||||||
pr_err("kalloc path failed.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
files_table = files_fdtable(current->files);
|
|
||||||
|
|
||||||
int pkg_len = strlen(pkg);
|
|
||||||
// todo: use iterate_fd
|
|
||||||
for (i = 0; files_table->fd[i] != NULL; i++) {
|
|
||||||
files_path = files_table->fd[i]->f_path;
|
|
||||||
if (!d_is_reg(files_path.dentry)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cwd = d_path(&files_path, buf, PATH_MAX);
|
|
||||||
if (startswith(cwd, "/data/app/") != 0 ||
|
|
||||||
endswith(cwd, "==/base.apk") != 0) {
|
|
||||||
// AOSP generate ramdom base64 with 16bit, without NO_PADDING, so it must have two "="
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// we have found the apk!
|
|
||||||
pr_info("found apk: %s\n", cwd);
|
|
||||||
char *pkg_index = strstr(cwd, pkg);
|
|
||||||
if (!pkg_index) {
|
|
||||||
pr_info("apk path not match package name!\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
char *next_char = pkg_index + pkg_len;
|
|
||||||
// because we ensure the cwd must startswith `/data/app` and endswith `base.apk`
|
|
||||||
// we don't need to check if the pointer is out of bounds
|
|
||||||
if (*next_char != '-') {
|
|
||||||
// from android 8.1: http://aospxref.com/android-8.1.0_r81/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java#17612
|
|
||||||
// to android 13: http://aospxref.com/android-13.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java#1208
|
|
||||||
// /data/app/~~[randomStringA]/[packageName]-[randomStringB]
|
|
||||||
// the previous char must be `/` and the next char must be `-`
|
|
||||||
// because we use strstr instead of equals, this is a strong verfication.
|
|
||||||
pr_info("invalid pkg: %s\n", pkg);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (is_manager_apk(cwd)) {
|
|
||||||
// check passed
|
|
||||||
uid_t uid = current_uid().val;
|
|
||||||
pr_info("manager uid: %d\n", uid);
|
|
||||||
|
|
||||||
ksu_set_manager_uid(uid);
|
|
||||||
|
|
||||||
result = true;
|
|
||||||
goto clean;
|
|
||||||
} else {
|
|
||||||
pr_info("manager signature invalid!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
clean:
|
|
||||||
kfree(buf);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
@@ -33,6 +33,4 @@ static inline void ksu_invalidate_manager_uid()
|
|||||||
ksu_manager_uid = KSU_INVALID_UID;
|
ksu_manager_uid = KSU_INVALID_UID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool become_manager(char *pkg);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11,9 +11,11 @@
|
|||||||
#include "klog.h" // IWYU pragma: keep
|
#include "klog.h" // IWYU pragma: keep
|
||||||
#include "ksu.h"
|
#include "ksu.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "uid_observer.h"
|
#include "throne_tracker.h"
|
||||||
#include "kernel_compat.h"
|
#include "kernel_compat.h"
|
||||||
|
|
||||||
|
uid_t ksu_manager_uid = KSU_INVALID_UID;
|
||||||
|
|
||||||
#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list"
|
#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list"
|
||||||
static struct work_struct ksu_update_uid_work;
|
static struct work_struct ksu_update_uid_work;
|
||||||
|
|
||||||
@@ -71,6 +73,14 @@ static void crown_manager(const char *apk, struct list_head *uid_data)
|
|||||||
|
|
||||||
pr_info("manager pkg: %s\n", pkg);
|
pr_info("manager pkg: %s\n", pkg);
|
||||||
|
|
||||||
|
#ifdef KSU_MANAGER_PACKAGE
|
||||||
|
// pkg is `/<real package>`
|
||||||
|
if (strncmp(pkg, KSU_MANAGER_PACKAGE, sizeof(KSU_MANAGER_PACKAGE))) {
|
||||||
|
pr_info("manager package is inconsistent with kernel build: %s\n",
|
||||||
|
KSU_MANAGER_PACKAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
struct list_head *list = (struct list_head *)uid_data;
|
struct list_head *list = (struct list_head *)uid_data;
|
||||||
struct uid_data *np;
|
struct uid_data *np;
|
||||||
|
|
||||||
@@ -292,18 +302,18 @@ out:
|
|||||||
filp_close(fp, 0);
|
filp_close(fp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_uid()
|
void track_throne()
|
||||||
{
|
{
|
||||||
ksu_queue_work(&ksu_update_uid_work);
|
ksu_queue_work(&ksu_update_uid_work);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksu_uid_observer_init()
|
int ksu_throne_tracker_init()
|
||||||
{
|
{
|
||||||
INIT_WORK(&ksu_update_uid_work, do_update_uid);
|
INIT_WORK(&ksu_update_uid_work, do_update_uid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ksu_uid_observer_exit()
|
int ksu_throne_tracker_exit()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
10
kernel/throne_tracker.h
Normal file
10
kernel/throne_tracker.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef __KSU_H_UID_OBSERVER
|
||||||
|
#define __KSU_H_UID_OBSERVER
|
||||||
|
|
||||||
|
int ksu_throne_tracker_init();
|
||||||
|
|
||||||
|
int ksu_throne_tracker_exit();
|
||||||
|
|
||||||
|
void track_throne();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#ifndef __KSU_H_UID_OBSERVER
|
|
||||||
#define __KSU_H_UID_OBSERVER
|
|
||||||
|
|
||||||
int ksu_uid_observer_init();
|
|
||||||
|
|
||||||
int ksu_uid_observer_exit();
|
|
||||||
|
|
||||||
void update_uid();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user