程序安全补丁级别2021年11月1日是什么意思?

2021开始至今,已有众多高危网络安全漏洞披露,涉及范围及公司广泛,例如高通芯片的高危漏洞据称会影响到全球40%手机,而英特尔、AMD CPU的高危漏洞会导致数十亿计算机受影响。苹果公司,微软,和谷歌浏览器Chrome中也分别发现多个高危漏洞。除此之外国内厂商小米也披露了其MIUI系统越权漏洞预警。

高通芯片高危漏洞影响全球40%手机

5月初,高通公司的移动调制解调器MSM芯片(包括最新的支持5G的版本)中发现了一个高危安全漏洞(CVE-),攻击者可以利用该漏洞获取手机用户的短信、通话记录、监听对话甚至远程解锁SIM卡,该漏洞的利用甚至无法被常规系统安全功能检测到。

高通MSM芯片包含2G、3G、4G和5G功能的一系列片上系统(SoC),全部都存在该高危漏洞。目前全球约40%的手机都使用了MSM芯片,其中包括三星、谷歌、LG、OnePlus和小米在内的多家手机供应商的产品。该安全漏洞甚至还可使攻击者解锁移动设备的用户识别模块(SIM),后者存储着用户的网络身份验证信息和联系人信息。

为了保护自己免受利用此类漏洞或相关恶意软件的攻击,建议安卓手机用户将设备尽快更新到最新版本的安卓操作系统。此外,安全专家再次强调,用户应当从安卓官方应用商店中安装应用程序,这样能大大降低意外安装恶意应用程序的风险。

英特尔、AMD CPU再曝高危漏洞,数十亿计算机受影响

5月初,美国一组研究人员发现了一条新的攻击路线,绕过了芯片中内置的所有当前Spectre保护,可能导致几乎所有台式机、笔记本电脑、云服务器和智能手机再次像三年前一样处于危险之中。同时,5月4日,戴尔公司自曝其上亿台电脑的固件升级驱动中存在一个长达12年的漏洞(已修复)。5月6日,英特尔、AMD等处理器巨头的处理器芯片再次发现新的高危漏洞。

2018年,现代处理器中普遍存在的的熔断漏洞(Meltdown)和幽灵漏洞(Spectre)被披露时,发现该类漏洞的研究人员说:现代处理器中普遍存在的的熔断漏洞(Meltdown)和幽灵漏洞(Spectre)由于难以修复,幽灵漏洞将困扰我们相当长的时间。

3月,Microsoft Exchange Server是美国微软(Microsoft)公司的一套电子邮件服务程序。它提供邮件存取、储存、转发,语音邮件,邮件过滤筛选等功能。据悉,全球已有数十万台Exchange服务器被攻击,大量企业、政府部门被感染,超过6万家组织受影响。

成功利用漏洞的攻击者可以在目标系统中获取敏感信息、写入任意文件、执行恶意代码等。通过这些漏洞,攻击者无需身份验证或访问个人电子邮件帐户即可从Exchange服务器读取电子邮件。而通过后面的漏洞链接,攻击者则能够完全接管邮件服务器。Exchange中出现的四个零日漏洞已经被至少10个高威胁性黑客组织注意到了,这些黑客组织已经在全球100个国家以上的超过5000台服务器中安装了后门程序,从而攻击者可以简单的通过web浏览器对服务器进行远程控制。

Windows系统本地提权漏洞(2月)

本地攻击者可以利用此漏洞提升到system权限,据称此漏洞被用于定向攻击活动。漏洞相应的利用程序已经公开,有可能被改造来执行大范围的攻击,已经构成现实的威胁。目前微软已经修补了此漏洞,建议用户及时确认是否受到漏洞影响,尽快采取修补措施。另外Windows客户端远程代码执行漏洞

微软 3 月补丁日公开了 Windows DNS Server 中存在的多个远程代码执行漏洞和拒绝服务漏洞,这些漏洞都存在于 Windows DNS Server 进行动态区域更新的过程中。攻击者可通过向目标主机发送特制请求来利用这些漏洞,成功利用这些漏洞可在目标主机上以 SYSTEM 权限执行任意代码或导致 DNS 服务拒绝服务。微软官方已发布补丁修复了上述漏洞,建议用户及时确认是否受到漏洞影响,尽快采取修补措施。

简介: Linux 内核函数的热替换“撞上”函数调用约定还靠谱吗?

Linux 内核热补丁可以修复正在运行的 linux 内核,是一种维持线上稳定性不可缺少的措施,现在比较常见的比如 kpatch 和 livepatch。内核热补丁可以修复内核中正在运行的函数,用已修复的函数替换掉内核中存在问题的函数从而达到修复目的。

函数替换的思想比较简单,就是在执行旧函数时绕开它的执行逻辑而跳转到新的函数中,有一种比较简单粗暴的方式,就是将原函数的第一条指令修改为“ jump 目标函数”指令,即直接跳转到新的函数以达到替换目的。

那么,问题来了,这么做靠谱吗?直接将原函数的第一条指令修改为 jump 指令,会破坏掉原函数和它的调用者之间的寄存器上下文关系,存在安全隐患!本文会针对该问题进行探索和验证。

因此,当 funA 再次使用到 R 的数据已经是错误的数据了。如果 funA 在调用 funB 前保存寄存器 R 中的数据,funB 返回后再将数据恢复到 R 中,或者 funB 先保存 R 中原有的数据,然后在返回前恢复,就可以解决这类问题。

需要对相应的寄存器进行保存和恢复操作:

调用约定,gcc 它遵守了吗?

设问:当函数实现很简单,只用到了少量寄存器,那没使用到的还需要保存吗?

答案:it depends。根据编译选项决定。

众所周知,GCC 编译器有 -O0、-O1、-O2 和 -Ox 等编译优化选项,优化范围和深度随 x 增大而增大(-O0是不优化,其中隐含的意思是,它会严格遵循 ABI 中的调用约定,对所有使用的寄存器进行保存和恢复)。

Linux 内核选用的都是 -O2 优化。GCC 会选择性的不遵守调用约定,也就是设问里提到的,不需要保存没使用到的寄存器。

当【运行时替换】撞见【调用约定】

GCC 之所以可以做这个优化,是因为 GCC 高屋建瓴,了解程序的执行流。当它知道 callee,caller 的寄存器分配情况,就会大胆且安全地做各种优化。

但是,运行时替换破坏了这个假设,GCC 所掌握的 callee 信息,极有可能是错误的。那么这些优化可能会引发严重问题。这里以一个具体的实例进行详细说明,这是一个用户态的例子( x86_64 平台):

  • 程序解释:该程序是对输入的数字进行计算,运行时利用 jump 指令将程序中的函数 b 替换为 newb 函数,即,将 y = x + x 计算过程替换为 y = x + (2x) ^ 3 * x;
  • 程序编译:gcc test.c -o test -O2,这里我们采用的是与编译内核相同的优化选项 -O2;
  • 程序执行:./test,输入参数:4,输出结果:2056;
  • 程序错误:2056 是错误的结果,应该是 2052,而且直接调用 newb 函数编译执行的结果是 2052。

该例子说明,直接使用 jump 指令替换函数在 -O2 的编译优化下,会出现问题,安全性受到了质疑和冲击!!!

上述例子中,我们将函数 b 用 jump 指令替换为 newb 函数,在 -O2 的编译优化下出现了计算错误的结果,因此,我们需要对函数的调用执行过程进行仔细分析,挖掘问题所在。首先,我们先来查看一下该程序的反汇编(指令:objdump -d test),并重点关注 a、b 和 newb 函数:


图2 -O2 编译优化的反汇编结果

(注意:b 函数中没有对 edi 寄存器进行写操作,而且它的代码段被修改为 jump 指令跳转到 newb 函数)

数据出错的原因在于,在函数 newb 中,使用到了 a 函数中使用的 edi 寄存器,edi 寄存器中的值在 newb 函数中被修改为 8,当 newb 函数返回后,edi 的值仍然是 8,a 函数继续使用了该值,因此,计算过程变为:8^3 4 + 8 = 2056,而正确的计算结果应该是 8^3 4 + 4 = 2052。

接下来不进行编译优化(-O0),其输出结果是正确的 2052,反汇编如下所示:


图3 不进行编译优化的反汇编

从反汇编中可以看到,函数 a 在调用 b 函数前,将 edi 寄存器的值存在了栈上,调用之后,将栈上的数据再取出,最后进行相加。这就说明,-O2 优化选项将 edi 寄存器的保存和恢复操作优化掉了,而在调用约定中,edi 寄存器本就该属于 caller 进行保存/恢复的。至于为什么编译器会进行优化,我们此刻的猜想是:

a 函数本来调用的是 b 函数,而且编译器知道 b 函数中没有使用到 edi 寄存器,因此调用者 a 函数没有对该寄存器进行保存和恢复操作。但是编译器不知道的是,在程序运行时,b 函数的代码段被动态修改,利用 jump 指令替换为 newb 函数,而在 newb 函数中对 edi 寄存器进行了数据读写操作,于是出现了错误。

这是一个典型的没有保存 caller-save 寄存器导致数据出错的场景。而编译内核采用的也是 -O2 选项。如果将该场景应用到内核函数热替换是否会出现这类问题呢?于是,我们带着问题继续探索。

我们构造了一个内核函数热替换的实例,将上面的用户态的例子移植到我们构造的场景中,通过内核模块修改原函数的代码段,用 jump 指令直接替换原来的 b 函数。然而加载模块后,结果是正确的 2052,经过反汇编我们发现,内核中 a 函数对 edi 寄存器进行了保存操作:


图4 内核中 a 函数的反汇编

内核和模块编译时采用的是 -O2 优化选项,而此处 a 函数并没有被优化,仍然保存了 edi 寄存器。

此时我们预测:对于内核函数的热替换来说,使用 jump 做函数替换是安全的。

我们猜想是否是内核编译时使用其它的编译选项导致问题不能复现。果不其然,经过探索我们发现内核编译使用的 -pg 选项导致问题不再复现。

通过翻阅 GCC 手册得知,-pg 选项是为了支持 GNU 的 gprop 性能分析工具所引入的,它能在函数中增加一条 call mount 指令,去做一些分析工作。

与本文主题没有关联,不再细说。

为了验证这个结论,我们回到上一节的用户态例子,并且增加了 -pg 编译选项:“gcc test.c -o test -O2 -pg”,此时运行结果果然正确了。查看其反汇编:


图6 增加 -pg 选项后的汇编

可以看到,每个函数都有 call mcount 指令,而且 a 函数中将 edi 寄存器保存到 ebx 中,在 newb 函数中又保存 ebx 寄存器。为什么在增加了 call mount 指令后,会做寄存器的保存操作?我们猜想,会不会是因为,由于 call mount 操作相当于调用了一个未知的函数( mcount 没有定义在同一个文件中),因此,GCC 认为这样未知的操作可能会污染了寄存器的数据,所以它才进行了保存现场的操作。

经过编译:gcc test.c mcount.c -O2 后运行,发现计算结果正确,而且反汇编中 a 函数保存了寄存器:

继续验证猜想,将 mcount 函数放在 test.c 文件中,计算结果错误,而且,反汇编中没有保存寄存器,于是我们得到了这样的猜想结论:

  • GCC 在编译某个源文件时,如果文件内的某个函数(比如场景中的函数 a)调用了其它文件中的一个未知函数(比如场景中的 mcount 函数),则 GCC 会在该函数中保存寄存器;
  • 开启 -pg 选项,增加了对 mcount 的调用,因此会在函数中增加对寄存器现场的保存操作,对 -O2 选项的函数调用优化起到了屏蔽作用。

神秘的 -fipa-ra 选项:真正的幕后主使

经过我们的探索和资料的查阅,发现了这个 -fipa-ra 选项,可以说它是优化的幕后主使。GCC 手册中给出 -fipa-ra 选项的解释是:

这里主要是说,如果开启这个选项,那么,callee 中如果没有使用到 caller 使用的寄存器,就没有必要保存这些寄存器,前提是,callee 与 caller 在同一个编译单元中而且 callee 函数比 caller 先被编译,这样才可能出现前面的优化。如果开启了 -O2 及以上的编译优化选项,则会使能 -fipa-ra 选项,然而,如果开启了 -p 或者 -pg 这些选项,或者,无法明确 callee 所使用的寄存器,-fipa-ra 选项会被禁用。

这段话,其实已经能 cover 掉我们前面大部分猜想的测试验证:

  • -O2 选项自动使能 -fipa-ra 进行优化:在我们的场景中,函数 a 使用的 edi 寄存器,在函数 b 中没有使用到,因此函数 a 被优化,没有保存 edi 寄存器,但是在 newb 函数中,使用到了 edi 寄存器,且数据被修改,将 newb 函数替换函数 b,则计算结果出错;
  • 在 -O2 中使用 -pg 选项会禁用 -fipa-ra:编译时使用 -pg 选项,计算结果是正确的,而且函数 a 保存了 edi 寄存器,说明没有对函数 a 进行优化;
  • 不在同一编译单元不会被优化:去掉 -pg 选项,在函数 a 中手动调用 mcount 函数,将这个函数放在 test.c(与函数 a 为同一编译单元)与放在另一个文件 mcount.c(不同编译单元)中的计算结果不同:同一编译单元中计算结果是错误的,而且函数 a 没有保存寄存器现场;不在同一编译单元中,计算结果是正确的,函数 a(caller) 保存了寄存器现场,因为编译器无法明确函数 b(callee)所使用的寄存器。

notrace:它是二度冲击吗?

字面上来看,notrace 和 -pg 的含义可以说完全对立,-pg 让 jump 变得安全,是否又会在 notrace 上栽一个跟斗呢?幸运的是,我们接下来将看到,notrace 仅仅是禁止了 instrument function,而没有破坏安全性。

gcc 手册中的 -pg 选项给出这样的解释:

这里主要是说,加上 notrace 属性的函数,不会产生调用 mcount 的行为,那么,是否意味着不再保护寄存器现场,换句话说,notrace 的出现是否会绕过“-pg 选项对 -fipa-ra 优化的屏蔽”?于是我们又增加 notrace 属性进行验证:在 a 函数中增加 notrace 的属性,因为 a 函数是 caller,编译时开启 -pg 选项,然后检查计算结果及反汇编,最后发现,计算结果正确,而且汇编代码中保存了寄存器现场。

我们又对所有的函数追加了 notrace 属性,计算结果正确且寄存器现场被保护。但是这些简单的验证不足以证明,于是我们通过阅读 GCC 源码发现:


图10 gcc 处理每一个函数时都会检查 -fipa-rq 选项,如果为 false,则不对函数进行优化

通过源码阅读,可以确定的是,当使用了 -pg 选项后,会禁用 -fipa-rq 优化选项,GCC 检查每一个函数的时候都会检查该选项,如果为 false,则不会对该函数进行优化。

由于 flag_ipa_ra 是一个全局选项,并不是函数粒度的,notrace 也无能为力。因此,这里可以排除对 notrace 的顾虑。

经过上述的探索分析以及官方资料的查阅,我们可以得出结论:

  • 内核函数的热替换,利用 jump 指令直接跳转到新函数的方式是安全的;

通过翻阅手册得知,ARMv8 ABI 中对过程调用时通用寄存器的使用准则如下

可见,ARMv8 ABI 中对函数调用时的寄存器使用有了明确的规定。

我们对于前面 x86-64 下的探索验证过程在 arm64 平台下重新做了测试,相同的代码和相同的测试过程,得出的结论和 x86-64 下的结论是一致的,即,在 arm64 下,直接利用 jump 指令实现函数替换同样是安全的。

其它语言不能保证其安全性

对于 C 语言而言,在不同的架构和系统下都有固定的 ABI 和 calling conventions,但是其它的语言不能保证,比如 rust 语言,rust 自身并没有固定的 ABI,比如社区对 rust 定义 ABI 的讨论,而且 rustc 编译器的优化和 gcc 可能会有不同,因此可能也会出现上述 caller/callee-save 寄存器的问题。

kpatch 利用的是 ftrace 进行函数替换的,它的原理如下所示:

ftrace 的主要作用是用来做 trace 的,会在函数头部或者尾部 hook 一个函数进行一些额外的处理,这些函数在运行过程中可能会污染被 trace 的函数的寄存器上下文,因此 ftrace 定义了一个 trampoline 进行寄存器的保存和恢复操作(图11 中的红框),这样从 hook 函数回来后,寄存器现场仍然是原来的模样。

kpatch 用 ftrace 进行函数替换,hook 的函数是 kpatch 中的函数,该函数的作用是修改 regs 中的 ip 字段的值,也就是将新函数的地址给到了 ip 字段,等 trampoline 恢复寄存器现场后,就直接跳转到新的函数函数去执行了。所以,对于 kpatch 而言,ftrace 的保存和恢复现场操作保护的是 kpatch 中修改 ip 字段函数的过程,而不是它要替换的新函数。

如果修复的是一个热函数,那么 ftrace 的 trampoline 会对性能产生一定的影响。所以,若考虑到性能的场景,那么使用 jump 指令直接替换函数可以很大的减少额外的性能开销。

邓二伟(扶风),2020 年就职于阿里云操作系统内核研发团队,目前从事 linux 内核研发工作。

吴一昊(丁缓),2017 年加入阿里云操作系统团队,主要经历有资源隔离、热升级、调度器 SLI 等。

陈善佩(雏雁),高级技术专家,兴趣方向包括:体系结构、调度器、虚拟化、内存管理。

讨论这么热烈,怎么能少了组织沉淀?Cloud Kernel SIG 盛情邀请你的加入

云内核 (Cloud Kernel) 是一款定制优化版的内核产品,在 Cloud Kernel 中实现了若干针对云基础设施和产品而优化的特性和改进功能,旨在提高云端和云下客户的使用体验。与其他 Linux 内核产品类似,Cloud Kernel 理论上可以运行于几乎所有常见的 Linux 发行版中。

在 2020 年,云内核项目加入 OpenAnolis 社区大家庭,OpenAnolis 是一个开源操作系统社区及系统软件创新平台,致力于通过开放的社区合作,推动软硬件及应用生态繁荣发展,共同构建云计算系统技术底座。


本文为阿里云原创内容,未经允许不得转载。

北京时间7月9日,据国外媒体报道,微软于今天发布了2008年7月的安全公告,4个补丁均为“严重”级别,没有“高危”级别。此次受影响的产品是Windows域名服务、Windows Vista系统中的Windows Explorer、Outlook Web Access和Microsoft SQL服务器。

2008用户。这一更新修复了CVE-和CVE-中存在的漏洞。该补丁修改了Windows中的域名系统。微软表示,域名服务器的客户端和服务器上均存在这两个漏洞,这可能导致远程攻击者将网络信息转移至自己的系统。

此安全公告题为“Windows Explorer中存在的漏洞可导致远程执行代码(950582)”。这个补丁涉及Windows Vista和Windows Server 2008的用户,而其它版本的Windows用户则不受影响。这一更新修复了CVE-中存在的漏洞。微软表示:“一旦攻击者将搜索文件有意打开并保存下来,那么Windows Explorer中存在的这一漏洞就可能导致攻击者远程执行代码。如果用户使用管理员权限登录,那么成功利用这一漏洞的攻击者就可以完全攻击受影响系统并安装程序,还可以查看、修改或删除数据,并能创建拥有所有用户权限的新账户。而使用权限较小的账户登录的用户受到的影响相对会较小。”

Server的用户。这一更新修复了CVE-中存在的问题。微软表示:“成功利用这些漏洞的攻击者可以完全进入用户的Outlook Web Access客户会议数据,并提升权限。之后,攻击者可以实施用户在OWA会议数据内可实施的任何行为。”

SP2的用户。这一更新修复了CVE-、CVE-、CVE-和CVE-中存在的问题。微软表示,这一补丁修复了四个秘密发现的漏洞。如果漏洞严重,这可导致攻击者执行代码,进而完全控制受影响系统。之后,经认证的攻击者即可安装程序,查看、修改或删除数据,并能创建拥有所有用户权限的新账户。


我要回帖

更多关于 补丁级别什么意思 的文章