misc: code format(use kernel code stype: https://www.kernel.org/doc/html/v6.1/process/coding-style.html
This commit is contained in:
114
kernel/ksu.c
114
kernel/ksu.c
@@ -14,7 +14,7 @@
|
||||
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/fdtable.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fs_struct.h>
|
||||
#include <linux/namei.h>
|
||||
|
||||
@@ -39,8 +39,9 @@
|
||||
#define CMD_GET_ALLOW_LIST 5
|
||||
#define CMD_GET_DENY_LIST 6
|
||||
|
||||
void escape_to_root() {
|
||||
struct cred* cred;
|
||||
void escape_to_root()
|
||||
{
|
||||
struct cred *cred;
|
||||
|
||||
cred = (struct cred *)__task_cred(current);
|
||||
|
||||
@@ -69,30 +70,34 @@ void escape_to_root() {
|
||||
setup_selinux();
|
||||
}
|
||||
|
||||
int startswith(char* s, char* prefix) {
|
||||
int startswith(char *s, char *prefix)
|
||||
{
|
||||
return strncmp(s, prefix, strlen(prefix));
|
||||
}
|
||||
|
||||
int endswith(const char *s, const char *t)
|
||||
{
|
||||
size_t slen = strlen(s);
|
||||
size_t tlen = strlen(t);
|
||||
if (tlen > slen) return 1;
|
||||
return strcmp(s + slen - tlen, t);
|
||||
size_t slen = strlen(s);
|
||||
size_t tlen = strlen(t);
|
||||
if (tlen > slen)
|
||||
return 1;
|
||||
return strcmp(s + slen - tlen, t);
|
||||
}
|
||||
|
||||
static uid_t __manager_uid;
|
||||
|
||||
static bool is_manager() {
|
||||
static bool is_manager()
|
||||
{
|
||||
return __manager_uid == current_uid().val;
|
||||
}
|
||||
|
||||
static bool become_manager(char* pkg) {
|
||||
struct fdtable *files_table;
|
||||
int i = 0;
|
||||
struct path files_path;
|
||||
static bool become_manager(char *pkg)
|
||||
{
|
||||
struct fdtable *files_table;
|
||||
int i = 0;
|
||||
struct path files_path;
|
||||
char *cwd;
|
||||
char *buf;
|
||||
char *buf;
|
||||
bool result = false;
|
||||
|
||||
// must be zygote's direct child, otherwise any app can fork a new process and open manager's apk
|
||||
@@ -106,23 +111,24 @@ static bool become_manager(char* pkg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
buf = (char *) kmalloc(PATH_MAX, GFP_ATOMIC);
|
||||
buf = (char *)kmalloc(PATH_MAX, GFP_ATOMIC);
|
||||
if (!buf) {
|
||||
pr_err("kalloc path failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
files_table = files_fdtable(current->files);
|
||||
files_table = files_fdtable(current->files);
|
||||
|
||||
// todo: use iterate_fd
|
||||
while(files_table->fd[i] != NULL) {
|
||||
files_path = files_table->fd[i]->f_path;
|
||||
while (files_table->fd[i] != NULL) {
|
||||
files_path = files_table->fd[i]->f_path;
|
||||
if (!d_is_reg(files_path.dentry)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
cwd = d_path(&files_path, buf, PATH_MAX);
|
||||
if (startswith(cwd, "/data/app/") == 0 && endswith(cwd, "/base.apk") == 0) {
|
||||
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)) {
|
||||
@@ -145,15 +151,16 @@ static bool become_manager(char* pkg) {
|
||||
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
clean:
|
||||
kfree(buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool is_allow_su() {
|
||||
static bool is_allow_su()
|
||||
{
|
||||
uid_t uid = current_uid().val;
|
||||
if (uid == __manager_uid) {
|
||||
// we are manager, allow!
|
||||
@@ -165,20 +172,20 @@ static bool is_allow_su() {
|
||||
|
||||
extern void enable_sucompat();
|
||||
|
||||
static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
|
||||
|
||||
struct pt_regs* real_regs = (struct pt_regs*) PT_REGS_PARM1(regs);
|
||||
int option = (int) PT_REGS_PARM1(real_regs);
|
||||
unsigned long arg2 = (unsigned long) PT_REGS_PARM2(real_regs);
|
||||
unsigned long arg3 = (unsigned long) PT_REGS_PARM3(real_regs);
|
||||
unsigned long arg4 = (unsigned long) PT_REGS_PARM4(real_regs);
|
||||
unsigned long arg5 = (unsigned long) PT_REGS_PARM5(real_regs);
|
||||
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *real_regs = (struct pt_regs *)PT_REGS_PARM1(regs);
|
||||
int option = (int)PT_REGS_PARM1(real_regs);
|
||||
unsigned long arg2 = (unsigned long)PT_REGS_PARM2(real_regs);
|
||||
unsigned long arg3 = (unsigned long)PT_REGS_PARM3(real_regs);
|
||||
unsigned long arg4 = (unsigned long)PT_REGS_PARM4(real_regs);
|
||||
unsigned long arg5 = (unsigned long)PT_REGS_PARM5(real_regs);
|
||||
|
||||
// if success, we modify the arg5 as result!
|
||||
u32* result = (u32*) arg5;
|
||||
u32 *result = (u32 *)arg5;
|
||||
u32 reply_ok = KERNEL_SU_OPTION;
|
||||
|
||||
if (KERNEL_SU_OPTION != option) {
|
||||
if (KERNEL_SU_OPTION != option) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -188,13 +195,13 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
|
||||
// someone wants to be root manager, just check it!
|
||||
// arg3 should be `/data/data/<manager_package_name>`
|
||||
char param[128];
|
||||
const char* prefix = "/data/data/";
|
||||
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) {
|
||||
if (startswith(param, (char *)prefix) != 0) {
|
||||
pr_info("become_manager: invalid param: %s\n", param);
|
||||
return 0;
|
||||
}
|
||||
@@ -211,7 +218,7 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
|
||||
path_put(&path);
|
||||
return 0;
|
||||
}
|
||||
char* pkg = param + strlen(prefix);
|
||||
char *pkg = param + strlen(prefix);
|
||||
pr_info("become_manager: param pkg: %s\n", pkg);
|
||||
|
||||
bool success = become_manager(pkg);
|
||||
@@ -246,22 +253,27 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
|
||||
if (arg2 == CMD_ALLOW_SU || arg2 == CMD_DENY_SU) {
|
||||
bool allow = arg2 == CMD_ALLOW_SU;
|
||||
bool success = false;
|
||||
uid_t uid = (uid_t) arg3;
|
||||
uid_t uid = (uid_t)arg3;
|
||||
success = ksu_allow_uid(uid, allow);
|
||||
if (success) {
|
||||
if (copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
|
||||
pr_err("prctl reply error, cmd: %d\n", arg2);
|
||||
}
|
||||
}
|
||||
} else if (arg2 == CMD_GET_ALLOW_LIST || arg2 == CMD_GET_DENY_LIST) {
|
||||
} else if (arg2 == CMD_GET_ALLOW_LIST || arg2 == CMD_GET_DENY_LIST) {
|
||||
u32 array[128];
|
||||
u32 array_length;
|
||||
bool success = ksu_get_allow_list(array, &array_length, arg2 == CMD_GET_ALLOW_LIST);
|
||||
bool success = ksu_get_allow_list(array, &array_length,
|
||||
arg2 == CMD_GET_ALLOW_LIST);
|
||||
if (success) {
|
||||
if (!copy_to_user(arg4, &array_length, sizeof(array_length)) &&
|
||||
!copy_to_user(arg3, array, sizeof(u32) * array_length)) {
|
||||
if (!copy_to_user(result, &reply_ok, sizeof(reply_ok))) {
|
||||
pr_err("prctl reply error, cmd: %d\n", arg2);
|
||||
if (!copy_to_user(arg4, &array_length,
|
||||
sizeof(array_length)) &&
|
||||
!copy_to_user(arg3, array,
|
||||
sizeof(u32) * array_length)) {
|
||||
if (!copy_to_user(result, &reply_ok,
|
||||
sizeof(reply_ok))) {
|
||||
pr_err("prctl reply error, cmd: %d\n",
|
||||
arg2);
|
||||
}
|
||||
} else {
|
||||
pr_err("prctl copy allowlist error\n");
|
||||
@@ -274,22 +286,24 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) {
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct kprobe kp = {
|
||||
.symbol_name = PRCTL_SYMBOL,
|
||||
.pre_handler = handler_pre,
|
||||
.symbol_name = PRCTL_SYMBOL,
|
||||
.pre_handler = handler_pre,
|
||||
};
|
||||
|
||||
int kernelsu_init(void){
|
||||
int kernelsu_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
ksu_allowlist_init();
|
||||
|
||||
rc = register_kprobe(&kp);
|
||||
if (rc) {
|
||||
pr_info("prctl kprobe failed: %d, please check your kernel config.\n", rc);
|
||||
pr_info("prctl kprobe failed: %d, please check your kernel config.\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -298,7 +312,8 @@ int kernelsu_init(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kernelsu_exit(void){
|
||||
void kernelsu_exit(void)
|
||||
{
|
||||
// should never happen...
|
||||
unregister_kprobe(&kp);
|
||||
|
||||
@@ -315,4 +330,5 @@ module_exit(kernelsu_exit);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("weishu");
|
||||
MODULE_DESCRIPTION("Android GKI KernelSU");
|
||||
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+才需要导出命名空间
|
||||
|
||||
Reference in New Issue
Block a user