|
|
|
@@ -91,7 +91,7 @@ void apply_kernelsu_rules()
|
|
|
|
ksu_allow(db, "init", "adb_data_file", "file", ALL);
|
|
|
|
ksu_allow(db, "init", "adb_data_file", "file", ALL);
|
|
|
|
ksu_allow(db, "init", "adb_data_file", "dir", ALL); // #1289
|
|
|
|
ksu_allow(db, "init", "adb_data_file", "dir", ALL); // #1289
|
|
|
|
ksu_allow(db, "init", KERNEL_SU_DOMAIN, ALL, ALL);
|
|
|
|
ksu_allow(db, "init", KERNEL_SU_DOMAIN, ALL, ALL);
|
|
|
|
|
|
|
|
|
|
|
|
// we need to umount modules in zygote
|
|
|
|
// we need to umount modules in zygote
|
|
|
|
ksu_allow(db, "zygote", "adb_data_file", "dir", "search");
|
|
|
|
ksu_allow(db, "zygote", "adb_data_file", "dir", "search");
|
|
|
|
|
|
|
|
|
|
|
|
@@ -150,29 +150,39 @@ void apply_kernelsu_rules()
|
|
|
|
#define CMD_TYPE_CHANGE 8
|
|
|
|
#define CMD_TYPE_CHANGE 8
|
|
|
|
#define CMD_GENFSCON 9
|
|
|
|
#define CMD_GENFSCON 9
|
|
|
|
|
|
|
|
|
|
|
|
// maximal is 7!!
|
|
|
|
// keep it!
|
|
|
|
#if defined(CONFIG_KSU_64BIT) && defined(CONFIG_64BIT)
|
|
|
|
extern bool ksu_is_compat __read_mostly;
|
|
|
|
#define usize_val u64
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#define usize_val u32
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if !defined(CONFIG_KSU_64BIT) && defined(CONFIG_64BIT)
|
|
|
|
// armv7l kernel compat
|
|
|
|
#define declare_char(a, x) char __user a = compat_ptr(x)
|
|
|
|
#ifdef CONFIG_64BIT
|
|
|
|
|
|
|
|
#define usize u64
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
#define declare_char(a, x) char __user a = x
|
|
|
|
#define usize u32
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
struct sepol_data {
|
|
|
|
struct sepol_data {
|
|
|
|
u32 cmd;
|
|
|
|
u32 cmd;
|
|
|
|
u32 subcmd;
|
|
|
|
u32 subcmd;
|
|
|
|
usize_val sepol1;
|
|
|
|
usize field_sepol1;
|
|
|
|
usize_val sepol2;
|
|
|
|
usize field_sepol2;
|
|
|
|
usize_val sepol3;
|
|
|
|
usize field_sepol3;
|
|
|
|
usize_val sepol4;
|
|
|
|
usize field_sepol4;
|
|
|
|
usize_val sepol5;
|
|
|
|
usize field_sepol5;
|
|
|
|
usize_val sepol6;
|
|
|
|
usize field_sepol6;
|
|
|
|
usize_val sepol7;
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static int get_object(char *buf, char __user *user_object, size_t buf_sz,
|
|
|
|
static int get_object(char *buf, char __user *user_object, size_t buf_sz,
|
|
|
|
@@ -219,23 +229,42 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
pr_info("SELinux permissive or disabled when handle policy!\n");
|
|
|
|
pr_info("SELinux permissive or disabled when handle policy!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct sepol_data data;
|
|
|
|
u32 cmd, subcmd;
|
|
|
|
if (copy_from_user(&data, arg4, sizeof(struct sepol_data))) {
|
|
|
|
char __user *sepol1, *sepol2, *sepol3, *sepol4, *sepol5, *sepol6, *sepol7;
|
|
|
|
pr_err("sepol: copy sepol_data failed.\n");
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
declare_char(*ptr1, data.sepol1);
|
|
|
|
|
|
|
|
declare_char(*ptr2, data.sepol2);
|
|
|
|
|
|
|
|
declare_char(*ptr3, data.sepol3);
|
|
|
|
|
|
|
|
declare_char(*ptr4, data.sepol4);
|
|
|
|
|
|
|
|
declare_char(*ptr5, data.sepol5);
|
|
|
|
|
|
|
|
declare_char(*ptr6, data.sepol6);
|
|
|
|
|
|
|
|
declare_char(*ptr7, data.sepol7);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
u32 cmd = data.cmd;
|
|
|
|
|
|
|
|
u32 subcmd = data.subcmd;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rcu_read_lock();
|
|
|
|
rcu_read_lock();
|
|
|
|
|
|
|
|
|
|
|
|
struct policydb *db = get_policydb();
|
|
|
|
struct policydb *db = get_policydb();
|
|
|
|
@@ -248,22 +277,22 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
char perm_buf[MAX_SEPOL_LEN];
|
|
|
|
char perm_buf[MAX_SEPOL_LEN];
|
|
|
|
|
|
|
|
|
|
|
|
char *s, *t, *c, *p;
|
|
|
|
char *s, *t, *c, *p;
|
|
|
|
if (get_object(src_buf, ptr1, sizeof(src_buf), &s) < 0) {
|
|
|
|
if (get_object(src_buf, sepol1, sizeof(src_buf), &s) < 0) {
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (get_object(tgt_buf, ptr2, sizeof(tgt_buf), &t) < 0) {
|
|
|
|
if (get_object(tgt_buf, sepol2, sizeof(tgt_buf), &t) < 0) {
|
|
|
|
pr_err("sepol: copy tgt failed.\n");
|
|
|
|
pr_err("sepol: copy tgt failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (get_object(cls_buf, ptr3, sizeof(cls_buf), &c) < 0) {
|
|
|
|
if (get_object(cls_buf, sepol3, sizeof(cls_buf), &c) < 0) {
|
|
|
|
pr_err("sepol: copy cls failed.\n");
|
|
|
|
pr_err("sepol: copy cls failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (get_object(perm_buf, ptr4, sizeof(perm_buf), &p) <
|
|
|
|
if (get_object(perm_buf, sepol4, sizeof(perm_buf), &p) <
|
|
|
|
0) {
|
|
|
|
0) {
|
|
|
|
pr_err("sepol: copy perm failed.\n");
|
|
|
|
pr_err("sepol: copy perm failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
@@ -293,24 +322,24 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
char perm_set[MAX_SEPOL_LEN];
|
|
|
|
char perm_set[MAX_SEPOL_LEN];
|
|
|
|
|
|
|
|
|
|
|
|
char *s, *t, *c;
|
|
|
|
char *s, *t, *c;
|
|
|
|
if (get_object(src_buf, ptr1, sizeof(src_buf), &s) < 0) {
|
|
|
|
if (get_object(src_buf, sepol1, sizeof(src_buf), &s) < 0) {
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (get_object(tgt_buf, ptr2, sizeof(tgt_buf), &t) < 0) {
|
|
|
|
if (get_object(tgt_buf, sepol2, sizeof(tgt_buf), &t) < 0) {
|
|
|
|
pr_err("sepol: copy tgt failed.\n");
|
|
|
|
pr_err("sepol: copy tgt failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (get_object(cls_buf, ptr3, sizeof(cls_buf), &c) < 0) {
|
|
|
|
if (get_object(cls_buf, sepol3, sizeof(cls_buf), &c) < 0) {
|
|
|
|
pr_err("sepol: copy cls failed.\n");
|
|
|
|
pr_err("sepol: copy cls failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(operation, ptr4,
|
|
|
|
if (strncpy_from_user(operation, sepol4,
|
|
|
|
sizeof(operation)) < 0) {
|
|
|
|
sizeof(operation)) < 0) {
|
|
|
|
pr_err("sepol: copy operation failed.\n");
|
|
|
|
pr_err("sepol: copy operation failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(perm_set, ptr5, sizeof(perm_set)) <
|
|
|
|
if (strncpy_from_user(perm_set, sepol5, sizeof(perm_set)) <
|
|
|
|
0) {
|
|
|
|
0) {
|
|
|
|
pr_err("sepol: copy perm_set failed.\n");
|
|
|
|
pr_err("sepol: copy perm_set failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
@@ -330,7 +359,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
} else if (cmd == CMD_TYPE_STATE) {
|
|
|
|
} else if (cmd == CMD_TYPE_STATE) {
|
|
|
|
char src[MAX_SEPOL_LEN];
|
|
|
|
char src[MAX_SEPOL_LEN];
|
|
|
|
|
|
|
|
|
|
|
|
if (strncpy_from_user(src, ptr1, sizeof(src)) < 0) {
|
|
|
|
if (strncpy_from_user(src, sepol1, sizeof(src)) < 0) {
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -350,11 +379,11 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
char type[MAX_SEPOL_LEN];
|
|
|
|
char type[MAX_SEPOL_LEN];
|
|
|
|
char attr[MAX_SEPOL_LEN];
|
|
|
|
char attr[MAX_SEPOL_LEN];
|
|
|
|
|
|
|
|
|
|
|
|
if (strncpy_from_user(type, ptr1, sizeof(type)) < 0) {
|
|
|
|
if (strncpy_from_user(type, sepol1, sizeof(type)) < 0) {
|
|
|
|
pr_err("sepol: copy type failed.\n");
|
|
|
|
pr_err("sepol: copy type failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(attr, ptr2, sizeof(attr)) < 0) {
|
|
|
|
if (strncpy_from_user(attr, sepol2, sizeof(attr)) < 0) {
|
|
|
|
pr_err("sepol: copy attr failed.\n");
|
|
|
|
pr_err("sepol: copy attr failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -374,7 +403,7 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
} else if (cmd == CMD_ATTR) {
|
|
|
|
} else if (cmd == CMD_ATTR) {
|
|
|
|
char attr[MAX_SEPOL_LEN];
|
|
|
|
char attr[MAX_SEPOL_LEN];
|
|
|
|
|
|
|
|
|
|
|
|
if (strncpy_from_user(attr, ptr1, sizeof(attr)) < 0) {
|
|
|
|
if (strncpy_from_user(attr, sepol1, sizeof(attr)) < 0) {
|
|
|
|
pr_err("sepol: copy attr failed.\n");
|
|
|
|
pr_err("sepol: copy attr failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -391,28 +420,28 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
char default_type[MAX_SEPOL_LEN];
|
|
|
|
char default_type[MAX_SEPOL_LEN];
|
|
|
|
char object[MAX_SEPOL_LEN];
|
|
|
|
char object[MAX_SEPOL_LEN];
|
|
|
|
|
|
|
|
|
|
|
|
if (strncpy_from_user(src, ptr1, sizeof(src)) < 0) {
|
|
|
|
if (strncpy_from_user(src, sepol1, sizeof(src)) < 0) {
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(tgt, ptr2, sizeof(tgt)) < 0) {
|
|
|
|
if (strncpy_from_user(tgt, sepol2, sizeof(tgt)) < 0) {
|
|
|
|
pr_err("sepol: copy tgt failed.\n");
|
|
|
|
pr_err("sepol: copy tgt failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(cls, ptr3, sizeof(cls)) < 0) {
|
|
|
|
if (strncpy_from_user(cls, sepol3, sizeof(cls)) < 0) {
|
|
|
|
pr_err("sepol: copy cls failed.\n");
|
|
|
|
pr_err("sepol: copy cls failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(default_type, ptr4,
|
|
|
|
if (strncpy_from_user(default_type, sepol4,
|
|
|
|
sizeof(default_type)) < 0) {
|
|
|
|
sizeof(default_type)) < 0) {
|
|
|
|
pr_err("sepol: copy default_type failed.\n");
|
|
|
|
pr_err("sepol: copy default_type failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
char *real_object;
|
|
|
|
char *real_object;
|
|
|
|
if (ptr5 == NULL) {
|
|
|
|
if (sepol5 == NULL) {
|
|
|
|
real_object = NULL;
|
|
|
|
real_object = NULL;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (strncpy_from_user(object, ptr5,
|
|
|
|
if (strncpy_from_user(object, sepol5,
|
|
|
|
sizeof(object)) < 0) {
|
|
|
|
sizeof(object)) < 0) {
|
|
|
|
pr_err("sepol: copy object failed.\n");
|
|
|
|
pr_err("sepol: copy object failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
@@ -431,19 +460,19 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
char cls[MAX_SEPOL_LEN];
|
|
|
|
char cls[MAX_SEPOL_LEN];
|
|
|
|
char default_type[MAX_SEPOL_LEN];
|
|
|
|
char default_type[MAX_SEPOL_LEN];
|
|
|
|
|
|
|
|
|
|
|
|
if (strncpy_from_user(src, ptr1, sizeof(src)) < 0) {
|
|
|
|
if (strncpy_from_user(src, sepol1, sizeof(src)) < 0) {
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
pr_err("sepol: copy src failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(tgt, ptr2, sizeof(tgt)) < 0) {
|
|
|
|
if (strncpy_from_user(tgt, sepol2, sizeof(tgt)) < 0) {
|
|
|
|
pr_err("sepol: copy tgt failed.\n");
|
|
|
|
pr_err("sepol: copy tgt failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(cls, ptr3, sizeof(cls)) < 0) {
|
|
|
|
if (strncpy_from_user(cls, sepol3, sizeof(cls)) < 0) {
|
|
|
|
pr_err("sepol: copy cls failed.\n");
|
|
|
|
pr_err("sepol: copy cls failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(default_type, ptr4,
|
|
|
|
if (strncpy_from_user(default_type, sepol4,
|
|
|
|
sizeof(default_type)) < 0) {
|
|
|
|
sizeof(default_type)) < 0) {
|
|
|
|
pr_err("sepol: copy default_type failed.\n");
|
|
|
|
pr_err("sepol: copy default_type failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
@@ -464,15 +493,15 @@ int handle_sepolicy(unsigned long arg3, void __user *arg4)
|
|
|
|
char name[MAX_SEPOL_LEN];
|
|
|
|
char name[MAX_SEPOL_LEN];
|
|
|
|
char path[MAX_SEPOL_LEN];
|
|
|
|
char path[MAX_SEPOL_LEN];
|
|
|
|
char context[MAX_SEPOL_LEN];
|
|
|
|
char context[MAX_SEPOL_LEN];
|
|
|
|
if (strncpy_from_user(name, ptr1, sizeof(name)) < 0) {
|
|
|
|
if (strncpy_from_user(name, sepol1, sizeof(name)) < 0) {
|
|
|
|
pr_err("sepol: copy name failed.\n");
|
|
|
|
pr_err("sepol: copy name failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(path, ptr2, sizeof(path)) < 0) {
|
|
|
|
if (strncpy_from_user(path, sepol2, sizeof(path)) < 0) {
|
|
|
|
pr_err("sepol: copy path failed.\n");
|
|
|
|
pr_err("sepol: copy path failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (strncpy_from_user(context, ptr3, sizeof(context)) <
|
|
|
|
if (strncpy_from_user(context, sepol3, sizeof(context)) <
|
|
|
|
0) {
|
|
|
|
0) {
|
|
|
|
pr_err("sepol: copy context failed.\n");
|
|
|
|
pr_err("sepol: copy context failed.\n");
|
|
|
|
goto exit;
|
|
|
|
goto exit;
|
|
|
|
@@ -495,4 +524,4 @@ exit:
|
|
|
|
reset_avc_cache();
|
|
|
|
reset_avc_cache();
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|