Linux 内核存在本地提权漏洞(CVE-2019-8912)

栏目: 服务器 · 发布时间: 5年前

内容简介:近日,Linux git中发布一个commit补丁,该补丁对应的漏洞是一个本地提权漏洞CVE-2019-8912,漏洞影响范围较广。根据git中的commit信息可知,该漏洞出现在内核Linux内核从版本2.5开始引入了加密机制,为内核提供加密功能,应用包括:硬件加密设备驱动、内核代码签名、硬件随机数生成器、文件系统加密等。从版本2.6.6之后,内核源码提供了丰富的密码学算法支持,并可以通过配置编译选项将加密算法作为模块编入内核。内核编译配置如下图所示:

作者:启明星辰ADLab

公众号: https://mp.weixin.qq.com/s/K1clZUCZBRtKi5wx1IhTcg

一、 漏洞背景

近日,Linux git中发布一个commit补丁,该补丁对应的漏洞是一个本地提权漏洞CVE-2019-8912,漏洞影响范围较广。根据git中的commit信息可知,该漏洞出现在内核 'crypto/af_alg.c' 中的 af_alg_release 函数中,可以通过 sockfs_setattr 函数触发,漏洞类型是use after free,可以导致本地代码执行进行权限提升。

二、 漏洞影响版本

  • Linux 2 .6 ~ linux 4.20.11
  • ed Hat Enterprise Linux 7,Package: kernel-alt
  • ebian,Release:Jessie,Version:3.16.56-1+deb8u1
  • Debian,Release:Jessie (security),Version:3.16.56-1
  • Debian,Release:stretch,Version:4.9.144-3
  • Debian,Release:stretch (security),Version:4.9.110-3+deb9u6
  • Debian,Release:buster,Version:4.19.16-1
  • Debian,Release:sid,Version:4.19.20-1

三、 Linux Crypto模块简介

Linux内核从版本2.5开始引入了加密机制,为内核提供加密功能,应用包括:硬件加密设备驱动、内核代码签名、硬件随机数生成器、文件系统加密等。从版本2.6.6之后,内核源码提供了丰富的密码学算法支持,并可以通过配置编译选项将加密算法作为模块编入内核。内核编译配置如下图所示:

Linux 内核存在本地提权漏洞(CVE-2019-8912)

但是该加密功能提供的API接口只能在内核层进行使用,用户层无法调用。2010年,有位维护者向Linux Crypto维护组提交了一份Crypato API 用户接口,类似于netlink,基于socket进行通信,便于用户层访问内核加密子系统。功能实现代码在文件 crypto/af_alg.c 中。

四、 漏洞原理及溯源

漏洞存在于crypto 模块中的 af_alg_release() 函数中。 af_alg_release() 函数在进行对象释放时,未将对象置空。对应commit: 9060cb719e61b685ec0102574e10337fa5f445ea 补丁代码如下,补丁添加了一行代码: sock->sk = NULL;

Linux 内核存在本地提权漏洞(CVE-2019-8912)

在未添加补丁之前,如果该sock->sk引用计数是1,当调用sock_put()进行释放后没有置空,就直接返回,会产生一个sock->sk悬挂指针。

为了分析这个漏洞的前因后果,先分析下相关的socket代码。对每个新创建的socket,Linux内核都将在sockfs中创建一个新的inode。 Sockfs_* 系列函数就是用来操作sockfs文件系统的。 Sockfs_setattr() 函数就是设置socket文件属性的。在 net/socket.c 文件中 sockfs_setattr() 函数将会使用sock->sk对象。

根据提交的commit: 9060cb719e61b685ec0102574e10337fa5f445ea 细节可知,在该漏洞披露之前,Linux已经修复了 sock_close()sockfs_setattr() 之间的条件竞争漏洞,对应commit为 6d8c50dcb029872b298eea68cc6209c866fd3e14 ,具体先看下 sockfs_setattr() 函数中的补丁。补丁代码如下:

Linux 内核存在本地提权漏洞(CVE-2019-8912)

行544,首先判断sock->sk是否为空,如果不为空,行545再将用户层传进来的 iattr->ia_uid 赋值为 sock->sk->sk_uid 。然后看 sock_close () 函数中的补丁。补丁代码如下:

Linux 内核存在本地提权漏洞(CVE-2019-8912)

行1186,替换成了新函数 __sock_release() ,该函数多了一个参数inode。 __sock_release() 函数实现如下:

Linux 内核存在本地提权漏洞(CVE-2019-8912)

行601,对inode进行判断,如果不为空,然后调用 inode_lock() 函数对其进行上锁。其实该inode本身和要进行释放的socket对象是对应的。行603,调用ops中release()函数进行释放操作。这个ops中release()函数只是一个函数指针,最终会根据用户注册哪种套接字类型决定。行604,再次判断inode是否为空,如果不为空,再进行解锁。通过对inode加锁,防止在对socket对象释放时进行其他操作。

从commit: 6d8c50dcb029872b298eea68cc6209c866fd3e14 提供的细节可知, sock_close() 函数和 sockfs_setattr() 函数之间的条件竞争可以通过用户层fchownat()函数引发。根据man手册可知,该函数是用于设置文件属性的,例如uid和gid,在内核中对应的 sockfs_setattr() 函数,如下图所示:

Linux 内核存在本地提权漏洞(CVE-2019-8912)

细节中描述,该函数不会保持文件fd的引用计数,这也是导致存在条件竞争的原因。根据前文可知, sockfs_setattr() 函数其实就是设置UID才操作sock->sk对象的。

如果再继续向前追溯的话,从commit: 86741ec25462e4c8cdce6df2f41ead05568c7d5e 提供的细节可知UID的来龙去脉。该补丁提交于2016年。由于socket 协议中的结构体struct sock在大多时候都是和用户层的sockets一一映射的,sockets对应的内核结构体为struct socket。考虑到方便操作,便通过向struct sock添加一个sk_uid字段来简化对struct socket中的UID的匹配,也因此添加了一个关键函数。如下图所示:

Linux 内核存在本地提权漏洞(CVE-2019-8912)

由此可知,本来存在于sock_close()和sockfs_setattr之间的条件竞争已经被修复,由于 crypto/af_alg.caf_alg_release() 函数没有将释放后的sock->sk及时置空,导致前面所做的安全补丁全部失效。

五、 安全建议

目前该漏洞补丁已经给出,请及时升级到最新版本。

https://github.com/torvalds/linux/commit/9060cb719e61b685ec0102574e10337fa5f445ea

启明星辰积极防御实验室(ADLab)

ADLab成立于1999年,是中国安全行业最早成立的攻防技术研究实验室之一,微软MAPP计划核心成员,“黑雀攻击”概念首推者。截止目前,ADLab已通过CVE累计发布安全漏洞近1000个,通过 CNVD/CNNVD累计发布安全漏洞近500个,持续保持国际网络安全领域一流水准。实验室研究方向涵盖操作系统与应用系统安全研究、移动智能终端安全研究、物联网智能设备安全研究、Web安全研究、工控系统安全研究、云安全研究。研究成果应用于产品核心技术研究、国家重点科技项目攻关、专业安全服务等。

Linux 内核存在本地提权漏洞(CVE-2019-8912)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法设计与分析

算法设计与分析

张德富 / 2009-8 / 36.00元

《算法设计与分析》主要取材于算法设计与分析领域的经典内容,并介绍了算法设计的发展趋势。内容主要包括非常经典的算法设计技术,例如递归与分治、动态规划、贪心、回溯、分支限界、图算法,也包括了一些高级的算法设计主题,例如网络流和匹配、启发式搜索、线性规划、数论以及计算几何。在算法分析方面,介绍了概率分析以及最新的分摊分析和实验分析方法。在算法的理论方面,介绍了问题的下界、算法的正确性证明以及NP完全理论......一起来看看 《算法设计与分析》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具