kernel: don't use 0(root uid) as manager init uid
This commit is contained in:
@@ -233,7 +233,7 @@ exit:
|
||||
filp_close(fp, 0);
|
||||
}
|
||||
|
||||
void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void* data)
|
||||
void ksu_prune_allowlist(bool (*is_uid_exist)(uid_t, void *), void *data)
|
||||
{
|
||||
struct perm_data *np = NULL;
|
||||
struct perm_data *n = NULL;
|
||||
|
||||
63
kernel/ksu.c
63
kernel/ksu.c
@@ -1,50 +1,38 @@
|
||||
#include <asm-generic/errno-base.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/uidgid.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm-generic/errno-base.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/uidgid.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/fdtable.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fs_struct.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
#include <linux/delay.h> // mslepp
|
||||
#include <linux/delay.h> // msleep
|
||||
|
||||
#include "selinux/selinux.h"
|
||||
#include "klog.h"
|
||||
#include "apk_sign.h"
|
||||
#include "allowlist.h"
|
||||
#include "apk_sign.h"
|
||||
#include "arch.h"
|
||||
#include "klog.h"
|
||||
#include "ksu.h"
|
||||
#include "selinux/selinux.h"
|
||||
#include "uid_observer.h"
|
||||
|
||||
#define KERNEL_SU_VERSION 9
|
||||
|
||||
#define KERNEL_SU_OPTION 0xDEADBEEF
|
||||
|
||||
#define CMD_GRANT_ROOT 0
|
||||
|
||||
#define CMD_BECOME_MANAGER 1
|
||||
#define CMD_GET_VERSION 2
|
||||
#define CMD_ALLOW_SU 3
|
||||
#define CMD_DENY_SU 4
|
||||
#define CMD_GET_ALLOW_LIST 5
|
||||
#define CMD_GET_DENY_LIST 6
|
||||
|
||||
static struct group_info root_groups = { .usage = ATOMIC_INIT(2) };
|
||||
|
||||
uid_t ksu_manager_uid;
|
||||
uid_t ksu_manager_uid = INVALID_UID;
|
||||
|
||||
void escape_to_root()
|
||||
{
|
||||
@@ -66,7 +54,8 @@ void escape_to_root()
|
||||
memset(&cred->cap_ambient, 0xff, sizeof(cred->cap_ambient));
|
||||
|
||||
// disable seccomp
|
||||
#if defined(CONFIG_GENERIC_ENTRY) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
|
||||
#if defined(CONFIG_GENERIC_ENTRY) && \
|
||||
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
|
||||
current_thread_info()->syscall_work &= ~SYSCALL_WORK_SECCOMP;
|
||||
#else
|
||||
current_thread_info()->flags &= ~(TIF_SECCOMP | _TIF_SECCOMP);
|
||||
@@ -94,7 +83,6 @@ int endswith(const char *s, const char *t)
|
||||
return strcmp(s + slen - tlen, t);
|
||||
}
|
||||
|
||||
|
||||
static bool is_manager()
|
||||
{
|
||||
return ksu_manager_uid == current_uid().val;
|
||||
@@ -109,13 +97,14 @@ static bool become_manager(char *pkg)
|
||||
char *buf;
|
||||
bool result = false;
|
||||
|
||||
// must be zygote's direct child, otherwise any app can fork a new process and open manager's apk
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (ksu_manager_uid != 0) {
|
||||
if (ksu_is_manager_uid_valid()) {
|
||||
pr_info("manager already exist: %d\n", ksu_manager_uid);
|
||||
return is_manager();
|
||||
}
|
||||
@@ -150,7 +139,7 @@ static bool become_manager(char *pkg)
|
||||
uid_t uid = current_uid().val;
|
||||
pr_info("manager uid: %d\n", uid);
|
||||
|
||||
ksu_manager_uid = uid;
|
||||
ksu_set_manager_uid(uid);
|
||||
|
||||
result = true;
|
||||
goto clean;
|
||||
@@ -259,12 +248,11 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Both root manager and root processes should be allowed to get version
|
||||
if (arg2 == CMD_GET_VERSION) {
|
||||
if (is_manager() || 0 == current_uid().val) {
|
||||
u32 version = KERNEL_SU_VERSION;
|
||||
if (copy_to_user(arg3, & version, sizeof(version))) {
|
||||
if (copy_to_user(arg3, &version, sizeof(version))) {
|
||||
pr_err("prctl reply error, cmd: %d\n", arg2);
|
||||
return 0;
|
||||
}
|
||||
@@ -361,5 +349,6 @@ MODULE_AUTHOR("weishu");
|
||||
MODULE_DESCRIPTION("Android GKI KernelSU");
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
|
||||
MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); // 5+才需要导出命名空间
|
||||
MODULE_IMPORT_NS(
|
||||
VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver); // 5+才需要导出命名空间
|
||||
#endif
|
||||
|
||||
38
kernel/ksu.h
Normal file
38
kernel/ksu.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef __KSU_H_KSU
|
||||
#define __KSU_H_KSU
|
||||
|
||||
#include "linux/uidgid.h"
|
||||
#define KERNEL_SU_VERSION 9
|
||||
|
||||
#define KERNEL_SU_OPTION 0xDEADBEEF
|
||||
|
||||
#define CMD_GRANT_ROOT 0
|
||||
|
||||
#define CMD_BECOME_MANAGER 1
|
||||
#define CMD_GET_VERSION 2
|
||||
#define CMD_ALLOW_SU 3
|
||||
#define CMD_DENY_SU 4
|
||||
#define CMD_GET_ALLOW_LIST 5
|
||||
#define CMD_GET_DENY_LIST 6
|
||||
|
||||
#define INVALID_UID -1
|
||||
|
||||
extern uid_t ksu_manager_uid;
|
||||
|
||||
static inline bool ksu_is_manager_uid_valid() {
|
||||
return ksu_manager_uid != INVALID_UID;
|
||||
}
|
||||
|
||||
static inline uid_t ksu_get_manager_uid() {
|
||||
return ksu_manager_uid;
|
||||
}
|
||||
|
||||
static inline void ksu_set_manager_uid(uid_t uid) {
|
||||
ksu_manager_uid = uid;
|
||||
}
|
||||
|
||||
static inline void ksu_invalidate_manager_uid() {
|
||||
ksu_manager_uid = INVALID_UID;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -15,12 +15,11 @@
|
||||
#include "allowlist.h"
|
||||
#include "arch.h"
|
||||
#include "klog.h"
|
||||
#include "ksu.h"
|
||||
|
||||
#define SYSTEM_PACKAGES_LIST_PATH "/data/system/packages.list"
|
||||
static struct work_struct ksu_update_uid_work;
|
||||
|
||||
extern uid_t ksu_manager_uid;
|
||||
|
||||
struct uid_data {
|
||||
struct list_head list;
|
||||
u32 uid;
|
||||
@@ -100,15 +99,15 @@ static void do_update_uid(struct work_struct *work)
|
||||
// first, check if manager_uid exist!
|
||||
bool manager_exist = false;
|
||||
list_for_each_entry (np, &uid_list, list) {
|
||||
if (np->uid == ksu_manager_uid) {
|
||||
if (np->uid == ksu_get_manager_uid()) {
|
||||
manager_exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!manager_exist) {
|
||||
pr_info("manager is uninstalled, reset it!\n");
|
||||
ksu_manager_uid = 0;
|
||||
if (!manager_exist && ksu_is_manager_uid_valid()) {
|
||||
pr_info("manager is uninstalled, invalidate it!\n");
|
||||
ksu_invalidate_manager_uid();
|
||||
}
|
||||
|
||||
// then prune the allowlist
|
||||
|
||||
Reference in New Issue
Block a user