diff --git a/kernel/Makefile b/kernel/Makefile index f88f1164..7bb39b1c 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -51,8 +51,7 @@ SRCS += $(LINUX_SRCS) OBJS := $(SRCS:.c=.o) OBJS := $(OBJS:.S=.o) - -all: ${TARGET} hdr +all: ${TARGET} ${TARGET}: ${TARGET}.elf ${OBJCOPY} -O binary -S $^ $@ @@ -66,10 +65,6 @@ ${TARGET}.elf: ${OBJS} %.o: %.S ${CC} $(CFLAGS) $(INCLUDE) -c -o $@ $< -hdr: - cp base/preset.h ../tools/ - cp -rf init/include/uapi ../user/ - .PHONY: clean clean: rm -rf *.elf diff --git a/kernel/init/android/sucompat.c b/kernel/init/android/sucompat.c index 8af0b09a..bc5ca3ef 100644 --- a/kernel/init/android/sucompat.c +++ b/kernel/init/android/sucompat.c @@ -24,15 +24,14 @@ #define INVALID_ALLOW_UID ((uid_t)-1) // sizeof android_su_path must not bigger than sizeof android_sh_path -// static const char android_su_path[] = "/system/bin/sc"; -static const char android_su_path[] = "/system/bin/su"; +static char android_su_path[] = "/system/bin/kp"; static const char android_sh_path[] = "/system/bin/sh"; static uid_t su_allow_list[32]; static int is_su_allow(uid_t uid) { - for (int i = 0; i < SUPERCALL_SU_ALLOW_MAX; i++) { + for (int i = 0; i < SUPERCALL_SU_ALLOW_UID_MAX; i++) { if (su_allow_list[i] == uid) return 1; } @@ -41,7 +40,7 @@ static int is_su_allow(uid_t uid) int add_allow_uid(uid_t uid) { - for (int i = 0; i < SUPERCALL_SU_ALLOW_MAX; i++) { + for (int i = 0; i < SUPERCALL_SU_ALLOW_UID_MAX; i++) { if (su_allow_list[i] == INVALID_ALLOW_UID || su_allow_list[i] == uid) { su_allow_list[i] = uid; return 0; @@ -52,22 +51,30 @@ int add_allow_uid(uid_t uid) int remove_allow_uid(uid_t uid) { - for (int i = 0; i < SUPERCALL_SU_ALLOW_MAX; i++) { + for (int i = 0; i < SUPERCALL_SU_ALLOW_UID_MAX; i++) { if (su_allow_list[i] == uid) { su_allow_list[i] = INVALID_ALLOW_UID; } } - return ERR_NO_SUCH_ID; + return ERR_NO_ERR; +} + +int reset_su_path(const char *path) +{ + if (min_strnlen(path, sizeof(android_sh_path)) >= sizeof(android_sh_path)) { + return ERR_CAP_FULL; + } + min_strncpy(android_su_path, path, SUPERCALL_SU_PATH_LEN); + return 0; } -// todo: PAGE_SIZE static int list_allow_uids_compat(uid_t __user *uids, size_t __user *size) { // uids struct trace_seq trace_seq; trace_seq_init(&trace_seq); size_t num = 0; - for (int i = 0; i < SUPERCALL_SU_ALLOW_MAX; i++) { + for (int i = 0; i < SUPERCALL_SU_ALLOW_UID_MAX; i++) { uid_t uid = su_allow_list[i]; if (uid != INVALID_ALLOW_UID) { trace_seq_putmem(&trace_seq, &uid, sizeof(uid_t)); @@ -90,11 +97,11 @@ int list_allow_uids(uid_t __user *uids, size_t __user *size) // uids struct seq_buf seq_buf; seq_buf_clear(&seq_buf); - char buffer[SUPERCALL_SU_ALLOW_MAX * sizeof(uid_t)]; + char buffer[SUPERCALL_SU_ALLOW_UID_MAX * sizeof(uid_t)]; seq_buf.buffer = buffer; seq_buf.size = sizeof(seq_buf); size_t num = 0; - for (int i = 0; i < SUPERCALL_SU_ALLOW_MAX; i++) { + for (int i = 0; i < SUPERCALL_SU_ALLOW_UID_MAX; i++) { uid_t uid = su_allow_list[i]; if (uid != INVALID_ALLOW_UID) { ((uid_t *)buffer)[num++] = uid; @@ -265,7 +272,7 @@ static int hook_execv_compat(void *data, const char *name, struct module *, unsi int su_compat_init() { - for (int i = 0; i < SUPERCALL_SU_ALLOW_MAX; i++) { + for (int i = 0; i < SUPERCALL_SU_ALLOW_UID_MAX; i++) { su_allow_list[i] = INVALID_ALLOW_UID; } hook_err_t err = HOOK_NO_ERR; diff --git a/kernel/init/android/supercall.c b/kernel/init/android/supercall.c index 8f76211d..54547cf6 100644 --- a/kernel/init/android/supercall.c +++ b/kernel/init/android/supercall.c @@ -9,6 +9,7 @@ #include #include #include +#include static long call_grant_su(uid_t uid) { @@ -25,6 +26,11 @@ static long call_list_su_allow(uid_t *__user uids, size_t *__user size) return list_allow_uids(uids, size); } +static long call_reset_su_path(const char *path) +{ + return reset_su_path(path); +} + long supercall_android(long cmd, void *__user arg1, void *__user arg2, void *__user arg3) { long ret; @@ -38,6 +44,10 @@ long supercall_android(long cmd, void *__user arg1, void *__user arg2, void *__u uid_t *uids = (uid_t *)arg1; size_t *size = (size_t *)arg2; ret = call_list_su_allow(uids, size); + } else if (cmd == SUPERCALL_RESET_SU_PATH) { + char path[SUPERCALL_SU_PATH_LEN + 1] = { '\0' }; + strncpy_from_user(path, (const char *)arg1, SUPERCALL_SU_PATH_LEN); + return call_reset_su_path(path); } else { ret = SUPERCALL_RES_NOT_IMPL; } diff --git a/kernel/init/include/accctl.h b/kernel/init/include/accctl.h index 8c17aa5e..9af12f1e 100644 --- a/kernel/init/include/accctl.h +++ b/kernel/init/include/accctl.h @@ -14,15 +14,15 @@ int effect_su_unsafe(const char *sctx); int commit_su(int super, const char *sctx); int thread_su(pid_t vpid, const char *sctx); -int add_allow_uid(uid_t uid); -int remove_allow_uid(uid_t uid); -int list_allow_uids(uid_t *uids, size_t *size); - -int su_compat_init(); int selinux_hook_install(); int supercall_install(); #ifdef ANDROID +int su_compat_init(); +int add_allow_uid(uid_t uid); +int remove_allow_uid(uid_t uid); +int list_allow_uids(uid_t *uids, size_t *size); +int reset_su_path(const char *path); long supercall_android(long cmd, void *__user arg1, void *__user arg2, void *__user arg3); #endif diff --git a/kernel/init/include/uapi/scdefs.h b/kernel/init/include/uapi/scdefs.h index 6427e0b1..74bc9c8d 100644 --- a/kernel/init/include/uapi/scdefs.h +++ b/kernel/init/include/uapi/scdefs.h @@ -26,6 +26,10 @@ static inline long hash_key(const char *key) #define SUPERCALL_GRANT_SU 0x1020 #define SUPERCALL_REVOKE_SU 0x1021 #define SUPERCALL_LIST_SU_ALLOW 0x1022 +#define SUPERCALL_RESET_SU_PATH 0x1023 + +#define SUPERCALL_SU_ALLOW_UID_MAX 32 +#define SUPERCALL_SU_PATH_LEN 14 #endif #define SUPERCALL_MAX 0x1100 @@ -37,6 +41,5 @@ static inline long hash_key(const char *key) #define SUPERCALL_HELLO_MAGIC 0x1158 #define SUPERCALL_SCONTEXT_LEN 64 -#define SUPERCALL_SU_ALLOW_MAX 32 #endif diff --git a/kernel/linux/include/linux/trace_seq.h b/kernel/linux/include/linux/trace_seq.h index bf139977..99f5d7dc 100644 --- a/kernel/linux/include/linux/trace_seq.h +++ b/kernel/linux/include/linux/trace_seq.h @@ -78,6 +78,7 @@ static inline int trace_seq_bitmask(struct trace_seq *s, const unsigned long *ma return 0; } +// todo: PAGE_SIZE static inline int trace_seq_copy_to_user(void __user *to, const void *from, int n) { struct trace_seq trace_seq; diff --git a/kernel/version b/kernel/version index 17b128e5..144691c4 100644 --- a/kernel/version +++ b/kernel/version @@ -1,3 +1,3 @@ #define MAJOR 0 -#define MINOR 2 -#define PATCH 2 \ No newline at end of file +#define MINOR 3 +#define PATCH 0 \ No newline at end of file diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index f3b7af58..0573159d 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,7 +1,10 @@ cmake_minimum_required(VERSION 3.5) - project (kptools) +file(COPY "../kernel/base/preset.h" DESTINATION ".") + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + set(SOURCES image.c kallsym.c diff --git a/tools/Makefile b/tools/Makefile index e35161b4..b9af4fd7 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -4,12 +4,17 @@ CFLAGS = -std=c11 -Wall -Wextra -Wno-unused -Wno-unused-parameter objs := image.o kallsym.o kptools.o order.o +all: hdr kptools + kptools: ${objs} ${CC} -o $@ $^ %.o : %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ +hdr: + cp ../kernel/base/preset.h . + .PHONY: clean clean: rm -rf preset.h diff --git a/tools/kptools.c b/tools/kptools.c index 108796e6..5d6be2a0 100644 --- a/tools/kptools.c +++ b/tools/kptools.c @@ -10,6 +10,8 @@ #include #include +#include "version" + #include "preset.h" #include "image.h" #include "order.h" @@ -41,6 +43,8 @@ static int b(uint32_t *buf, uint64_t from, uint64_t to) return 0; } +static uint32_t version = 0; + static char image[FILENAME_MAX] = { '\0' }; static char out[FILENAME_MAX] = { '\0' }; static char kpimg[FILENAME_MAX] = { '\0' }; @@ -51,7 +55,8 @@ static kallsym_t kallsym; void print_usage() { - char *c = "\nkptools. Kernel Image Patch Tools.\n" + char *c = "\nkptools. Kernel Image Patch Tools. " + "version: %x\n" "\n" "Usage: ./kptools [args...]\n" " -h, --help\n" @@ -59,13 +64,13 @@ void print_usage() "\n" " -p, --patch <--kpimg kpimg> <--skey super_key> [--out image_patched]\n" " Patch kernel_image with kpimg.\n" - " If [--out] is not specified, default ${kernel_image}__patched will be used.\n" + " If --out is not specified, default ${kernel_image}__patched will be used.\n" " super_key: Authentication key for supercall system call.\n" "\n" " -d, --dump \n" " Analyze and dump kallsyms infomations of kernel_image to stdout.\n" "\n"; - fprintf(stdout, "%s", c); + fprintf(stdout, c, version); } int dump_kallsym() @@ -105,6 +110,15 @@ static int32_t relo_branch_func(const char *img, int32_t func_offset) return relo_offset; } +static void print_kpimg_info(const char *img) +{ + setup_header_t *header = (setup_header_t *)img; + version_t ver = header->kp_version; + uint32_t ver_num = (ver.major << 16) + (ver.minor << 8) + ver.patch; + fprintf(stdout, "[+] kptools kpimg version: %x\n", ver_num); + fprintf(stdout, "[+] kptools kpimg compile time: %s\n", header->compile_time); +} + static void target_endian_preset(setup_preset_t *preset, int32_t target_is_be) { if (!(is_be() ^ target_is_be)) @@ -177,6 +191,8 @@ int patch_image() fread(out_buf + align_image_len, 1, kpimg_len, fkpimg); fclose(fkpimg); + print_kpimg_info(out_buf + align_image_len); + get_kernel_info(&kinfo, image_buf, image_len); long align_kernel_size = align_ceil(kinfo.kernel_size, 4096); @@ -268,20 +284,22 @@ int patch_image() int main(int argc, char *argv[]) { - struct option longopts[] = { { "help", no_argument, NULL, 'h' }, - { "patch", required_argument, NULL, 'p' }, - { "skey", required_argument, NULL, 's' }, - { "out", required_argument, NULL, 'o' }, - { "kpimg", required_argument, NULL, 'k' }, - { "dump", required_argument, NULL, 'd' }, - { 0, 0, 0, 0 } }; - char *optstr = "hp:d:o:"; + version = (MAJOR << 16) + (MINOR << 8) + PATCH; + + struct option longopts[] = { { "version", no_argument, NULL, 'v' }, { "help", no_argument, NULL, 'h' }, + { "patch", required_argument, NULL, 'p' }, { "skey", required_argument, NULL, 's' }, + { "out", required_argument, NULL, 'o' }, { "kpimg", required_argument, NULL, 'k' }, + { "dump", required_argument, NULL, 'd' }, { 0, 0, 0, 0 } }; + char *optstr = "vhp:d:o:"; int cmd = '\0'; int opt = -1; int opt_index = -1; while ((opt = getopt_long(argc, argv, optstr, longopts, &opt_index)) != -1) { switch (opt) { + case 'v': + cmd = 'v'; + break; case 'h': cmd = 'h'; break; @@ -310,6 +328,8 @@ int main(int argc, char *argv[]) ret = patch_image(); } else if (cmd == 'd') { ret = dump_kallsym(); + } else if (cmd == 'v') { + fprintf(stdout, "%x\n", version); } else { print_usage(); } diff --git a/user/.gitignore b/user/.gitignore index f7866cd7..7cf6ee8b 100644 --- a/user/.gitignore +++ b/user/.gitignore @@ -32,6 +32,6 @@ build/* uapi - +version kpatch diff --git a/user/CMakeLists.txt b/user/CMakeLists.txt index 3ede24d8..6d21ffa3 100644 --- a/user/CMakeLists.txt +++ b/user/CMakeLists.txt @@ -1,9 +1,20 @@ cmake_minimum_required(VERSION 3.5) project("kpatch") +# hdr +file(COPY "../kernel/init/include/uapi" DESTINATION ".") +file(COPY "../kernel/version" DESTINATION ".") + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") +if(ANDROID) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DANDROID") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID") +endif() + set(SRCS libkp.c ) diff --git a/user/Makefile b/user/Makefile index 734b6947..7526b09b 100644 --- a/user/Makefile +++ b/user/Makefile @@ -1,9 +1,13 @@ CFLAGS = -std=c11 -Wall -Wextra -Wno-unused -Wno-unused-parameter +ifdef ANDROID + CFLAGS += -DANDROID +endif + objs := libkp.o -all: kpatch libkp.a +all: hdr libkp.a kpatch kpatch: main.o ${objs} ${CC} -o $@ $^ @@ -14,9 +18,14 @@ libkp.a: ${objs} %.o : %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ +hdr: + cp -r ../kernel/init/include/uapi . + cp ../kernel/version . + .PHONY: clean clean: - rm -rf uapi/* - rm -rf kpatch - rm -rf libkp.a + rm -rf build + rm -rf uapi + rm -f kpatch + rm -f libkp.a find . -name "*.o" | xargs rm -f \ No newline at end of file diff --git a/user/libkp.c b/user/libkp.c index 06de4915..83dee53a 100644 --- a/user/libkp.c +++ b/user/libkp.c @@ -10,6 +10,12 @@ #include "version" +uint32_t get_version() +{ + uint32_t version_code = (MAJOR << 16) + (MINOR << 8) + PATCH; + return version_code; +} + long su_fork(const char *key, const char *sctx) { long ret = 0; diff --git a/user/libkp.h b/user/libkp.h index 399bb876..f413cec4 100644 --- a/user/libkp.h +++ b/user/libkp.h @@ -4,12 +4,7 @@ #include "supercall.h" #include "version" -static inline uint32_t get_version() -{ - uint32_t version_code = (MAJOR << 16) + (MINOR << 8) + PATCH; - return version_code; -} - +uint32_t get_version(); long su_fork(const char *key, const char *sctx); #endif diff --git a/user/main.c b/user/main.c index b81f1543..ef1c4658 100644 --- a/user/main.c +++ b/user/main.c @@ -11,44 +11,57 @@ void print_usage(char **argv) { - char *c = "\nkpatch: KernelPatch Userspace Executable.\n" - "\n" - "Common Usage:\n" - "./kpatch -h, --help\n" - " Print this message.\n" - "./kpatch -v, --version\n" - " Print kpatch version.\n" - "\n" - "SuperCall Usage:\n" - "./kpatch [args...]\n" - "command:\n" - " --hello\n" - " Print SuperCall hello message in the kernel. Return 0 if succeed, others if failed!\n" - " --kv\n" - " Get Kernel version.\n" - " --kpv\n" - " Get KernelPatch version.\n" - " --su [--arg1 scontext]\n" - " Fork a root shell and change security context to scontext.\n" - " If scontext is not specified, " - " bypass all selinux permission checks for all calls initiated by this thread using hooks, " - " but the permission determined by other threads remain unchanged.\n" - " --load_kpm --arg1 kpm_patch\n" - " Load KernelPatch Module\n" - " (Unimplemented ...).\n" - " --unload_kpm --arg1 kpm_patch\n" - " Unload KernelPatch Module\n" - " (Unimplemented ...).\n" - " --grant_su --arg1 uid\n" - " Grant root privileges to the user corresponding to the given uid.\n" - " --revoke_su --arg1 uid\n" - " Revoke root privileges to the user corresponding to the given uid.\n" - " --thread_su --arg1 tid\n" - " Grant root privileges to the thread corresponding to the given tid.\n" - " --thread_unsu --arg1 tid\n" - " Revoke root privileges to the thread corresponding to the given tid.\n" - " (Unimplemented ...).\n" - "\n"; + char *c = + "\nkpatch: KernelPatch Userspace Executable.\n" + "\n" + "Common Usage:\n" + "./kpatch -h, --help\n" + " Print this message.\n" + "./kpatch -v, --version\n" + " Print kpatch version.\n" + "\n" + "SuperCall Usage:\n" + "./kpatch [args...]\n" + "command:\n" + " --hello\n" + " Print SuperCall hello message in the kernel. Return 0 if succeed, others if failed!\n" + " --kv\n" + " Get Kernel version.\n" + " --kpv\n" + " Get KernelPatch version.\n" + " --su [--arg1 scontext]\n" + " Fork a root shell and change security context to scontext.\n" + " If scontext is not specified, " + " bypass all selinux permission checks for all calls initiated by this thread using hooks, " + " but the permission determined by other threads remain unchanged.\n" + " --load_kpm --arg1 path\n" + " Load KernelPatch Module\n" + " (Unimplemented ...).\n" + " --unload_kpm --arg1 path\n" + " Unload KernelPatch Module\n" + " (Unimplemented ...).\n" + " --thread_su --arg1 tid\n" + " Grant root privileges to the thread corresponding to the given tid.\n" + " --thread_unsu --arg1 tid\n" + " Revoke root privileges to the thread corresponding to the given tid.\n" + " (Unimplemented ...).\n" +#ifdef ANDROID + "\n" + "Android Specific Usage:\n" + "The default command to get a root shell is 'kp', whose full path is '/system/bin/kp'.\n" + "This can avoid conflicts with the existing 'su' command.\n" + "If you want to change this path, you can use the 'reset_su' command, " + "but keep in mind that the command's length should not exceed two characters.\n" + " --grant_su --arg1 uid\n" + " Grant root privileges to the user corresponding to the given uid.\n" + " --revoke_su --arg1 uid\n" + " Revoke root privileges to the user corresponding to the given uid.\n" + " --list_su\n" + " Revoke root privileges to the user corresponding to the given uid.\n" + " --reset_su --arg1 cmd\n" + " Reset root shell command full path to '/system/bin/cmd'. The length of cmd must not exceed two characters.\n" +#endif + "\n"; fprintf(stdout, "%s", c); } @@ -86,12 +99,14 @@ int main(int argc, char **argv) { "load_kpm", no_argument, NULL, SUPERCALL_LOAD_KPM }, { "unload_kpm", no_argument, NULL, SUPERCALL_UNLOAD_KPM }, { "su", no_argument, &cmd, SUPERCALL_SU }, + { "thread_su", no_argument, &cmd, SUPERCALL_THREAD_SU }, + { "thread_unsu", no_argument, &cmd, SUPERCALL_THREAD_UNSU }, +#ifdef ANDROID { "grant_su", no_argument, &cmd, SUPERCALL_GRANT_SU }, { "revoke_su", no_argument, &cmd, SUPERCALL_REVOKE_SU }, { "list_su", no_argument, &cmd, SUPERCALL_LIST_SU_ALLOW }, - { "thread_su", no_argument, &cmd, SUPERCALL_THREAD_SU }, - { "thread_unsu", no_argument, &cmd, SUPERCALL_THREAD_UNSU }, - + { "reset_su", no_argument, &cmd, SUPERCALL_RESET_SU_PATH }, +#endif { 0, 0, 0, 0 } }; char *optstr = "1:2:3:"; int opt = -1; @@ -125,7 +140,23 @@ int main(int argc, char **argv) fprintf(stdout, "%lx\n", kpv); } else if (cmd == SUPERCALL_SU) { ret = su_fork(key, arg1); - } else if (cmd == SUPERCALL_GRANT_SU) { + } else if (cmd == SUPERCALL_THREAD_SU) { + if (!arg1) { + fprintf(stderr, "Empty tid!\n"); + return -1; + } + int pid = atoi(arg1); + ret = sc_thread_su(key, pid, 0); + } else if (cmd == SUPERCALL_THREAD_UNSU) { + if (!arg1) { + fprintf(stderr, "Empty tid!\n"); + return -1; + } + int pid = atoi(arg1); + ret = sc_thread_unsu(key, pid); + } +#ifdef ANDROID + else if (cmd == SUPERCALL_GRANT_SU) { if (!arg1) { fprintf(stderr, "Empty uid!\n"); return -1; @@ -140,8 +171,8 @@ int main(int argc, char **argv) uid_t uid = atoi(arg1); ret = sc_revoke_su(key, uid); } else if (cmd == SUPERCALL_LIST_SU_ALLOW) { - uid_t uids[SUPERCALL_SU_ALLOW_MAX]; - size_t size = SUPERCALL_SU_ALLOW_MAX; + uid_t uids[SUPERCALL_SU_ALLOW_UID_MAX]; + size_t size = SUPERCALL_SU_ALLOW_UID_MAX; ret = sc_list_su_allow(key, uids, &size); if (ret) return ret; @@ -150,24 +181,22 @@ int main(int argc, char **argv) fprintf(stdout, "%d\t", uids[i]); } fprintf(stdout, "\n"); - } else if (cmd == SUPERCALL_THREAD_SU) { - if (!arg1) { - fprintf(stderr, "Empty tid!\n"); + } else if (cmd == SUPERCALL_RESET_SU_PATH) { + const char *cmd = (const char *)arg1; + if (strnlen(cmd, 3) > 2) { + fprintf(stderr, "The string length of arg1 should not exceed two characters.\n"); return -1; } - int pid = atoi(arg1); - ret = sc_thread_su(key, pid, 0); - } else if (cmd == SUPERCALL_THREAD_UNSU) { - if (!arg1) { - fprintf(stderr, "Empty tid!\n"); - return -1; - } - int pid = atoi(arg1); - ret = sc_thread_unsu(key, pid); - } else { + char path[sizeof("/system/bin/sh")] = { '\0' }; + sprintf(path, "/system/bin/%s", cmd); + return sc_reset_su_path(key, path); + } +#endif + else { fprintf(stderr, "Invalid SuperCall command!\n"); return 0; } + if (ret == SUPERCALL_RES_NOT_IMPL) { fprintf(stdout, "Unimplemented SuperCall\n"); } diff --git a/user/supercall.h b/user/supercall.h index 0c2f2307..8022180b 100644 --- a/user/supercall.h +++ b/user/supercall.h @@ -6,6 +6,7 @@ #include #include #include +#include static inline long sc_hello(const char *key) { @@ -44,10 +45,27 @@ static inline long sc_unload_kpm(const char *key, const char *path) static inline long sc_su(const char *key, const char *sctx) { + // todo: error code + if (sctx && strlen(sctx) > SUPERCALL_SCONTEXT_LEN) { + return -1; + } long ret = syscall(__NR_supercall, key, hash_key(key), SUPERCALL_SU, sctx); return ret; } +static inline long sc_thread_su(const char *key, pid_t pid, const char *sctx) +{ + long ret = syscall(__NR_supercall, key, hash_key(key), SUPERCALL_THREAD_SU, pid, sctx); + return ret; +} + +static inline long sc_thread_unsu(const char *key, pid_t pid) +{ + long ret = syscall(__NR_supercall, key, hash_key(key), SUPERCALL_THREAD_UNSU, pid); + return ret; +} + +#ifdef ANDROID static inline long sc_grant_su(const char *key, uid_t uid) { long ret = syscall(__NR_supercall, key, hash_key(key), SUPERCALL_GRANT_SU, uid); @@ -62,20 +80,21 @@ static inline long sc_revoke_su(const char *key, uid_t uid) static inline long sc_list_su_allow(const char *key, uid_t *uids, size_t *size) { + // todo: size enough long ret = syscall(__NR_supercall, key, hash_key(key), SUPERCALL_LIST_SU_ALLOW, uids, size); return ret; } -static inline long sc_thread_su(const char *key, pid_t pid, const char *sctx) +static inline long sc_reset_su_path(const char *key, const char *path) { - long ret = syscall(__NR_supercall, key, hash_key(key), SUPERCALL_THREAD_SU, pid, sctx); + // todo: error code + if (strlen(path) > SUPERCALL_SU_PATH_LEN) { + return -1; + } + long ret = syscall(__NR_supercall, key, hash_key(key), SUPERCALL_RESET_SU_PATH, path); return ret; } -static inline long sc_thread_unsu(const char *key, pid_t pid) -{ - long ret = syscall(__NR_supercall, key, hash_key(key), SUPERCALL_THREAD_UNSU, pid); - return ret; -} +#endif #endif \ No newline at end of file diff --git a/user/version b/user/version deleted file mode 100644 index 17b128e5..00000000 --- a/user/version +++ /dev/null @@ -1,3 +0,0 @@ -#define MAJOR 0 -#define MINOR 2 -#define PATCH 2 \ No newline at end of file