ASLR在Windows与Linux系统之间的差别

作者 Taskiller

Hi 基友们,我在上篇文章中讨论了Linux平台上NX的特性。我们已经知道一般情况下NX(Windows平台上称其为DEP)和地址空间分布随机化(ASLR)会同时工作,所以也值得看一下ASLR在Linux平台是如何工作的。事实证明,Linux上ASLR的实现与Windows上的有些显著的差异。

在Windows平台,ASLR不会影响运行时的性能,只是会拖慢模块加载的速度。根据文档《Windows ISVSoftware Security Defenses》的描述,要使Windows上的程序或库兼容ASLR特性,只需要在链接时添加了/DYNAMICBASE选项。

通常情况下,ASLR不会影响性能,在某些运行32位系统的场景中甚至会有一些性能提高。但是在运行比较慢的系统中,当有很多图片需要加载到随机地址时,可能会产生卡顿现象。因为要考虑图像的数据和大小等因素,我们很难量化ASLR对性能的影响。但是其对堆或栈随机化的性能影响可以说是微乎其微的。

因此,我们当然没有理由在链接时不使用/DYNAMICBASE选项来启用ASLR了。启用/DYNAMICBASE后,模块的加载地址是随机的,也就没那么容易受到ROP(ReturnOriented Programming)攻击了。所以我们建议所有Windows应用程序在编译时都启用DEP和ASLR,以及其它在文档《Windows ISV Software Security Defenses》中指出的所有安全属性。如果程序在编译时没有使用/DYNAMICBASE选项,用户也可以通过使用微软的EMET强制其启用ASLR。

在Linux平台,ASLR会给系统带来性能损耗,这种损耗在x86架构上尤其大,也最容易被感知。要使Linux程序在运行时兼容ASLR,其在编译时必须指定PIE(PositionIndependent Executable)选项。根据论文《Toomuch PIE is bad for performance》[PDF],“我们的分析显示,32位的x86系统上过量的PIE会带来高于基准26%的性能开销,而一般平均开销(统计数据)为10%左右。

大概是由于这种潜在的性能损失,Linux发行版并没有对所有可执行文件启用PIE特性。例如,在Ubuntu系统上,“在拥有少量寄存器的架构上(如x86)PIE有较大(5%-10%)性能损耗,所以这种特性只用于那些事关安全的重要的软件包……”

RedHat系统也持类似观点:

Fedora工程指导委员会(The Fedora Engineering Steering Committee)维护着一个保守的软件包列表,这个列表中的软件在编译时必须使用GCC的安全特性。不在这个列表中的软件,其安全特性在软件包的描述中启用。目前对哪些二进制程序需要使用这些安全增强特性还没有达成一个共识,因此这种程序的使用也就成了一个有争议的话题。大多数争论可以简单概括为使用这些安全特性带来的性能损耗是否值得。

既然ASLR的目标是使可执行程序在执行时位于一个不可预知的地址,为什么Windows上与Linux上的实现会有这么大的差别呢?很重要的一点是Windows上的ASLR是一个链接时(link-time)选项,而在Linux上是一个编译时(compile-time)选项。

在Windows上,代码在运行时因重定位才被patch。但在Linux与Unix的世界,该技术被称为text重定位。在Linux上,ASLR用不同的方式实现,除了在代码运行时patch,其在编译时就用某种方式使其地址无关。也就是说,可以将其加载到内存地址的任意位置,都可以正常运行。

至少在x86平台,这种地址无关功能是通过一个通用寄存器实现的,而程序少用一个寄存器就无法正常运行了。这种限制在寄存器少的架构上最明显,如x86平台。

为什么Linux开发者选择使用这种技术实现ASLR?在大多数情况下,安全其实就是一种权衡。由于text重定位涉及到patching,加载这种模块会触发“写时拷贝(copy-on-write)”,因此增加了系统的内存占用。地址无关代码不需要patching,因此不会触发“写时拷贝”。要了解Linux上地址无关代码的实现细节,以及其与加载时(load-time)重定位的比较,可以参考Eli Bendersky的博文:《PositionIndependent Code (PIC) in shared libraries》。

对大多数Linux用户来说这意味着什么?

1.在大部分Linux发行版上,ASLR并不像在Windows系统上那么普遍。
2.在Linux系统上没办法强制启用ASLR特性,但在Windows上用EMET可以做到。

读者需要了解的是,随着时间的推移,该特性在x86架构上正变得没那么重要了。因为地址无关代码不会使x86_64架构产生明显性能损耗,因为x86_64几乎有两倍于x86架构的寄存器,而且与x86架构不同,x86_64架构支持PC相关的地址策略,可以使系统对ASLR的使用几乎变得无处不在。

感谢The Pax Team对本文提供的信息。

[via cert]

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2014-03-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程

高级运维工程师学习路线

信息安全公益宣传,信息安全知识启蒙。 ? 运维工程师在前期是一个很苦逼的工作,在这期间可能干着修电脑、掐网线、搬机器的活,显得没地位!时间也很碎片化,各种零碎...

60070
来自专栏数据和云

数据库高可用和分区解决方案-MySQL 篇

许春植(Luocs) (阿里巴巴高级数据库管理员,7年以上数据库运维管理经验,擅长MySQL、Oracle及MongoDB数据库,目前主要研究并建设Mongo...

56560
来自专栏编程软文

程序员常用软件,你用了哪些

30950
来自专栏架构师小秘圈

日订单50万级分布式事务

作者:伈情,喜玩Java、Python、Golang!热爱架构设计、SOA、微服务、高并发、分布式、性能优化、DevOps、大数据、消息队列等....!在互联网...

99980
来自专栏腾讯Bugly的专栏

微信文件微起底

微信大家都在用,但微信的本地文件到底隐藏着什么样的信息呢?我们怎么可以把长得都一样的微信,变的跟别人的不一样,来个专业定制 100 年呢?这个是一个让大家的微信...

34440
来自专栏zingpLiu

海量日志实时收集系统架构设计与go语言实现

日志收集系统应该说是到达一定规模的公司的标配了,一个能满足业务需求、运维成本低、稳定的日志收集系统对于运维的同学和日志使用方的同学都是非常nice的。然而这时理...

15420
来自专栏Java架构师学习

一文归纳总结分布式架构的那些事!

进入十一月,最火热的话题与期待的日子自然是双十一狂欢购物节了,作为程序员的你除了要清空自己的购物车之外,最关心的是不是双十一架构技术是如何承受亿级用户流量的冲击...

13940
来自专栏编程一生

架构必会的性能指标及分析策略

13620
来自专栏MoeLove

高效 Bash 使用技巧

我们在日常使用中,难免会使用到一些历史命令或者有时需要对历史命令进行更正,那么如何更加高效的来完成这些操作呢?

10220
来自专栏CDA数据分析师

Python程序员都会喜欢的6个库,拿走不谢!

在编程时,小挫折可能与大难题一样令人痛苦。没人希望在费劲心思之后,只是做到弹出消息窗口或是快速写入数据库。因此,程序员都会喜欢那些能够快速处理这些问题,同时长远...

22150

扫码关注云+社区

领取腾讯云代金券