* Cherry-picked range: (kernel)
ebea31daa8..6915b62b9a
* Also merged unmerged pr:
https://github.com/tiann/KernelSU/pull/ 2909
Co-authored-by: Ylarod <me@ylarod.cn>
Co-authored-by: 5ec1cff <56485584+5ec1cff@users.noreply.github.com>
Co-authored-by: backslashxx <118538522+backslashxx@users.noreply.github.com>
Co-authored-by: u9521 <63995396+u9521@users.noreply.github.com>
Co-authored-by: Wang Han <416810799@qq.com>
185 lines
3.8 KiB
C
185 lines
3.8 KiB
C
#include "linux/cred.h"
|
|
#include "linux/sched.h"
|
|
#include "linux/security.h"
|
|
#include "linux/version.h"
|
|
#include "selinux_defs.h"
|
|
#include "../klog.h" // IWYU pragma: keep
|
|
|
|
#define KERNEL_SU_DOMAIN "u:r:su:s0"
|
|
|
|
static int transive_to_domain(const char *domain)
|
|
{
|
|
struct cred *cred;
|
|
struct task_security_struct *tsec;
|
|
u32 sid;
|
|
int error;
|
|
|
|
cred = (struct cred *)__task_cred(current);
|
|
|
|
tsec = cred->security;
|
|
if (!tsec) {
|
|
pr_err("tsec == NULL!\n");
|
|
return -1;
|
|
}
|
|
|
|
error = security_secctx_to_secid(domain, strlen(domain), &sid);
|
|
if (error) {
|
|
pr_info("security_secctx_to_secid %s -> sid: %d, error: %d\n",
|
|
domain, sid, error);
|
|
}
|
|
if (!error) {
|
|
tsec->sid = sid;
|
|
tsec->create_sid = 0;
|
|
tsec->keycreate_sid = 0;
|
|
tsec->sockcreate_sid = 0;
|
|
}
|
|
return error;
|
|
}
|
|
|
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0)
|
|
bool __maybe_unused
|
|
is_ksu_transition(const struct task_security_struct *old_tsec,
|
|
const struct task_security_struct *new_tsec)
|
|
{
|
|
static u32 ksu_sid;
|
|
char *secdata;
|
|
u32 seclen;
|
|
bool allowed = false;
|
|
|
|
if (!ksu_sid)
|
|
security_secctx_to_secid(KERNEL_SU_DOMAIN,
|
|
strlen(KERNEL_SU_DOMAIN), &ksu_sid);
|
|
|
|
if (security_secid_to_secctx(old_tsec->sid, &secdata, &seclen))
|
|
return false;
|
|
|
|
allowed = (!strcmp("u:r:init:s0", secdata) && new_tsec->sid == ksu_sid);
|
|
security_release_secctx(secdata, seclen);
|
|
return allowed;
|
|
}
|
|
#endif
|
|
|
|
|
|
void setup_selinux(const char *domain)
|
|
{
|
|
if (transive_to_domain(domain)) {
|
|
pr_err("transive domain failed.\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
void setenforce(bool enforce)
|
|
{
|
|
__setenforce(enforce);
|
|
}
|
|
|
|
bool getenforce(void)
|
|
{
|
|
if (is_selinux_disabled()) {
|
|
return false;
|
|
}
|
|
|
|
return __is_selinux_enforcing();
|
|
}
|
|
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) && \
|
|
!defined(KSU_COMPAT_HAS_CURRENT_SID)
|
|
/*
|
|
* get the subjective security ID of the current task
|
|
*/
|
|
static inline u32 current_sid(void)
|
|
{
|
|
const struct task_security_struct *tsec = current_security();
|
|
|
|
return tsec->sid;
|
|
}
|
|
#endif
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 14, 0)
|
|
struct lsm_context {
|
|
char *context;
|
|
u32 len;
|
|
};
|
|
|
|
static int __security_secid_to_secctx(u32 secid, struct lsm_context *cp)
|
|
{
|
|
return security_secid_to_secctx(secid, &cp->context, &cp->len);
|
|
}
|
|
static void __security_release_secctx(struct lsm_context *cp)
|
|
{
|
|
security_release_secctx(cp->context, cp->len);
|
|
}
|
|
#else
|
|
#define __security_secid_to_secctx security_secid_to_secctx
|
|
#define __security_release_secctx security_release_secctx
|
|
#endif
|
|
|
|
bool is_task_ksu_domain(const struct cred *cred)
|
|
{
|
|
struct lsm_context ctx;
|
|
bool result;
|
|
if (!cred) {
|
|
return false;
|
|
}
|
|
const struct task_security_struct *tsec = __selinux_cred(cred);
|
|
if (!tsec) {
|
|
return false;
|
|
}
|
|
int err = __security_secid_to_secctx(tsec->sid, &ctx);
|
|
if (err) {
|
|
return false;
|
|
}
|
|
result = strncmp(KERNEL_SU_DOMAIN, ctx.context, ctx.len) == 0;
|
|
__security_release_secctx(&ctx);
|
|
return result;
|
|
}
|
|
|
|
bool is_ksu_domain(void)
|
|
{
|
|
current_sid();
|
|
return is_task_ksu_domain(current_cred());
|
|
}
|
|
|
|
bool is_context(const struct cred *cred, const char *context)
|
|
{
|
|
if (!cred) {
|
|
return false;
|
|
}
|
|
const struct task_security_struct *tsec = __selinux_cred(cred);
|
|
if (!tsec) {
|
|
return false;
|
|
}
|
|
struct lsm_context ctx;
|
|
bool result;
|
|
int err = __security_secid_to_secctx(tsec->sid, &ctx);
|
|
if (err) {
|
|
return false;
|
|
}
|
|
result = strncmp(context, ctx.context, ctx.len) == 0;
|
|
__security_release_secctx(&ctx);
|
|
return result;
|
|
}
|
|
|
|
bool is_zygote(const struct cred *cred)
|
|
{
|
|
return is_context(cred, "u:r:zygote:s0");
|
|
}
|
|
|
|
bool is_init(const struct cred *cred)
|
|
{
|
|
return is_context(cred, "u:r:init:s0");
|
|
}
|
|
|
|
#define KSU_FILE_DOMAIN "u:object_r:ksu_file:s0"
|
|
|
|
u32 ksu_get_ksu_file_sid(void)
|
|
{
|
|
u32 ksu_file_sid = 0;
|
|
int err = security_secctx_to_secid(
|
|
KSU_FILE_DOMAIN, strlen(KSU_FILE_DOMAIN), &ksu_file_sid);
|
|
if (err) {
|
|
pr_info("get ksufile sid err %d\n", err);
|
|
}
|
|
return ksu_file_sid;
|
|
}
|