Skip to content

Commit

Permalink
feat: android su compat done
Browse files Browse the repository at this point in the history
  • Loading branch information
bmax committed Sep 30, 2023
1 parent 30879f5 commit 46a8632
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 58 deletions.
12 changes: 9 additions & 3 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ ifndef TARGET_COMPILE
$(error TARGET_COMPILE is not set)
endif

TARGET=kpimg

CC = $(TARGET_COMPILE)gcc
LD = $(TARGET_COMPILE)ld
AS = $(TARGET_COMPILE)as
Expand Down Expand Up @@ -39,19 +41,23 @@ BASE_SRCS += $(wildcard init/ksyms/*.c)
BASE_SRCS += $(wildcard init/struct/*.c)
BASE_SRCS += $(wildcard init/debug/*.c)

ifdef ANDROID
BASE_SRCS += $(wildcard init/android/*.c)
endif

SRCS += $(BASE_SRCS)
SRCS += $(LINUX_SRCS)

OBJS := $(SRCS:.c=.o)
OBJS := $(OBJS:.S=.o)

all: kpimg hdr

kpimg: kpimg.elf
all: ${TARGET} hdr

${TARGET}: ${TARGET}.elf
${OBJCOPY} -O binary -S $^ $@

kpimg.elf: ${OBJS}
${TARGET}.elf: ${OBJS}
${LD} -nostdlib -static -no-pie -Tkpimg.lds -o $@ $^

%.o: %.c
Expand Down
42 changes: 11 additions & 31 deletions kernel/init/accctl/supercall.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,6 @@ static inline long call_su(const char *sctx)
return ret;
}

static long call_grant_su(uid_t uid)
{
return add_allow_uid(uid);
}

static long call_revoke_su(uid_t uid)
{
return remove_allow_uid(uid);
}

static long call_list_su_allow(uid_t *__user uids, size_t *__user size)
{
return list_allow_uids(uids, size);
}

static long call_thread_su(pid_t pid, const char *sctx)
{
int ret = SUPERCALL_RES_SUCCEED;
Expand All @@ -79,7 +64,8 @@ static long supercall(long cmd, void *__user arg1, void *__user arg2, void *__us
{
logkd("SuperCall with cmd: %x\n", cmd);

long ret = SUPERCALL_RES_SUCCEED;
long ret = SUPERCALL_RES_NOT_IMPL;

if (cmd == SUPERCALL_HELLO) {
ret = call_hello();
} else if (cmd == SUPERCALL_GET_KERNEL_VERSION) {
Expand All @@ -91,29 +77,23 @@ static long supercall(long cmd, void *__user arg1, void *__user arg2, void *__us
} else if (cmd == SUPERCALL_UNLOAD_KPM) {
ret = call_unload_kpm(0, 0);
} else if (cmd == SUPERCALL_SU) {
char sctx[SUPERCALL_SCONTEXT_LEN] = { '\0' };
long len = strncpy_from_user(sctx, (const char *)arg1, SUPERCALL_SCONTEXT_LEN - 1);
char sctx[SUPERCALL_SCONTEXT_LEN + 1];
sctx[SUPERCALL_SCONTEXT_LEN] = 0;
long len = strncpy_from_user(sctx, (const char *)arg1, SUPERCALL_SCONTEXT_LEN);
ret = call_su(len > 0 ? sctx : 0);
} else if (cmd == SUPERCALL_GRANT_SU) {
uid_t uid = (uid_t)(uintptr_t)arg1;
ret = call_grant_su(uid);
} else if (cmd == SUPERCALL_REVOKE_SU) {
uid_t uid = (uid_t)(uintptr_t)arg1;
ret = call_revoke_su(uid);
} else if (cmd == SUPERCALL_LIST_SU_ALLOW) {
uid_t *uids = (uid_t *)arg1;
size_t *size = (size_t *)arg2;
ret = call_list_su_allow(uids, size);
} else if (cmd == SUPERCALL_THREAD_SU) {
pid_t pid = (pid_t)(uintptr_t)arg1;
char sctx[SUPERCALL_SCONTEXT_LEN] = { '\0' };
long len = strncpy_from_user(sctx, (const char *)arg2, SUPERCALL_SCONTEXT_LEN - 1);
char sctx[SUPERCALL_SCONTEXT_LEN + 1];
sctx[SUPERCALL_SCONTEXT_LEN] = 0;
long len = strncpy_from_user(sctx, (const char *)arg2, SUPERCALL_SCONTEXT_LEN);
ret = call_thread_su(pid, len > 0 ? sctx : 0);
} else if (cmd == SUPERCALL_THREAD_UNSU) {
pid_t pid = (pid_t)(uintptr_t)arg1;
ret = call_thread_unsu(pid);
} else {
ret = SUPERCALL_RES_NOT_IMPL;
#ifdef ANDROID
ret = supercall_android(cmd, arg1, arg2, arg3);
#endif
}
return ret;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ static void *replace_do_execve(void *a0, void *a1, void *a2, void *a3, void *a4,
}
if (!IS_ERR(filename)) {
if (!min_strcmp(filename->name, android_su_path)) {
// todo: bugs printk
// todo: panic printk
// logkd("exec: uid: %d, filename: %s\n", uid, filename->name);
commit_su(0, 0);
min_strcpy((char *)filename->name, android_sh_path);
Expand All @@ -204,7 +204,7 @@ static long replace_faccessat(int dfd, char __user *filename, int mode, int flag
char buf[sizeof(android_su_path) + 1] = { '\0' };
strncpy_from_user(buf, filename, sizeof(android_su_path));
if (!min_strcmp(buf, android_su_path)) {
logkd("access: uid: %d, filename: %s\n", uid, buf);
// logkd("access: uid: %d, filename: %s\n", uid, buf);
copy_to_user(filename, android_sh_path, sizeof(android_sh_path));
change_flag = 1;
}
Expand All @@ -229,14 +229,14 @@ static void *replace_vfs_stat(int dfd, void *a1, void *a2, void *a3, void *a4, v
if ((((uintptr_t)a1) & 0xF000000000000000) == 0xF000000000000000) {
struct filename *filename = (struct filename *)a1;
if (!min_strcmp(filename->name, android_su_path)) {
logkd("stat: uid: %d, filename: %s\n", uid, filename);
// logkd("stat: uid: %d, filename: %s\n", uid, filename);
min_strcpy((char *)filename->name, android_sh_path);
}
} else {
char buf[sizeof(android_su_path) + 1] = { '\0' };
strncpy_from_user(buf, a1, sizeof(android_su_path));
if (!min_strcmp(buf, android_su_path)) {
logkd("stat: uid: %d, user filename: %s\n", uid, buf);
// logkd("stat: uid: %d, user filename: %s\n", uid, buf);
copy_to_user(a1, android_sh_path, sizeof(android_sh_path));
change_flag = 1;
}
Expand Down
45 changes: 45 additions & 0 deletions kernel/init/android/supercall.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <uapi/scdefs.h>
#include <hook.h>
#include <common.h>
#include <log.h>
#include <linux/uaccess.h>
#include <linux/cred.h>
#include <asm/current.h>
#include <linux/pid.h>
#include <linux/sched.h>
#include <linux/security.h>
#include <accctl.h>

static long call_grant_su(uid_t uid)
{
return add_allow_uid(uid);
}

static long call_revoke_su(uid_t uid)
{
return remove_allow_uid(uid);
}

static long call_list_su_allow(uid_t *__user uids, size_t *__user size)
{
return list_allow_uids(uids, size);
}

long supercall_android(long cmd, void *__user arg1, void *__user arg2, void *__user arg3)
{
long ret;
if (cmd == SUPERCALL_GRANT_SU) {
uid_t uid = (uid_t)(uintptr_t)arg1;
ret = call_grant_su(uid);
} else if (cmd == SUPERCALL_REVOKE_SU) {
uid_t uid = (uid_t)(uintptr_t)arg1;
ret = call_revoke_su(uid);
} else if (cmd == SUPERCALL_LIST_SU_ALLOW) {
uid_t *uids = (uid_t *)arg1;
size_t *size = (size_t *)arg2;
ret = call_list_su_allow(uids, size);
} else {
ret = SUPERCALL_RES_NOT_IMPL;
}
return ret;
}
4 changes: 4 additions & 0 deletions kernel/init/include/accctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ int su_compat_init();
int selinux_hook_install();
int supercall_install();

#ifdef ANDROID
long supercall_android(long cmd, void *__user arg1, void *__user arg2, void *__user arg3);
#endif

#endif
13 changes: 8 additions & 5 deletions kernel/init/include/uapi/scdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ static inline long hash_key(const char *key)
#define SUPERCALL_LOAD_KPM 0x1003
#define SUPERCALL_UNLOAD_KPM 0x1004
#define SUPERCALL_SU 0x1005
#define SUPERCALL_GRANT_SU 0x1006
#define SUPERCALL_REVOKE_SU 0x1007
#define SUPERCALL_LIST_SU_ALLOW 0x1008
#define SUPERCALL_THREAD_SU 0x1009
#define SUPERCALL_THREAD_UNSU 0x100a
#define SUPERCALL_THREAD_SU 0x1006
#define SUPERCALL_THREAD_UNSU 0x1007

#ifdef ANDROID
#define SUPERCALL_GRANT_SU 0x1020
#define SUPERCALL_REVOKE_SU 0x1021
#define SUPERCALL_LIST_SU_ALLOW 0x1022
#endif

#define SUPERCALL_MAX 0x1100

Expand Down
5 changes: 2 additions & 3 deletions kernel/init/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,16 @@ int linux_symbol_init()
static inline void do_init()
{
logki("==== KernelPatch Do Init ====\n");

linux_symbol_init();
linux_sybmol_len_init();

syscall_init();
build_struct();
task_observer();
selinux_hook_install();
supercall_install();
#ifdef ANDROID
su_compat_init();

#endif
logki("==== KernelPatch Everything Done ====\n");
}

Expand Down
15 changes: 3 additions & 12 deletions user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,6 @@ int main(int argc, char **argv)
continue;
}
}
#if 1
uint64_t stack_pointer;
__asm__ volatile("mov %0, sp" : "=r"(stack_pointer));
fprintf(stdout, "Stack Pointer (SP): %p\n", stack_pointer);
uid_t ruid, euid, suid;
gid_t rgid, egid, sgid;
getresuid(&ruid, &euid, &suid);
getresgid(&rgid, &egid, &sgid);
fprintf(stdout, "resuid: %ud, %ud, %ud, resgid: %ud, %ud, %ud\n", ruid, euid, suid, rgid, egid, sgid);
fprintf(stdout, "command no: %x, arg1: %s, arg2: %s, arg3:%s\n", cmd, arg1, arg2, arg3);
#endif
long ret = 0;
if (cmd == SUPERCALL_HELLO) {
ret = sc_hello(key);
Expand Down Expand Up @@ -156,9 +145,11 @@ int main(int argc, char **argv)
ret = sc_list_su_allow(key, uids, &size);
if (ret)
return ret;
fprintf(stdout, "su allow nums: %d\n", (int)size);
for (int i = 0; i < size; i++) {
fprintf(stdout, "su allow uid: %d\n", uids[i]);
fprintf(stdout, "%d\t", uids[i]);
}
fprintf(stdout, "\n");
} else if (cmd == SUPERCALL_THREAD_SU) {
if (!arg1) {
fprintf(stderr, "Empty tid!\n");
Expand Down

0 comments on commit 46a8632

Please sign in to comment.