From a4c4082acf7fd61ee8ff61fb66ba5698e1a631aa Mon Sep 17 00:00:00 2001 From: bmax Date: Mon, 30 Sep 2024 20:16:02 +0800 Subject: [PATCH] add exclude api, add exclude command to supercmd --- kernel/patch/common/selinuxhook.c.bak | 336 ---------------- kernel/patch/common/sucompat.c | 43 +- kernel/patch/common/sucompat.c.bak | 554 -------------------------- kernel/patch/common/supercmd.c | 23 +- kernel/patch/include/kstorage.h | 4 +- kernel/patch/include/sucompat.h | 3 +- kernel/patch/include/uapi/scdefs.h | 4 +- kernel/patch/patch.c | 8 +- user/supercall.h | 109 ++--- 9 files changed, 131 insertions(+), 953 deletions(-) delete mode 100644 kernel/patch/common/selinuxhook.c.bak delete mode 100644 kernel/patch/common/sucompat.c.bak diff --git a/kernel/patch/common/selinuxhook.c.bak b/kernel/patch/common/selinuxhook.c.bak deleted file mode 100644 index 20be0f2..0000000 --- a/kernel/patch/common/selinuxhook.c.bak +++ /dev/null @@ -1,336 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2023 bmax121. All Rights Reserved. - */ - -#include "accctl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SHOW_AVC_PASS_LOG - -#if 0 -static void _selinux_debug(u32 ssid, u32 tsid, u16 tclass, u32 requested) -{ - logkfd("ssid: %x, tsid: %x, tclass: %x, requested: %x\n", ssid, tsid, tclass, requested); - char *scontext = 0; - u32 sctx_len = 0; - char *tcontext = 0; - u32 tctx_len = 0; - security_sid_to_context(ssid, &scontext, &sctx_len); - security_sid_to_context(tsid, &tcontext, &tctx_len); - const char *stclass = kvar_val(secclass_map)[tclass - 1].name; - const char *const *perms = kvar_val(secclass_map)[tclass - 1].perms; - char buf[128] = { '\0' }; - for (int i = 0; i < (sizeof(u32) * 8); i++) { - if ((1 << i) & requested) { - int len = min_strlen(buf); - min_snprintf(buf + len, 128 - len, "%s ", perms[i]); - } - } - logkfd("context: %s, tcontext: %s, tclass: %s, perms: %s\n", scontext, tcontext, stclass, buf); -} -#endif - -#define hook_backup(func) (*backup_##func) -#define hook_replace(func) replace_##func -#define hook_call_backup(func, ...) backup_##func(__VA_ARGS__) - -#define hook_kfunc_with(func, replace, backup) \ - if (kfunc(func)) { \ - hook_err_t err_##func = hook(kfunc(func), replace, (void **)&backup); \ - if (err_##func != HOOK_NO_ERR) log_boot("hook %s, %llx, error: %d\n", #func, kfunc(func), err_##func); \ - } else { \ - log_boot("no symbol: %s\n", #func); \ - } - -#define hook_kfunc(func) hook_kfunc_with(func, replace_##func, backup_##func) - -#define find_and_hook_func_with(func, replace, backup) \ - unsigned long addr = kallsyms_lookup_name(#func); \ - if (addr) { \ - hook_err_t err_##func = hook(addr, replace, (void **)&backup); \ - if (err_##func != HOOK_NO_ERR) log_boot("hook %s, %llx, error: %d\n", #func, kfunc(func), err_##func); \ - } else { \ - log_boot("no symbol %s\n", #func); \ - } - -#define HOOK_AVC_RET_ZERO_BEFORE() \ - struct task_ext *ext = get_current_task_ext(); \ - if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { \ - return 0; \ - } - -static int (*avc_denied_backup)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, void *requested, - void *driver, void *xperm, void *flags, struct av_decision *avd) = 0; - -static int avc_denied_replace(struct selinux_state *_state, void *_ssid, void *_tsid, void *_tclass, void *_requested, - void *_driver, void *_xperm, void *_flags, struct av_decision *_avd) -{ - struct task_ext *ext = get_current_task_ext(); - if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { - struct av_decision *avd = (struct av_decision *)_avd; - if ((uint64_t)_state <= 0xffffffffL) { - avd = (struct av_decision *)_flags; - } - avd->allowed = 0xffffffff; - avd->auditallow = 0; - avd->auditdeny = 0; - return 0; - } - int rc = avc_denied_backup(_state, _ssid, _tsid, _tclass, _requested, _driver, _xperm, _flags, _avd); - return rc; -} - -static int (*slow_avc_audit_backup)(struct selinux_state *_state, void *_ssid, void *_tsid, void *_tclass, - void *_requested, void *_audited, void *_denied, void *_result, - struct common_audit_data *_a) = 0; - -static int slow_avc_audit_replace(struct selinux_state *_state, void *_ssid, void *_tsid, void *_tclass, - void *_requested, void *_audited, void *_denied, void *_result, - struct common_audit_data *_a) -{ - struct task_ext *ext = get_current_task_ext(); - if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { - return 0; - } - int rc = slow_avc_audit_backup(_state, _ssid, _tsid, _tclass, _requested, _audited, _denied, _result, _a); - return rc; -} - -// static inline void *min_memset(void *dst, int c, size_t n) -// { -// char *q = dst; -// while (n--) { -// *q++ = c; -// } -// return dst; -// } - -// static int hook_backup(avc_has_perm_noaudit)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, -// void *requested, void *flags, struct av_decision *avd) = 0; -// static int hook_replace(avc_has_perm_noaudit)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, -// void *requested, void *flags, struct av_decision *avd) -// { -// // HOOK_AVC_RET_ZERO_BEFORE(); - -// struct task_ext *ext = get_current_task_ext(); -// if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { -// struct av_decision *avd = (struct av_decision *)avd; -// if (((uint64_t)state & 0xF000000000000000) != 0xF000000000000000) { -// avd = (struct av_decision *)flags; -// } -// if (((uint64_t)avd & 0xF000000000000000) == 0xF000000000000000) { -// avd->allowed = 0xffffffff; -// avd->auditallow = 0; -// avd->auditdeny = 0; -// } -// return 0; -// } - -// int rc = hook_call_backup(avc_has_perm_noaudit, state, ssid, tsid, tclass, requested, flags, avd); - -// return rc; -// } - -// static int hook_backup(avc_has_perm)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, void *requested, -// struct common_audit_data *auditdata) = 0; -// static int hook_replace(avc_has_perm)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, -// void *requested, struct common_audit_data *auditdata) -// { -// HOOK_AVC_RET_ZERO_BEFORE(); -// int rc = hook_call_backup(avc_has_perm, state, ssid, tsid, tclass, requested, auditdata); -// return rc; -// } - -// static int hook_backup(avc_has_perm_flags)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, -// void *requested, struct common_audit_data *auditdata, void *flags) = 0; -// static int hook_replace(avc_has_perm_flags)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, -// void *requested, struct common_audit_data *auditdata, void *flags) -// { -// HOOK_AVC_RET_ZERO_BEFORE(); -// int rc = hook_call_backup(avc_has_perm_flags, state, ssid, tsid, tclass, requested, auditdata, flags); -// return rc; -// } - -// // int avc_has_extended_perms((struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, u8 driver, u8 xperm, struct common_audit_data *ad) -// static int hook_backup(avc_has_extended_perms)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, -// void *requested, void *driver, void *perm, struct common_audit_data *ad); -// static int hook_replace(avc_has_extended_perms)(struct selinux_state *state, void *ssid, void *tsid, void *tclass, -// void *requested, void *driver, void *perm, struct common_audit_data *ad) -// { -// HOOK_AVC_RET_ZERO_BEFORE(); -// int rc = hook_call_backup(avc_has_extended_perms, state, ssid, tsid, tclass, requested, driver, perm, ad); -// return rc; -// } - -// static void make_avc_node_all_perm(struct avc_node *node) -// { -// struct avc_entry *ae = &node->ae; -// struct av_decision *avd = &ae->avd; -// avd->allowed = 0xffffffff; -// avd->auditallow = 0; -// avd->auditdeny = 0; -// if (likely(kfunc(avc_has_extended_perms))) { -// struct avc_xperms_node *xp_node = ae->xp_node; -// if (xp_node) { -// struct extended_perms *xp = &xp_node->xp; -// min_memset(xp->drivers.p, 0xff, sizeof(xp->drivers.p)); -// } -// } -// } - -// struct avc_node *hook_backup(avc_lookup)(void *_state, void *_ssid, void *_tsid, void *_tclass) = 0; - -// // struct selinux_avc *avc, u32 ssid, u32 tsid, u16 tclass -// struct avc_node *hook_replace(avc_lookup)(void *_state, void *_ssid, void *_tsid, void *_tclass) -// { -// struct avc_node *node = hook_call_backup(avc_lookup, _state, _ssid, _tsid, _tclass); -// if (!node) return node; - -// struct task_ext *ext = get_current_task_ext(); -// if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { -// make_avc_node_all_perm(node); -// } -// return node; -// } - -// struct avc_node *hook_backup(avc_compute_av)(void *_state, void *_ssid, void *_tsid, void *_tclass, void *_avd, -// void *_xp_node); - -// // struct selinux_state *state,u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd, struct avc_xperms_node *xp_node -// struct avc_node *hook_replace(avc_compute_av)(void *_state, void *_ssid, void *_tsid, void *_tclass, void *_avd, -// void *_xp_node) -// { -// struct avc_node *node = hook_call_backup(avc_compute_av, _state, _ssid, _tsid, _tclass, _avd, _xp_node); -// struct task_ext *ext = get_current_task_ext(); -// if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { -// struct av_decision *avd = (struct av_decision *)_avd; -// struct avc_xperms_node *xp_node = (struct avc_xperms_node *)_xp_node; -// if ((uint64_t)_state <= 0xffffffffL) { -// avd = (struct av_decision *)_tclass; -// xp_node = (struct avc_xperms_node *)_avd; -// } -// avd->allowed = 0xffffffff; -// avd->auditallow = 0; -// avd->auditdeny = 0; -// if (xp_node) { -// struct extended_perms *xp = &xp_node->xp; -// min_memset(xp->drivers.p, 0xff, sizeof(xp->drivers.p)); -// } -// make_avc_node_all_perm(node); -// } -// return node; -// } - -// static void hook_backup(security_compute_av)(void *_state, void *_ssid, void *_tsid, void *_orig_tclass, void *_avd, -// void *_xperms) = 0; - -// // struct selinux_state *state, u32 ssid, u32 tsid, u16 orig_tclass, struct av_decision *avd, struct extended_perms *xperms -// static void hook_replace(security_compute_av)(void *_state, void *_ssid, void *_tsid, void *_orig_tclass, void *_avd, -// void *_xperms) -// { -// hook_call_backup(security_compute_av, _state, _ssid, _tsid, _orig_tclass, _avd, _xperms); - -// struct task_ext *ext = get_current_task_ext(); -// if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { -// struct av_decision *avd = (struct av_decision *)_avd; -// struct extended_perms *xperms = (struct extended_perms *)_xperms; -// if ((uint64_t)_state <= 0xffffffffL) { -// avd = (struct av_decision *)_orig_tclass; -// xperms = (struct extended_perms *)_avd; -// } -// avd->allowed = 0xffffffff; -// avd->auditallow = 0; -// avd->auditdeny = 0; -// if (xperms) { -// min_memset(xperms->drivers.p, 0xff, sizeof(xperms->drivers.p)); -// } -// } -// } - -// static void hook_backup(security_compute_xperms_decision)(void *_state, void *_ssid, void *_tsid, void *_orig_tclass, -// void *_driver, void *_xpermd) = 0; - -// //struct selinux_state *state, u32 ssid, u32 tsid, u16 orig_tclass, u8 driver, struct extended_perms_decision *xpermd -// static void hook_replace(security_compute_xperms_decision)(void *_state, void *_ssid, void *_tsid, void *_orig_tclass, -// void *_driver, void *_xpermd) -// { -// hook_call_backup(security_compute_xperms_decision, _state, _ssid, _tsid, _orig_tclass, _driver, _xpermd); -// struct task_ext *ext = get_current_task_ext(); -// if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { -// struct extended_perms_decision *xpermd = (struct extended_perms_decision *)_xpermd; -// if ((uint64_t)_state <= 0xffffffffL) { -// xpermd = (struct extended_perms_decision *)_driver; -// } -// min_memset(xpermd->allowed->p, 0xff, sizeof(xpermd->allowed->p)); -// min_memset(xpermd->auditallow->p, 0, sizeof(xpermd->auditallow->p)); -// min_memset(xpermd->dontaudit->p, 0xff, sizeof(xpermd->dontaudit->p)); -// } -// } - -// static void hook_backup(security_compute_av_user)(void *_state, void *_ssid, void *_tsid, void *_tclass, -// void *_avd) = 0; - -// // struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd -// static void hook_replace(security_compute_av_user)(void *_state, void *_ssid, void *_tsid, void *_tclass, void *_avd) -// { -// hook_call_backup(security_compute_av_user, _state, _ssid, _tsid, _tclass, _avd); - -// struct task_ext *ext = get_current_task_ext(); -// if (unlikely(task_ext_valid(ext) && (ext->sel_allow || ext->priv_sel_allow))) { -// struct av_decision *avd = (struct av_decision *)_avd; -// if ((uint64_t)_state <= 0xffffffffL) { -// avd = (struct av_decision *)_tclass; -// } -// avd->allowed = 0xffffffff; -// avd->auditallow = 0; -// avd->auditdeny = 0; -// } -// } - -int selinux_hook_install() -{ - unsigned long avc_denied_addr = patch_config->avc_denied; - if (avc_denied_addr) { - hook_err_t err = hook((void *)avc_denied_addr, (void *)avc_denied_replace, (void **)&avc_denied_backup); - if (err != HOOK_NO_ERR) { - log_boot("hook avc_denied_addr: %llx, error: %d\n", avc_denied_addr, err); - } - } - - unsigned long slow_avc_audit_addr = patch_config->slow_avc_audit; - if (slow_avc_audit_addr) { - hook_err_t err = - hook((void *)slow_avc_audit_addr, (void *)slow_avc_audit_replace, (void **)&slow_avc_audit_backup); - if (err != HOOK_NO_ERR) { - log_boot("hook slow_avc_audit: %llx, error: %d\n", slow_avc_audit_addr, err); - } - } - - // hook_kfunc(avc_denied); - // hook_kfunc(slow_avc_audit); - - // hook_kfunc(avc_has_perm_noaudit); - // hook_kfunc(avc_has_perm); - // hook_kfunc(avc_has_perm_flags); - // hook_kfunc(avc_has_extended_perms); - - // we can't hook avc_compute_av and ..., it will 'avc_update_node' with diffused permission allowed - // hook_kfunc(avc_lookup); - // hook_kfunc(avc_compute_av); - - // hook_kfunc(security_compute_av); - // hook_kfunc(security_compute_xperms_decision); - // hook_kfunc(security_compute_av_user); - - return 0; -} \ No newline at end of file diff --git a/kernel/patch/common/sucompat.c b/kernel/patch/common/sucompat.c index 6a017d3..13cfc4d 100644 --- a/kernel/patch/common/sucompat.c +++ b/kernel/patch/common/sucompat.c @@ -49,10 +49,13 @@ const char apd_path[] = APD_PATH; static const char *current_su_path = 0; +static int su_kstorage_gid = -1; +static int exclude_kstorage_gid = -1; + int is_su_allow_uid(uid_t uid) { rcu_read_lock(); - const struct kstorage *ks = get_kstorage(KSTORAGE_SU_LIST_GROUP, uid); + const struct kstorage *ks = get_kstorage(su_kstorage_gid, uid); struct su_profile *profile = (struct su_profile *)ks->data; int rc = profile != 0; rcu_read_unlock(); @@ -68,7 +71,7 @@ int su_add_allow_uid(uid_t uid, uid_t to_uid, const char *scontext) to_uid, }; memcpy(profile.scontext, scontext, SUPERCALL_SCONTEXT_LEN); - int rc = write_kstorage(KSTORAGE_SU_LIST_GROUP, uid, &profile, 0, sizeof(struct su_profile), false); + int rc = write_kstorage(su_kstorage_gid, uid, &profile, 0, sizeof(struct su_profile), false); logkfd("uid: %d, to_uid: %d, sctx: %s, rc: %d\n", uid, to_uid, scontext, rc); return rc; } @@ -76,13 +79,13 @@ KP_EXPORT_SYMBOL(su_add_allow_uid); int su_remove_allow_uid(uid_t uid) { - return remove_kstorage(KSTORAGE_SU_LIST_GROUP, uid); + return remove_kstorage(su_kstorage_gid, uid); } KP_EXPORT_SYMBOL(su_remove_allow_uid); int su_allow_uid_nums() { - return kstorage_group_size(KSTORAGE_SU_LIST_GROUP); + return kstorage_group_size(su_kstorage_gid); } KP_EXPORT_SYMBOL(su_allow_uid_nums); @@ -124,7 +127,7 @@ int su_allow_uids(int is_user, uid_t *out_uids, int out_num) uid_t *up; int un; } udata = { is_user, out_uids, out_num }; - on_each_kstorage_elem(KSTORAGE_SU_LIST_GROUP, allow_uids_cb, &udata); + on_each_kstorage_elem(su_kstorage_gid, allow_uids_cb, &udata); return rc; } KP_EXPORT_SYMBOL(su_allow_uids); @@ -134,7 +137,7 @@ int su_allow_uid_profile(int is_user, uid_t uid, struct su_profile *out_profile) int rc = 0; rcu_read_lock(); - const struct kstorage *ks = get_kstorage(KSTORAGE_SU_LIST_GROUP, uid); + const struct kstorage *ks = get_kstorage(su_kstorage_gid, uid); if (IS_ERR(ks)) { rc = -ENOENT; goto out; @@ -237,6 +240,7 @@ static void handle_before_execve(char **__user u_filename_p, char **__user uargv } #endif // ANDROID } else if (!strcmp(SUPERCMD, filename)) { + void handle_supercmd(char **__user u_filename_p, char **__user uargv); handle_supercmd(u_filename_p, uargv); return; } @@ -311,6 +315,27 @@ static void su_handler_arg1_ufilename_before(hook_fargs6_t *args, void *udata) } } +int set_su_mod_exclude(uid_t uid, int exclude) +{ + int rc = 0; + if (exclude) { + rc = write_kstorage(exclude_kstorage_gid, uid, &exclude, 0, sizeof(exclude), false); + } else { + rc = remove_kstorage(exclude_kstorage_gid, uid); + } + return rc; +} +KP_EXPORT_SYMBOL(set_su_mod_exclude); + +int get_su_mod_exclude(uid_t uid) +{ + int exclude = 0; + int rc = read_kstorage(exclude_kstorage_gid, uid, &exclude, 0, sizeof(exclude), false); + if (rc < 0) return false; + return exclude; +} +KP_EXPORT_SYMBOL(get_su_mod_exclude); + int su_compat_init() { current_su_path = default_su_path; @@ -331,6 +356,12 @@ int su_compat_init() // if (!enable) return; + su_kstorage_gid = try_alloc_kstroage_group(); + if (su_kstorage_gid < 0) return -ENOMEM; + + exclude_kstorage_gid = try_alloc_kstroage_group(); + if (exclude_kstorage_gid < 0) return -ENOMEM; + rc = hook_syscalln(__NR_execve, 3, before_execve, 0, (void *)0); log_boot("hook __NR_execve rc: %d\n", rc); diff --git a/kernel/patch/common/sucompat.c.bak b/kernel/patch/common/sucompat.c.bak deleted file mode 100644 index be3ab2e..0000000 --- a/kernel/patch/common/sucompat.c.bak +++ /dev/null @@ -1,554 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2023 bmax121. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char sh_path[] = SH_PATH; -const char default_su_path[] = SU_PATH; - -#ifdef ANDROID -const char legacy_su_path[] = LEGACY_SU_PATH; -const char apd_path[] = APD_PATH; -#endif - -static const char *current_su_path = 0; - -static struct list_head allow_uid_list; -static spinlock_t list_lock; - -static void allow_reclaim_callback(struct rcu_head *rcu) -{ - struct allow_uid *allow = container_of(rcu, struct allow_uid, rcu); - kvfree(allow); -} - -struct su_profile profile_su_allow_uid(uid_t uid) -{ - rcu_read_lock(); - struct allow_uid *pos; - struct su_profile profile = { 0 }; - list_for_each_entry_rcu(pos, &allow_uid_list, list) - { - if (pos->uid == uid) { - memcpy(&profile, &pos->profile, sizeof(struct su_profile)); - rcu_read_unlock(); - return profile; - } - } - rcu_read_unlock(); - return profile; -} -KP_EXPORT_SYMBOL(profile_su_allow_uid); - -int is_su_allow_uid(uid_t uid) -{ - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry_rcu(pos, &allow_uid_list, list) - { - if (pos->uid == uid) { - rcu_read_unlock(); - return 1; - } - } - rcu_read_unlock(); - return 0; -} -KP_EXPORT_SYMBOL(is_su_allow_uid); - -int su_add_allow_uid(uid_t uid, uid_t to_uid, const char *scontext, int async) -{ - if (!scontext) scontext = ""; - - rcu_read_lock(); - struct allow_uid *pos, *old = 0; - list_for_each_entry(pos, &allow_uid_list, list) - { - if (pos->uid == uid) { - old = pos; - break; - } - } - // todo: vmalloc -> kmalloc, gfp - struct allow_uid *new = (struct allow_uid *)vmalloc(sizeof(struct allow_uid)); - new->uid = uid; - new->profile.uid = uid; - new->profile.to_uid = to_uid; - strncpy(new->profile.scontext, scontext, sizeof(new->profile.scontext)); - new->profile.scontext[sizeof(new->profile.scontext) - 1] = '\0'; - - spin_lock(&list_lock); - if (old) { // update - list_replace_rcu(&old->list, &new->list); - logkfi("update uid: %d, to_uid: %d, sctx: %s\n", uid, new->profile.to_uid, new->profile.scontext); - } else { // add new one - list_add_rcu(&new->list, &allow_uid_list); - logkfi("new uid: %d, to_uid: %d, sctx: %s\n", uid, new->profile.to_uid, new->profile.scontext); - } - spin_unlock(&list_lock); - - rcu_read_unlock(); - if (old) { - if (async) { - call_rcu(&old->rcu, allow_reclaim_callback); - } else { - synchronize_rcu(); - kvfree(old); - } - } - return 0; -} -KP_EXPORT_SYMBOL(su_add_allow_uid); - -int su_remove_allow_uid(uid_t uid, int async) -{ - struct allow_uid *pos; - spin_lock(&list_lock); - list_for_each_entry(pos, &allow_uid_list, list) - { - if (pos->uid == uid) { - list_del_rcu(&pos->list); - spin_unlock(&list_lock); - logkfi("uid: %d, to_uid: %d, sctx: %s\n", pos->uid, pos->profile.to_uid, pos->profile.scontext); - if (async) { - call_rcu(&pos->rcu, allow_reclaim_callback); - } else { - synchronize_rcu(); - kvfree(pos); - } - return 0; - } - } - spin_unlock(&list_lock); - return 0; -} -KP_EXPORT_SYMBOL(su_remove_allow_uid); - -int su_allow_uid_nums() -{ - int num = 0; - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry(pos, &allow_uid_list, list) - { - num++; - } - rcu_read_unlock(); - logkfd("%d\n", num); - return num; -} -KP_EXPORT_SYMBOL(su_allow_uid_nums); - -int su_allow_uids(int is_user, uid_t *out_uids, int out_num) -{ - int rc = 0; - int num = 0; - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry(pos, &allow_uid_list, list) - { - if (num >= out_num) goto out; - - uid_t uid = pos->profile.uid; - if (is_user) { - int cplen = compat_copy_to_user(out_uids + num, &uid, sizeof(uid)); - logkfd("uid: %d\n", uid); - if (cplen <= 0) { - logkfd("compat_copy_to_user error: %d", cplen); - rc = cplen; - goto out; - } - } else { - out_uids[num] = uid; - } - - num++; - } - rc = num; -out: - rcu_read_unlock(); - return rc; -} -KP_EXPORT_SYMBOL(su_allow_uids); - -int su_allow_uid_profile(int is_user, uid_t uid, struct su_profile *profile) -{ - int rc = -ENOENT; - rcu_read_lock(); - struct allow_uid *pos; - list_for_each_entry(pos, &allow_uid_list, list) - { - if (pos->profile.uid != uid) continue; - if (is_user) { - int cplen = compat_copy_to_user(profile, &pos->profile, sizeof(struct su_profile)); - logkfd("profile: %d %d %s\n", uid, pos->profile.to_uid, pos->profile.scontext); - if (cplen <= 0) { - logkfd("compat_copy_to_user error: %d", cplen); - rc = cplen; - goto out; - } - } else { - memcpy(profile, &pos->profile, sizeof(struct su_profile)); - } - rc = 0; - goto out; - } -out: - rcu_read_unlock(); - return rc; -} -KP_EXPORT_SYMBOL(su_allow_uid_profile); - -// no free, no lock -int su_reset_path(const char *path) -{ - if (!path) return -EINVAL; - if (IS_ERR(path)) return PTR_ERR(path); - current_su_path = path; - logkfd("%s\n", current_su_path); - dsb(ish); - return 0; -} -KP_EXPORT_SYMBOL(su_reset_path); - -const char *su_get_path() -{ - if (!current_su_path) current_su_path = default_su_path; - return current_su_path; -} -KP_EXPORT_SYMBOL(su_get_path); - -// #define TRY_DIRECT_MODIFY_USER - -#define INLINE_HOOK_SYSCALL - -static void handle_before_execve(hook_local_t *hook_local, char **__user u_filename_p, char **__user uargv, void *udata) -{ -#ifdef TRY_DIRECT_MODIFY_USER - // copy to user len - hook_local->data0 = 0; -#endif - - char __user *ufilename = *u_filename_p; - char filename[SU_PATH_MAX_LEN]; - int flen = compat_strncpy_from_user(filename, ufilename, sizeof(filename)); - if (flen <= 0) return; - - if (!strcmp(current_su_path, filename)) { - uid_t uid = current_uid(); - if (!is_su_allow_uid(uid)) return; - struct su_profile profile = profile_su_allow_uid(uid); - - uid_t to_uid = profile.to_uid; - const char *sctx = profile.scontext; - commit_su(to_uid, sctx); - -#ifdef ANDROID - struct file *filp = filp_open(apd_path, O_RDONLY, 0); - if (!filp || IS_ERR(filp)) { -#endif - int cplen = 0; -#ifdef TRY_DIRECT_MODIFY_USER - cplen = compat_copy_to_user(*u_filename_p, sh_path, sizeof(sh_path)); - if (cplen > 0) { - hook_local->data0 = cplen; - hook_local->data1 = (uint64_t)u_filename_p; - logkfi("call su uid: %d, to_uid: %d, sctx: %s, cplen: %d\n", uid, to_uid, sctx, cplen); - } -#endif - if (cplen <= 0) { - void *uptr = copy_to_user_stack(sh_path, sizeof(sh_path)); - if (uptr && !IS_ERR(uptr)) { - *u_filename_p = (char *__user)uptr; - } - logkfi("call su uid: %d, to_uid: %d, sctx: %s, uptr: %llx\n", uid, to_uid, sctx, uptr); - } - -#ifdef ANDROID - } else { - filp_close(filp, 0); - - // command - int cplen = 0; -#ifdef TRY_DIRECT_MODIFY_USER - cplen = compat_copy_to_user(*u_filename_p, apd_path, sizeof(apd_path)); - if (cplen > 0) { - hook_local->data0 = cplen; - hook_local->data1 = (uint64_t)u_filename_p; - } -#endif - uint64_t sp = 0; - if (cplen <= 0) { - sp = current_user_stack_pointer(); - sp -= sizeof(apd_path); - sp &= 0xFFFFFFFFFFFFFFF8; - cplen = compat_copy_to_user((void *)sp, apd_path, sizeof(apd_path)); - if (cplen > 0) { - *u_filename_p = (char *)sp; - } - } - - // argv - int argv_cplen = 0; - if (strcmp(legacy_su_path, filename)) { -#ifdef TRY_DIRECT_MODIFY_USER - const char __user *p1 = get_user_arg_ptr(0, *uargv, 0); - argv_cplen = compat_copy_to_user((void *__user)p1, legacy_su_path, sizeof(legacy_su_path)); -#endif - if (argv_cplen <= 0) { - sp = sp ?: current_user_stack_pointer(); - sp -= sizeof(legacy_su_path); - sp &= 0xFFFFFFFFFFFFFFF8; - argv_cplen = compat_copy_to_user((void *)sp, legacy_su_path, sizeof(legacy_su_path)); - if (argv_cplen > 0) { - int rc = set_user_arg_ptr(0, *uargv, 0, sp); - if (rc < 0) { // todo: modify entire argv - logkfi("call apd argv error, uid: %d, to_uid: %d, sctx: %s, rc: %d\n", uid, to_uid, sctx, - rc); - } - } - } - } - logkfi("call apd uid: %d, to_uid: %d, sctx: %s, cplen: %d, %d\n", uid, to_uid, sctx, cplen, argv_cplen); - } -#endif // ANDROID - } else if (!strcmp(SUPERCMD, filename)) { - handle_supercmd(u_filename_p, uargv); - return; - } -} - -#ifdef TRY_DIRECT_MODIFY_USER -static void handle_after_execve(hook_local_t *hook_local) -{ - int cplen = hook_local->data0; - char **__user u_filename_p = (char **__user)hook_local->data1; - if (cplen > 0) { - compat_copy_to_user((void *)*u_filename_p, current_su_path, cplen); - } -} -#endif - -// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2107 -// COMPAT_SYSCALL_DEFINE3(execve, const char __user *, filename, -// const compat_uptr_t __user *, argv, -// const compat_uptr_t __user *, envp) - -// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2087 -// SYSCALL_DEFINE3(execve, const char __user *, filename, const char __user *const __user *, argv, -// const char __user *const __user *, envp) - -static void before_execve(hook_fargs3_t *args, void *udata) -{ - void *arg0p = syscall_argn_p(args, 0); - void *arg1p = syscall_argn_p(args, 1); - handle_before_execve(&args->local, (char **)arg0p, (char **)arg1p, udata); -} - -#ifdef TRY_DIRECT_MODIFY_USER -static void after_execve(hook_fargs3_t *args, void *udata) -{ - handle_after_execve(&args->local); -} -#else -#define after_execve 0 -#endif - -// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2114 -// COMPAT_SYSCALL_DEFINE5(execveat, int, fd, -// const char __user *, filename, -// const compat_uptr_t __user *, argv, -// const compat_uptr_t __user *, envp, -// int, flags) - -// https://elixir.bootlin.com/linux/v6.1/source/fs/exec.c#L2095 -// SYSCALL_DEFINE5(execveat, int, fd, const char __user *, filename, const char __user *const __user *, argv, -// const char __user *const __user *, envp, int, flags) -__maybe_unused static void before_execveat(hook_fargs5_t *args, void *udata) -{ - void *arg1p = syscall_argn_p(args, 1); - void *arg2p = syscall_argn_p(args, 2); - handle_before_execve(&args->local, (char **)arg1p, (char **)arg2p, udata); -} - -#ifdef TRY_DIRECT_MODIFY_USER -static void after_execveat(hook_fargs5_t *args, void *udata) -{ - handle_after_execve(&args->local); -} -#else -#define after_execveat 0 -#endif - -// https://elixir.bootlin.com/linux/v6.1/source/fs/stat.c#L431 -// SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, -// struct stat __user *, statbuf, int, flag) - -// https://elixir.bootlin.com/linux/v6.1/source/fs/open.c#L492 -// SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) - -// https://elixir.bootlin.com/linux/v6.1/source/fs/open.c#L497 -// SYSCALL_DEFINE4(faccessat2, int, dfd, const char __user *, filename, int, mode, int, flags) - -// https://elixir.bootlin.com/linux/v6.1/source/fs/stat.c#L661 -// SYSCALL_DEFINE5(statx, -// int, dfd, const char __user *, filename, unsigned, flags, -// unsigned int, mask, -// struct statx __user *, buffer) -static void su_handler_arg1_ufilename_before(hook_fargs6_t *args, void *udata) -{ - // copy to user len - args->local.data0 = 0; - - uid_t uid = current_uid(); - if (!is_su_allow_uid(uid)) return; - - char __user **u_filename_p = (char __user **)syscall_argn_p(args, 1); - - char filename[SU_PATH_MAX_LEN]; - int flen = compat_strncpy_from_user(filename, *u_filename_p, sizeof(filename)); - if (flen <= 0) return; - - if (!strcmp(current_su_path, filename)) { -#ifdef TRY_DIRECT_MODIFY_USER - int cplen = 0; - cplen = compat_copy_to_user(*u_filename_p, sh_path, sizeof(sh_path)); - if (cplen > 0) { - args->local.data0 = cplen; - args->local.data1 = (uint64_t)*u_filename_p; - logkfi("su uid: %d, cp: %d\n", uid, cplen); - } else { -#endif - void *uptr = copy_to_user_stack(sh_path, sizeof(sh_path)); - if (uptr && !IS_ERR(uptr)) { - *u_filename_p = uptr; - } else { - logkfi("su uid: %d, cp stack error: %d\n", uid, uptr); - } -#ifdef TRY_DIRECT_MODIFY_USER - } -#endif - } -} - -#ifdef TRY_DIRECT_MODIFY_USER -static void su_handler_arg1_ufilename_after(hook_fargs6_t *args, void *udata) -{ - int cplen = args->local.data0; - if (cplen > 0) { - compat_copy_to_user((void *)args->local.data1, current_su_path, cplen); - } -} -#else -#define su_handler_arg1_ufilename_after 0 -#endif - -int su_compat_init() -{ - current_su_path = default_su_path; - - INIT_LIST_HEAD(&allow_uid_list); - spin_lock_init(&list_lock); - -#ifdef ANDROID - // default shell - if (!all_allow_sctx[0]) strcpy(all_allow_sctx, ALL_ALLOW_SCONTEXT_MAGISK); - su_add_allow_uid(2000, 0, all_allow_sctx, 1); - su_add_allow_uid(0, 0, all_allow_sctx, 1); -#endif - - hook_err_t rc = HOOK_NO_ERR; - - uint8_t su_config = patch_config->patch_su_config; - bool enable = su_config & PATCH_CONFIG_SU_ENABLE; - bool wrap = su_config & PATCH_CONFIG_SU_HOOK_NO_WRAP; - log_boot("su config, enable: %d, wrap: %d\n"); - - rc = hook_syscalln(__NR_execve, 3, before_execve, after_execve, (void *)0); - log_boot("hook __NR_execve rc: %d\n", rc); - - // rc = hook_syscalln(__NR_execveat, 5, before_execveat, after_execveat, (void *)0); - // log_boot("hook __NR_execveat rc: %d\n", rc); - - rc = hook_syscalln(__NR3264_fstatat, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, - (void *)0); - log_boot("hook __NR3264_fstatat rc: %d\n", rc); - - // rc = hook_syscalln(__NR_statx, 5, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, (void *)0); - // log_boot("hook __NR_statx rc: %d\n", rc); - - rc = hook_syscalln(__NR_faccessat, 3, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, (void *)0); - log_boot("hook __NR_faccessat rc: %d\n", rc); - - // rc = - // hook_syscalln(__NR_faccessat2, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, (void *)0); - // log_boot("hook __NR_faccessat2 rc: %d\n", rc); - - // #include - - // __NR_execve 11 - rc = hook_compat_syscalln(11, 3, before_execve, after_execve, (void *)1); - log_boot("hook 32 __NR_execve rc: %d\n", rc); - - // __NR_execveat 387 - // rc = hook_compat_syscalln(387, 5, before_execveat, after_execveat, (void *)1); - // log_boot("hook 32 __NR_execveat rc: %d\n", rc); - - // __NR_statx 397 - // rc = hook_compat_syscalln(397, 5, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, (void *)0); - // log_boot("hook 32 __NR_statx rc: %d\n", rc); - - // #define __NR_stat 106 - // #define __NR_lstat 107 - // #define __NR_stat64 195 - // #define __NR_lstat64 196 - - // __NR_fstatat64 327 - rc = hook_compat_syscalln(327, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, (void *)0); - log_boot("hook 32 __NR_fstatat64 rc: %d\n", rc); - - // __NR_faccessat 334 - rc = hook_compat_syscalln(334, 3, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, (void *)0); - log_boot("hook 32 __NR_faccessat rc: %d\n", rc); - - // __NR_faccessat2 439 - // rc = hook_compat_syscalln(439, 4, su_handler_arg1_ufilename_before, su_handler_arg1_ufilename_after, (void *)0); - // log_boot("hook 32 __NR_faccessat2 rc: %d\n", rc); - - return 0; -} \ No newline at end of file diff --git a/kernel/patch/common/supercmd.c b/kernel/patch/common/supercmd.c index 1d9aa8e..d573642 100644 --- a/kernel/patch/common/supercmd.c +++ b/kernel/patch/common/supercmd.c @@ -80,7 +80,8 @@ static const char supercmd_help[] = " list List all su allowed uids.\n" " profile Get the profile of the uid configuration.\n" " path [PATH] Get or Reset current su path. The length of PATH must 2-127.\n" - " sctx [SCONTEXT] Get or Reset current all allowed security context, \n" + " sctx [SCONTEXT] Get or Reset current all allowed security context.\n" + " exclude [1|0] Get or Reset exclude policy for UID.\n" " event Report EVENT.\n" "\n" "The command below requires superkey authentication.\n" @@ -179,6 +180,26 @@ static void handle_cmd_sumgr(char **__user u_filename_p, const char **carr, char } else { cmd_res->msg = all_allow_sctx; } + } else if (!strcmp(sub_cmd, "exclude")) { + unsigned long long uid; + if (!carr[2] || kstrtoull(carr[2], 10, &uid)) { + cmd_res->err_msg = "invalid uid"; + return; + } else { + if (!carr[3]) { + int exclude = get_su_mod_exclude(uid); + sprintf(buffer, "%d", exclude); + cmd_res->msg = buffer; + } else { + if (carr[3][0] == '0') { + set_su_mod_exclude(uid, 0); + cmd_res->msg = "0"; + } else { + set_su_mod_exclude(uid, 1); + cmd_res->msg = "1"; + } + } + } } else { cmd_res->err_msg = "invalid subcommand"; } diff --git a/kernel/patch/include/kstorage.h b/kernel/patch/include/kstorage.h index 8e7c0a2..b011c11 100644 --- a/kernel/patch/include/kstorage.h +++ b/kernel/patch/include/kstorage.h @@ -27,14 +27,12 @@ int kstorage_group_size(int gid); int write_kstorage(int gid, long did, void *data, int offset, int len, bool data_is_user); -// must surround with rcu read lock +// must within rcu read lock const struct kstorage *get_kstorage(int gid, long did); typedef int (*on_kstorage_cb)(struct kstorage *kstorage, void *udata); int on_each_kstorage_elem(int gid, on_kstorage_cb cb, void *udata); -const struct kstorage *get_kstorage(int gid, long did); - int read_kstorage(int gid, long did, void *data, int offset, int len, bool data_is_user); int remove_kstorage(int gid, long did); diff --git a/kernel/patch/include/sucompat.h b/kernel/patch/include/sucompat.h index d1da7bc..f4035b7 100644 --- a/kernel/patch/include/sucompat.h +++ b/kernel/patch/include/sucompat.h @@ -32,6 +32,7 @@ int su_allow_uid_profile(int is_user, uid_t uid, struct su_profile *profile); int su_reset_path(const char *path); const char *su_get_path(); -void handle_supercmd(char **__user u_filename_p, char **__user uargv); +int get_su_mod_exclude(uid_t uid); +int set_su_mod_exclude(uid_t uid, int exclude); #endif diff --git a/kernel/patch/include/uapi/scdefs.h b/kernel/patch/include/uapi/scdefs.h index 19ac252..7629145 100644 --- a/kernel/patch/include/uapi/scdefs.h +++ b/kernel/patch/include/uapi/scdefs.h @@ -48,8 +48,8 @@ struct kernel_storage }; #define SUPERCALL_KSTORAGE_ALLOC_GROUP 0x1040 -#define SUPERCALL_KSTORAGE_SET 0x1041 -#define SUPERCALL_KSTORAGE_GET 0x1042 +#define SUPERCALL_KSTORAGE_WRITE 0x1041 +#define SUPERCALL_KSTORAGE_READ 0x1042 #define SUPERCALL_KSTORAGE_REMOVE 0x1043 #define SUPERCALL_KSTORAGE_REMOVE_GROUP 0x1044 diff --git a/kernel/patch/patch.c b/kernel/patch/patch.c index 44260e8..1f3d4dd 100644 --- a/kernel/patch/patch.c +++ b/kernel/patch/patch.c @@ -38,19 +38,19 @@ void before_panic(hook_fargs12_t *args, void *udata) printk("==== End KernelPatch for Kernel panic ====\n"); } +void linux_misc_symbol_init(); +void linux_libs_symbol_init(); + int resolve_struct(); int task_observer(); int bypass_kcfi(); int bypass_selinux(); int resolve_pt_regs(); int supercall_install(); -int su_compat_init(); - -void linux_misc_symbol_init(); -void linux_libs_symbol_init(); void module_init(); void syscall_init(); int kstorage_init(); +int su_compat_init(); #ifdef ANDROID int android_user_init(); diff --git a/user/supercall.h b/user/supercall.h index 1e0ab50..b285002 100644 --- a/user/supercall.h +++ b/user/supercall.h @@ -16,14 +16,6 @@ #include "uapi/scdefs.h" #include "version" -/// @deprecated -/// KernelPatch version less than 0xa05 -static inline long hash_key_cmd(const char *key, long cmd) -{ - long hash = hash_key(key); - return hash & 0xFFFF0000 | cmd; -} - /// KernelPatch version is greater than or equal to 0x0a05 static inline long ver_and_cmd(const char *key, long cmd) { @@ -31,15 +23,6 @@ static inline long ver_and_cmd(const char *key, long cmd) return ((long)version_code << 32) | (0x1158 << 16) | (cmd & 0xFFFF); } -static inline long compact_cmd(const char *key, long cmd) -{ -#if 1 - long ver = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KERNELPATCH_VER)); - if (ver >= 0xa05) return ver_and_cmd(key, cmd); -#endif - return hash_key_cmd(key, cmd); -} - /** * @brief If KernelPatch installed, @see SUPERCALL_HELLO_ECHO will echoed. * @@ -49,7 +32,7 @@ static inline long compact_cmd(const char *key, long cmd) static inline long sc_hello(const char *key) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_HELLO)); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_HELLO)); return ret; } @@ -76,7 +59,7 @@ static inline long sc_klog(const char *key, const char *msg) { if (!key || !key[0]) return -EINVAL; if (!msg || strlen(msg) <= 0) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KLOG), msg); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KLOG), msg); return ret; } @@ -89,7 +72,7 @@ static inline long sc_klog(const char *key, const char *msg) static inline uint32_t sc_kp_ver(const char *key) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KERNELPATCH_VER)); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KERNELPATCH_VER)); return (uint32_t)ret; } @@ -102,7 +85,7 @@ static inline uint32_t sc_kp_ver(const char *key) static inline uint32_t sc_k_ver(const char *key) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KERNEL_VER)); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KERNEL_VER)); return (uint32_t)ret; } @@ -118,12 +101,12 @@ static inline long sc_su(const char *key, struct su_profile *profile) { if (!key || !key[0]) return -EINVAL; if (strlen(profile->scontext) >= SUPERCALL_SCONTEXT_LEN) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU), profile); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU), profile); return ret; } /** - * @brief Substitute user of tid specfied + * @brief Substitute user of tid specfied thread * * @param key : superkey or 'su' string if caller uid is su allowed * @param tid : target thread id @@ -134,7 +117,41 @@ static inline long sc_su(const char *key, struct su_profile *profile) static inline long sc_su_task(const char *key, pid_t tid, struct su_profile *profile) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_TASK), tid, profile); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_TASK), tid, profile); + return ret; +} + +/** + * @brief + * + * @param key + * @param gid group id + * @param did data id + * @param data + * @param dlen + * @return long + */ +static inline long sc_kstorage_write(const char *key, int gid, long did, void *data, int dlen) +{ + if (!key || !key[0]) return -EINVAL; + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KSTORAGE_WRITE), gid, did, data, dlen); + return ret; +} + +/** + * @brief + * + * @param key + * @param gid + * @param did + * @param out_data + * @param dlen + * @return long + */ +static inline long sc_kstorage_read(const char *key, int gid, long did, void *out_data, int dlen) +{ + if (!key || !key[0]) return -EINVAL; + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KSTORAGE_READ), gid, did, out_data, dlen); return ret; } @@ -148,7 +165,7 @@ static inline long sc_su_task(const char *key, pid_t tid, struct su_profile *pro static inline long sc_su_grant_uid(const char *key, struct su_profile *profile) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_GRANT_UID), profile); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_GRANT_UID), profile); return ret; } @@ -162,7 +179,7 @@ static inline long sc_su_grant_uid(const char *key, struct su_profile *profile) static inline long sc_su_revoke_uid(const char *key, uid_t uid) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_REVOKE_UID), uid); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_REVOKE_UID), uid); return ret; } @@ -175,7 +192,7 @@ static inline long sc_su_revoke_uid(const char *key, uid_t uid) static inline long sc_su_uid_nums(const char *key) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_NUMS)); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_NUMS)); return ret; } @@ -191,7 +208,7 @@ static inline long sc_su_allow_uids(const char *key, uid_t *buf, int num) { if (!key || !key[0]) return -EINVAL; if (!buf || num <= 0) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_LIST), buf, num); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_LIST), buf, num); return ret; } @@ -206,7 +223,7 @@ static inline long sc_su_allow_uids(const char *key, uid_t *buf, int num) static inline long sc_su_uid_profile(const char *key, uid_t uid, struct su_profile *out_profile) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_PROFILE), uid, out_profile); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_PROFILE), uid, out_profile); return ret; } @@ -222,7 +239,7 @@ static inline long sc_su_get_path(const char *key, char *out_path, int path_len) { if (!key || !key[0]) return -EINVAL; if (!out_path || out_path <= 0) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_GET_PATH), out_path, path_len); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_GET_PATH), out_path, path_len); return ret; } @@ -237,7 +254,7 @@ static inline long sc_su_reset_path(const char *key, const char *path) { if (!key || !key[0]) return -EINVAL; if (!path || !path[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_RESET_PATH), path); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_RESET_PATH), path); return ret; } @@ -253,7 +270,7 @@ static inline long sc_su_get_all_allow_sctx(const char *key, char *out_sctx, int { if (!key || !key[0]) return -EINVAL; if (!out_sctx) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_GET_ALLOW_SCTX), out_sctx); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_GET_ALLOW_SCTX), out_sctx); return ret; } @@ -269,7 +286,7 @@ static inline long sc_su_reset_all_allow_sctx(const char *key, const char *sctx) { if (!key || !key[0]) return -EINVAL; if (!sctx) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_SET_ALLOW_SCTX), sctx); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_SET_ALLOW_SCTX), sctx); return ret; } @@ -286,7 +303,7 @@ static inline long sc_kpm_load(const char *key, const char *path, const char *ar { if (!key || !key[0]) return -EINVAL; if (!path || strlen(path) <= 0) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KPM_LOAD), path, args, reserved); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KPM_LOAD), path, args, reserved); return ret; } @@ -305,7 +322,7 @@ static inline long sc_kpm_control(const char *key, const char *name, const char if (!key || !key[0]) return -EINVAL; if (!name || strlen(name) <= 0) return -EINVAL; if (!ctl_args || strlen(ctl_args) <= 0) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KPM_CONTROL), name, ctl_args, out_msg, outlen); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KPM_CONTROL), name, ctl_args, out_msg, outlen); return ret; } @@ -321,7 +338,7 @@ static inline long sc_kpm_unload(const char *key, const char *name, void *reserv { if (!key || !key[0]) return -EINVAL; if (!name || strlen(name) <= 0) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KPM_UNLOAD), name, reserved); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KPM_UNLOAD), name, reserved); return ret; } @@ -334,7 +351,7 @@ static inline long sc_kpm_unload(const char *key, const char *name, void *reserv static inline long sc_kpm_nums(const char *key) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KPM_NUMS)); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KPM_NUMS)); return ret; } @@ -350,7 +367,7 @@ static inline long sc_kpm_list(const char *key, char *names_buf, int buf_len) { if (!key || !key[0]) return -EINVAL; if (!names_buf || buf_len <= 0) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KPM_LIST), names_buf, buf_len); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KPM_LIST), names_buf, buf_len); return ret; } @@ -367,7 +384,7 @@ static inline long sc_kpm_info(const char *key, const char *name, char *buf, int { if (!key || !key[0]) return -EINVAL; if (!buf || buf_len <= 0) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_KPM_INFO), name, buf, buf_len); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_KPM_INFO), name, buf, buf_len); return ret; } @@ -383,7 +400,7 @@ static inline long sc_skey_get(const char *key, char *out_key, int outlen) { if (!key || !key[0]) return -EINVAL; if (outlen < SUPERCALL_KEY_MAX_LEN) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SKEY_GET), out_key, outlen); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SKEY_GET), out_key, outlen); return ret; } @@ -398,7 +415,7 @@ static inline long sc_skey_set(const char *key, const char *new_key) { if (!key || !key[0]) return -EINVAL; if (!new_key || !new_key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SKEY_SET), new_key); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SKEY_SET), new_key); return ret; } @@ -412,7 +429,7 @@ static inline long sc_skey_set(const char *key, const char *new_key) static inline long sc_skey_root_enable(const char *key, bool enable) { if (!key || !key[0]) return -EINVAL; - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SKEY_ROOT_ENABLE), (long)enable); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SKEY_ROOT_ENABLE), (long)enable); return ret; } @@ -425,25 +442,25 @@ static inline long sc_skey_root_enable(const char *key, bool enable) static inline long sc_su_get_safemode(const char *key) { if (!key || !key[0]) return -EINVAL; - return syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_SU_GET_SAFEMODE)); + return syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_SU_GET_SAFEMODE)); } static inline long sc_bootlog(const char *key) { - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_BOOTLOG)); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_BOOTLOG)); return ret; } static inline long sc_panic(const char *key) { - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_PANIC)); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_PANIC)); return ret; } static inline long __sc_test(const char *key, long a1, long a2, long a3) { - long ret = syscall(__NR_supercall, key, compact_cmd(key, SUPERCALL_TEST), a1, a2, a3); + long ret = syscall(__NR_supercall, key, ver_and_cmd(key, SUPERCALL_TEST), a1, a2, a3); return ret; }