kernel: Undo some changes

This commit is contained in:
ShirkNeko
2025-11-09 16:09:59 +08:00
parent a0ceda008d
commit 1c86944142
6 changed files with 296 additions and 549 deletions

View File

@@ -6,7 +6,7 @@
#include "selinux.h"
#include "sepolicy.h"
#include "ss/services.h"
#include "linux/lsm_audit.h" // IWYU pragma: keep
#include "linux/lsm_audit.h"
#include "xfrm.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
@@ -141,7 +141,7 @@ void apply_kernelsu_rules(void)
// https://android-review.googlesource.com/c/platform/system/logging/+/3725346
ksu_dontaudit(db, "untrusted_app", KERNEL_SU_DOMAIN, "dir", "getattr");
mutex_unlock(&ksu_rules);
}
@@ -157,39 +157,16 @@ void apply_kernelsu_rules(void)
#define CMD_TYPE_CHANGE 8
#define CMD_GENFSCON 9
// keep it!
extern bool ksu_is_compat __read_mostly;
// armv7l kernel compat
#ifdef CONFIG_64BIT
#define usize u64
#else
#define usize u32
#endif
struct sepol_data {
u32 cmd;
u32 subcmd;
usize field_sepol1;
usize field_sepol2;
usize field_sepol3;
usize field_sepol4;
usize field_sepol5;
usize field_sepol6;
usize field_sepol7;
};
// ksud 32-bit on arm64 kernel
struct __maybe_unused sepol_data_compat {
u32 cmd;
u32 subcmd;
u32 field_sepol1;
u32 field_sepol2;
u32 field_sepol3;
u32 field_sepol4;
u32 field_sepol5;
u32 field_sepol6;
u32 field_sepol7;
uint32_t cmd;
uint32_t subcmd;
uint64_t sepol1;
uint64_t sepol2;
uint64_t sepol3;
uint64_t sepol4;
uint64_t sepol5;
uint64_t sepol6;
uint64_t sepol7;
};
static int get_object(char *buf, char __user *user_object, size_t buf_sz,
@@ -208,15 +185,18 @@ static int get_object(char *buf, char __user *user_object, size_t buf_sz,
return 0;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) || \
!defined(KSU_COMPAT_USE_SELINUX_STATE)
extern int avc_ss_reset(u32 seqno);
#else
extern int avc_ss_reset(struct selinux_avc *avc, u32 seqno);
#endif
// reset avc cache table, otherwise the new rules will not take effect if already denied
static void reset_avc_cache(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) || \
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0) || \
!defined(KSU_COMPAT_USE_SELINUX_STATE)
avc_ss_reset(0);
selnl_notify_policyload(0);
@@ -242,76 +222,55 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
pr_info("SELinux permissive or disabled when handle policy!\n");
}
u32 cmd, subcmd;
char __user *sepol1, *sepol2, *sepol3, *sepol4, *sepol5, *sepol6, *sepol7;
if (unlikely(ksu_is_compat)) {
struct sepol_data_compat data_compat;
if (copy_from_user(&data_compat, arg4, sizeof(struct sepol_data_compat))) {
pr_err("sepol: copy sepol_data failed.\n");
return -1;
}
pr_info("sepol: running in compat mode!\n");
sepol1 = compat_ptr(data_compat.field_sepol1);
sepol2 = compat_ptr(data_compat.field_sepol2);
sepol3 = compat_ptr(data_compat.field_sepol3);
sepol4 = compat_ptr(data_compat.field_sepol4);
sepol5 = compat_ptr(data_compat.field_sepol5);
sepol6 = compat_ptr(data_compat.field_sepol6);
sepol7 = compat_ptr(data_compat.field_sepol7);
cmd = data_compat.cmd;
subcmd = data_compat.subcmd;
} else {
struct sepol_data data;
if (copy_from_user(&data, arg4, sizeof(struct sepol_data))) {
pr_err("sepol: copy sepol_data failed.\n");
return -1;
}
sepol1 = data.field_sepol1;
sepol2 = data.field_sepol2;
sepol3 = data.field_sepol3;
sepol4 = data.field_sepol4;
sepol5 = data.field_sepol5;
sepol6 = data.field_sepol6;
sepol7 = data.field_sepol7;
cmd = data.cmd;
subcmd = data.subcmd;
struct sepol_data data = { 0 };
if (copy_from_user(&data, arg4, sizeof(struct sepol_data))) {
pr_err("sepol: copy sepol_data failed.\n");
return -EINVAL;
}
u32 cmd = data.cmd;
u32 subcmd = data.subcmd;
mutex_lock(&ksu_rules);
db = get_policydb();
int ret = -EINVAL;
if (cmd == CMD_NORMAL_PERM) {
switch (cmd) {
case CMD_NORMAL_PERM: {
char src_buf[MAX_SEPOL_LEN];
char tgt_buf[MAX_SEPOL_LEN];
char cls_buf[MAX_SEPOL_LEN];
char perm_buf[MAX_SEPOL_LEN];
char *s, *t, *c, *p;
if (get_object(src_buf, sepol1, sizeof(src_buf), &s) < 0) {
if (get_object(src_buf, (void __user *)data.sepol1,
sizeof(src_buf), &s) < 0) {
pr_err("sepol: copy src failed.\n");
goto exit;
}
if (get_object(tgt_buf, sepol2, sizeof(tgt_buf), &t) < 0) {
if (get_object(tgt_buf, (void __user *)data.sepol2,
sizeof(tgt_buf), &t) < 0) {
pr_err("sepol: copy tgt failed.\n");
goto exit;
}
if (get_object(cls_buf, sepol3, sizeof(cls_buf), &c) < 0) {
if (get_object(cls_buf, (void __user *)data.sepol3,
sizeof(cls_buf), &c) < 0) {
pr_err("sepol: copy cls failed.\n");
goto exit;
}
if (get_object(perm_buf, sepol4, sizeof(perm_buf), &p) <
0) {
if (get_object(perm_buf, (void __user *)data.sepol4,
sizeof(perm_buf), &p) < 0) {
pr_err("sepol: copy perm failed.\n");
goto exit;
}
bool success = false;
if (subcmd == 1) {
success = ksu_allow(db, s, t, c, p);
} else if (subcmd == 2) {
@@ -324,8 +283,9 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
pr_err("sepol: unknown subcmd: %d\n", subcmd);
}
ret = success ? 0 : -EINVAL;
} else if (cmd == CMD_XPERM) {
break;
}
case CMD_XPERM: {
char src_buf[MAX_SEPOL_LEN];
char tgt_buf[MAX_SEPOL_LEN];
char cls_buf[MAX_SEPOL_LEN];
@@ -335,25 +295,28 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
char perm_set[MAX_SEPOL_LEN];
char *s, *t, *c;
if (get_object(src_buf, sepol1, sizeof(src_buf), &s) < 0) {
if (get_object(src_buf, (void __user *)data.sepol1,
sizeof(src_buf), &s) < 0) {
pr_err("sepol: copy src failed.\n");
goto exit;
}
if (get_object(tgt_buf, sepol2, sizeof(tgt_buf), &t) < 0) {
if (get_object(tgt_buf, (void __user *)data.sepol2,
sizeof(tgt_buf), &t) < 0) {
pr_err("sepol: copy tgt failed.\n");
goto exit;
}
if (get_object(cls_buf, sepol3, sizeof(cls_buf), &c) < 0) {
if (get_object(cls_buf, (void __user *)data.sepol3,
sizeof(cls_buf), &c) < 0) {
pr_err("sepol: copy cls failed.\n");
goto exit;
}
if (strncpy_from_user(operation, sepol4,
if (strncpy_from_user(operation, (void __user *)data.sepol4,
sizeof(operation)) < 0) {
pr_err("sepol: copy operation failed.\n");
goto exit;
}
if (strncpy_from_user(perm_set, sepol5, sizeof(perm_set)) <
0) {
if (strncpy_from_user(perm_set, (void __user *)data.sepol5,
sizeof(perm_set)) < 0) {
pr_err("sepol: copy perm_set failed.\n");
goto exit;
}
@@ -369,10 +332,13 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
pr_err("sepol: unknown subcmd: %d\n", subcmd);
}
ret = success ? 0 : -EINVAL;
} else if (cmd == CMD_TYPE_STATE) {
break;
}
case CMD_TYPE_STATE: {
char src[MAX_SEPOL_LEN];
if (strncpy_from_user(src, sepol1, sizeof(src)) < 0) {
if (strncpy_from_user(src, (void __user *)data.sepol1,
sizeof(src)) < 0) {
pr_err("sepol: copy src failed.\n");
goto exit;
}
@@ -387,16 +353,20 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
}
if (success)
ret = 0;
} else if (cmd == CMD_TYPE || cmd == CMD_TYPE_ATTR) {
break;
}
case CMD_TYPE:
case CMD_TYPE_ATTR: {
char type[MAX_SEPOL_LEN];
char attr[MAX_SEPOL_LEN];
if (strncpy_from_user(type, sepol1, sizeof(type)) < 0) {
if (strncpy_from_user(type, (void __user *)data.sepol1,
sizeof(type)) < 0) {
pr_err("sepol: copy type failed.\n");
goto exit;
}
if (strncpy_from_user(attr, sepol2, sizeof(attr)) < 0) {
if (strncpy_from_user(attr, (void __user *)data.sepol2,
sizeof(attr)) < 0) {
pr_err("sepol: copy attr failed.\n");
goto exit;
}
@@ -412,11 +382,13 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
goto exit;
}
ret = 0;
} else if (cmd == CMD_ATTR) {
break;
}
case CMD_ATTR: {
char attr[MAX_SEPOL_LEN];
if (strncpy_from_user(attr, sepol1, sizeof(attr)) < 0) {
if (strncpy_from_user(attr, (void __user *)data.sepol1,
sizeof(attr)) < 0) {
pr_err("sepol: copy attr failed.\n");
goto exit;
}
@@ -425,36 +397,41 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
goto exit;
}
ret = 0;
} else if (cmd == CMD_TYPE_TRANSITION) {
break;
}
case CMD_TYPE_TRANSITION: {
char src[MAX_SEPOL_LEN];
char tgt[MAX_SEPOL_LEN];
char cls[MAX_SEPOL_LEN];
char default_type[MAX_SEPOL_LEN];
char object[MAX_SEPOL_LEN];
if (strncpy_from_user(src, sepol1, sizeof(src)) < 0) {
if (strncpy_from_user(src, (void __user *)data.sepol1,
sizeof(src)) < 0) {
pr_err("sepol: copy src failed.\n");
goto exit;
}
if (strncpy_from_user(tgt, sepol2, sizeof(tgt)) < 0) {
if (strncpy_from_user(tgt, (void __user *)data.sepol2,
sizeof(tgt)) < 0) {
pr_err("sepol: copy tgt failed.\n");
goto exit;
}
if (strncpy_from_user(cls, sepol3, sizeof(cls)) < 0) {
if (strncpy_from_user(cls, (void __user *)data.sepol3,
sizeof(cls)) < 0) {
pr_err("sepol: copy cls failed.\n");
goto exit;
}
if (strncpy_from_user(default_type, sepol4,
if (strncpy_from_user(default_type, (void __user *)data.sepol4,
sizeof(default_type)) < 0) {
pr_err("sepol: copy default_type failed.\n");
goto exit;
}
char *real_object;
if (sepol5 == NULL) {
if ((void __user *)data.sepol5 == NULL) {
real_object = NULL;
} else {
if (strncpy_from_user(object, sepol5,
if (strncpy_from_user(object,
(void __user *)data.sepol5,
sizeof(object)) < 0) {
pr_err("sepol: copy object failed.\n");
goto exit;
@@ -466,26 +443,30 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
default_type, real_object);
if (success)
ret = 0;
} else if (cmd == CMD_TYPE_CHANGE) {
break;
}
case CMD_TYPE_CHANGE: {
char src[MAX_SEPOL_LEN];
char tgt[MAX_SEPOL_LEN];
char cls[MAX_SEPOL_LEN];
char default_type[MAX_SEPOL_LEN];
if (strncpy_from_user(src, sepol1, sizeof(src)) < 0) {
if (strncpy_from_user(src, (void __user *)data.sepol1,
sizeof(src)) < 0) {
pr_err("sepol: copy src failed.\n");
goto exit;
}
if (strncpy_from_user(tgt, sepol2, sizeof(tgt)) < 0) {
if (strncpy_from_user(tgt, (void __user *)data.sepol2,
sizeof(tgt)) < 0) {
pr_err("sepol: copy tgt failed.\n");
goto exit;
}
if (strncpy_from_user(cls, sepol3, sizeof(cls)) < 0) {
if (strncpy_from_user(cls, (void __user *)data.sepol3,
sizeof(cls)) < 0) {
pr_err("sepol: copy cls failed.\n");
goto exit;
}
if (strncpy_from_user(default_type, sepol4,
if (strncpy_from_user(default_type, (void __user *)data.sepol4,
sizeof(default_type)) < 0) {
pr_err("sepol: copy default_type failed.\n");
goto exit;
@@ -502,20 +483,24 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
}
if (success)
ret = 0;
} else if (cmd == CMD_GENFSCON) {
break;
}
case CMD_GENFSCON: {
char name[MAX_SEPOL_LEN];
char path[MAX_SEPOL_LEN];
char context[MAX_SEPOL_LEN];
if (strncpy_from_user(name, sepol1, sizeof(name)) < 0) {
if (strncpy_from_user(name, (void __user *)data.sepol1,
sizeof(name)) < 0) {
pr_err("sepol: copy name failed.\n");
goto exit;
}
if (strncpy_from_user(path, sepol2, sizeof(path)) < 0) {
if (strncpy_from_user(path, (void __user *)data.sepol2,
sizeof(path)) < 0) {
pr_err("sepol: copy path failed.\n");
goto exit;
}
if (strncpy_from_user(context, sepol3, sizeof(context)) <
0) {
if (strncpy_from_user(context, (void __user *)data.sepol3,
sizeof(context)) < 0) {
pr_err("sepol: copy context failed.\n");
goto exit;
}
@@ -525,8 +510,12 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
goto exit;
}
ret = 0;
} else {
break;
}
default: {
pr_err("sepol: unknown cmd: %d\n", cmd);
break;
}
}
exit:
@@ -537,4 +526,4 @@ exit:
reset_avc_cache();
return ret;
}
}