在init 进程中,初始化调用到了selinux_initialize,这里就决定了selinux 开关
system/core/init/init.cpp
main-->
selinux_initialize(true);
总结:开启与关闭selinux, 在android 系统中修改ALLOW_PERMISSIVE_SELINUX
system/core/init/Android.mk(Android.bp 也要有对应的修改)
手动操作开启关闭:
echo 0 > /sys/fs/selinux/enforce----> 关闭selinux (setenforce 0 等价)
echo 1 > /sys/fs/selinux/enforce ----> 开启selinux (setenforce 1 等价)
下面是具体原理分析:
static void selinux_initialize(bool in_kernel_domain) {
Timer t;
selinux_callback cb;
cb.func_log = selinux_klog_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
if (in_kernel_domain) {
LOG(INFO) << "Loading SELinux policy";
if (!selinux_load_policy()) {
panic();
}
//security_getenforce()----》备注 1:默认配置是 enforce 是1
bool kernel_enforcing = (security_getenforce() == 1);
bool is_enforcing = selinux_is_enforcing();-----》 备注 2:由android mk,bp配置
if (kernel_enforcing != is_enforcing) {
if (security_setenforce(is_enforcing)) {----》备注 3:根据返回值is_enforcing 设定
PLOG(ERROR) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false");
security_failure();
}
}
std::string err;
if (!WriteFile("/sys/fs/selinux/checkreqprot", "0", &err)) {
LOG(ERROR) << err;
security_failure();
}
// init's first stage can't set properties, so pass the time to the second stage.
setenv("INIT_SELINUX_TOOK", std::to_string(t.duration().count()).c_str(), 1);
} else {
selinux_init_all_handles();
}
}
备注 1
external/selinux/libselinux/src/getenforce.c
security_getenforce
int security_getenforce(void)
{
int fd, ret, enforce = 0;
char path[PATH_MAX];
char buf[20];
if (!selinux_mnt) {
errno = ENOENT;
return -1;
}
// 这里对应了开发板 android 系统文件是: /sys/fs/selinux/enforce
snprintf(path, sizeof path, "%s/enforce", selinux_mnt);
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return -1;
memset(buf, 0, sizeof buf);
ret = read(fd, buf, sizeof buf - 1);
close(fd);
if (ret < 0)
return -1;
if (sscanf(buf, "%d", &enforce) != 1)
return -1;
return !!enforce; ---->默认是1
}
备注 2
static bool selinux_is_enforcing(void)
{
if (ALLOW_PERMISSIVE_SELINUX) {
return selinux_status_from_cmdline() == SELINUX_ENFORCING;
//selinux_status_from_cmdline --->这里取cmdlines 中参数, boot中不配置可以完全由上层的android mk ,bp文件中的ALLOW_PERMISSIVE_SELINUX 控制开启与关闭
}
return true;
}
system/core/init/Android.mk(Android.bp 也要有对应的修改)
ALLOW_PERMISSIVE_SELINUX:
......
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
init_options += \
-DALLOW_LOCAL_PROP_OVERRIDE=1 \
-DALLOW_PERMISSIVE_SELINUX=1 \----》userdebug 版本 permissive
-DREBOOT_BOOTLOADER_ON_PANIC=1 \
-DDUMP_ON_UMOUNT_FAILURE=0
else
init_options += \
-DALLOW_LOCAL_PROP_OVERRIDE=0 \
-DALLOW_PERMISSIVE_SELINUX=1 \----》user 版本 permissive
-DREBOOT_BOOTLOADER_ON_PANIC=0 \
-DDUMP_ON_UMOUNT_FAILURE=0
endif
......
备注 3:
实际就操作节点:/sys/fs/selinux/enforce
external/selinux/libselinux/src/setenforce.c
security_setenforce
int security_setenforce(int value)
{
int fd, ret;
char path[PATH_MAX];
char buf[20];
if (!selinux_mnt) {
errno = ENOENT;
return -1;
}
snprintf(path, sizeof path, "%s/enforce", selinux_mnt);
fd = open(path, O_RDWR | O_CLOEXEC);
if (fd < 0)
return -1;
snprintf(buf, sizeof buf, "%d", value);
ret = write(fd, buf, strlen(buf));
close(fd);
if (ret < 0)
return -1;
return 0;
}
遇到的问题 : 系统开发过程中, userdebug 系统运行正常, 可是在build user 版本系统无法运行,最后发现使用与userdebug 一样的selinux 权限就可以
网友评论