selinux与kernel 0day
selinux与kernel 0day
usr/src/debug/kernel-2.6.18/linux-2.6.18.i686/security/dummy.c:
static int dummy_file_mmap_addr (struct file *file, unsigned long reqprot,
unsigned long prot,
unsigned long flags,
unsigned long addr,
unsigned long addr_only)
{
if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
return -EACCES;
return 0;
}
mmap_min_addr代表了用户能映射的最小内存地址, 它在/proc/sys/vm/mmap_min_addr进行设置。这里还要对当前进程的CAP_SYS_RAWIO能力做个判断, 就是说如果进程有这个能力的话, 不管mmap_min_addr的值是多大,都可以满足用户的需求, 当然就可以映射0地址了。 那么这跟selinux有什么关系呢? 进程在被执行的时候,尤其是调用了execve这个函数, 进程的权能是需要重新来计算的,在selinux开启的时候, selinux是LSM的第一验证模块, 看下它是怎么计算进程在被execve后的权能的:
void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
{
/* Derived from fs/exec.c:compute_creds. */
kernel_cap_t new_permitted, working;
new_permitted = cap_intersect (bprm->cap_permitted, cap_bset);
working = cap_intersect (bprm->cap_inheritable,
current->cap_inheritable);
new_permitted = cap_combine (new_permitted, working);
if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
!cap_issubset (new_permitted, current->cap_permitted)) {
current->mm->dumpable = suid_dumpable;
if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
if (!capable(CAP_SETUID)) {
bprm->e_uid = current->uid;
bprm->e_gid = current->gid;
}
if (!capable (CAP_SETPCAP)) {
new_permitted = cap_intersect (new_permitted,
current->cap_permitted);
}
}
}
current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = current->fsgid = bprm->e_gid;
/* For init, we want to retain the capabilities set
* in the init_task struct. Thus we skip the usual
* capability rules */
if (current->pid != 1) {
current->cap_permitted = new_permitted;
current->cap_effective =
cap_intersect (new_permitted, bprm->cap_effective);
}
/* AUD: Audit candidate if current->cap_effective is set */
current->keep_capabilities = 0;
}
我们看到如果当前进程不是init进程的话, 权能还是会被继承下来的。
在selinux关闭的时候, capabiliy模块成为了LSM的第一验证模块, 看下它是怎么计算的:
static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
{
if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
current->mm->dumpable = suid_dumpable;
if ((unsafe & ~LSM_UNSAFE_PTRACE_CAP) && !capable(CAP_SETUID)) {
bprm->e_uid = current->uid;
bprm->e_gid = current->gid;
}
}
current->suid = current->euid = current->fsuid = bprm->e_uid;
current->sgid = current->egid = current->fsgid = bprm->e_gid;
dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted);
}
static int dummy_capget (struct task_struct *target, kernel_cap_t * effective,
kernel_cap_t * inheritable, kernel_cap_t * permitted)
{
*effective = *inheritable = *permitted = 0;
if (!issecure(SECURE_NOROOT)) {
if (target->euid == 0) {
*permitted |= (~0 & ~CAP_FS_MASK);
*effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK);
}
if (target->fsuid == 0) {
*permitted |= CAP_FS_MASK;
*effective |= CAP_FS_MASK;
}
}
return 0;
}
注意看这行:
*effective = *inheritable = *permitted = 0;
selinux将当前进程的权能全部清0了, 所以excve后的普通进程是没有任何权能的。 也就没有了CAP_SYS_RAWIO权能,也就不能映射0内存了。 所以想阻止NULL pointer kernel 0day的攻击,最好把selinux关掉,或升级到最新的内核版本。 同时把mmap_min_addr的值设为大于4096。
最新文章
- Validate Binary Search Tree
- SQL Server 视图修改后有错怎么办?
- 如何在64位的Windows中安裝PLSQLDEVELOPER 8
- Spring中的mappingResources和mappingDirectoryLocations
- ubuntu java jdk安装及环境变量设置
- RSA算法原理(二)
- python编程快速上手之第3章实践项目参考答案
- javascript 正則表達式补充
- 201621123050 《Java程序设计》第14周学习总结
- Android Studio Gradle 多渠道自动打包,动态修改HostUrl,签名apk,混淆配置详解
- python学习笔记(十 三)、网络编程
- Ubuntu 16 桌面版使用笔记
- entity framework 缓存干扰的数据不一致问题
- element-table中使用checkbox
- php_admin_value open_basedir 引起的上传文件失败解决方法
- 部署OpenStack问题汇总(六)-- OpenStack入门需要知道的概念
- JMeter连接数据库(查询出的数据作为参数)
- 动画js版本
- 【原】Maven解决Jar包冲突
- [20] 鼓状物(Drum)图形的生成算法
热门文章
- SAP内表查询速度优化实例-OPEN SQL
- java虚拟机规范(se8)——class文件格式(四)
- System.Net.Mail.SmtpException:不允许使用邮箱名称.
- 从前端角度出发有哪些注意事项有利于SEO?
- 基于Windows 7(本地)和CentOS7.6(云端)的Minecraft服务器(无Forge/有Forge)搭建方法
- MVC默认提供了一个异常过滤器 HandleErrorAttribte特性
- nmap使用笔记
- 【leetcode】924.Minimize Malware Spread
- 【leetcode】757. Set Intersection Size At Least Two
- js浮点解决