欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

CVE-2019-9213——linux内核用户空间0虚拟地址映射漏洞分析

来源:本站整理 作者:佚名 时间:2019-03-15 TAG: 我要投稿


 
0x00 漏洞原理
前一段时间project zero的jann horn披露了一个linux内核用户空间0虚拟地址映射漏洞,通过这个漏洞可以绕过mmap_min_addr的限制,再配合一个内核中的null pointer dereference漏洞理论上有提权的可能。这个漏洞是非常有趣的,这里分享一下我的分析。
POC很短,我们直接来看POC:

触发漏洞的点在于LD_DEBUG=help su 1>&%d向/proc/self/mem中写入了数据,其实LD_DEBUG=help su并不重要,重要的是通过它调用write函数。下面我们就来一步一步分析从这行代码到漏洞点的过程。
linux内核对于文件系统通用的结构体是file_operations,fs/proc/base.c中的代码提供与/proc相关的操作。

LD_DEBUG=help su 1>&%d会调用write函数,在这里也就是mem_write函数。mem_write函数是对mem_rw函数的封装。

在while循环中,如果是写首先通过copy_from_user函数将待写内容buf拷贝到分配的page中,然后调用access_remote_vm函数写入远程进程。读则相反,先调用access_remote_vm函数读取远程进程中的数据,然后调用copy_to_user函数将读取的page拷贝到buf中。

access_remote_vm函数是对__access_remote_vm函数的封装(这里注意分析mmap.c中的代码,nommu.c中的代码是用在没有MMU的CPU上的)。

在__access_remote_vm函数的while循环中调用get_user_pages_remote函数,get_user_pages_remote函数和get_user_pages函数都是对__get_user_pages_locked函数的封装,作用在于查找并将给定的虚拟地址范围固定到page。之后通过kmap函数将page映射到永久内存映射区,如果是写操作则调用copy_to_user_page函数之后调用set_page_dirty_lock函数将page设置为脏,读操作则调用copy_from_user_page函数。之后调用kunmap函数取消映射。

get_user_pages_remote函数和get_user_pages函数的区别在于是否跨进程。get_user_pages_remote函数调用__get_user_pages_locked函数时设置了FOLL_REMOTE标志区分。

__get_user_pages_locked函数在for循环中首先调用__get_user_pages函数将start 开始的nr_pages个页固定到pages,返回成功固定的页的个数。

__get_user_pages函数首先查找vma,调用follow_page_mask函数查询页表获取虚拟地址对应的物理页,如果返回null会调用faultin_page函数。获取到page的指针之后存在pages数组中。

__get_user_pages函数返回值大于0说明调用成功,减少nr_pages增加pages_done,nr_pages为0则退出循环。

再固定一个页,正常情况下应该返回0退出循环,如果没有退出循环nr_pages减1,pages_done加1,start地址加一个PAGE_SIZE重新开始固定。

__get_user_pages函数查找vma是通过调用find_extend_vma函数实现的,如果vma->vm_start

expand_stack函数是对expand_downwards函数的封装。

expand_downwards函数中做的首先就是调用security_mmap_addr函数检查权限。

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载