本故事根据CPU真实漏洞改编

前情回顾

还记得我吗,我是阿Q,就是那个CPU一号车间的阿Q啊。如果你忘记了我,记得看看这里回忆一下哦:完了!CPU一味求快出事儿了!

自从我们车间用上了乱序执行分支预测后,生产效率那是大大提升,领导不仅在全厂的员工大会表扬了我们,还把这两项技术向全厂推广,在我们8个CPU核心车间都铺开了,性能甩开竞争对手CPU几条街。

可是,就在我们还沉醉在取得的成绩时,不知不觉我们竟埋下了灾难的种子······

事情还得从不久前的一个晚上说起。

神秘代码

这天晚上,我们一号车间遇到了这样一段代码:

uint8_t array1[160] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
uint8_t array2[256 * 512];
uint8_t temp = 0; void bad_guy(int x) {
if (x < 16) {
temp &= array2[array1[x] * 512];
}
}

不到一会儿功夫,我们就执行了这个bad_guy()函数很多次,这不,又来了。

负责取指令的小A向内存那家伙打了一通电话,让内存把参数x的内容传输过来,我们知道,以内存那蜗牛的速度,估计得让我们好等。

这时,负责指令译码的小胖忍不住说了:“你们看,我们这都执行这个函数好多次了,每次的参数x都是小于16的,这一次估计也差不多,要不咱们启动分支预测功能,先把小于16分支里的指令先提前做一些?大家看怎么样”

我和负责数据回写的老K互相看了一眼,都点头表示同意。

于是,就在等待的间隙,我们又给内存那家伙打了电话,让他把array1[x]的内容也传过来。

等了一会儿,数据总算传了过来:

x: 2
array1[x]: 3

拿到结果之后,我们开始一边执行x<16的比较指令,一边继续打电话给内存索要array2[3]的内容。

比较指令执行的结果不出所料,果然是true,接下来就要走入我们预测的分支,而我们提前已经将需要的数据准备到缓存中,省去了不少时间。

就这样,我们成功的预测了后续的路线,我们真是一群机智的小伙伴。

遭遇滑铁卢

天有不测风云,不久,事情发生了变化。

“呀!比较结果是false,这一次的x比16大了”,我执行完结果后发现和我们预期的有了出入。

小A闻讯而来,“额,咱们提前执行了不该执行的指令不会有问题吧?”

老K安慰道:“没事儿,咱们只是提前把数据读到了我们的缓存中,没问题的,放心好啦”

我想了想也对,大不了我们提前做的准备工作白费了,没有多想就继续去执行>16的分支指令了。

随后,同样的事情也时有发生,渐渐的我们就习惯了。

灾难降临

夜越来越深,我们都有点犯困了,突然,领导来了一通电话,让我们放下手里的工作火速去他办公室。

我们几个不敢耽误,赶紧出发。

来到领导的办公室,里面多了两个陌生人,其中一个还被绑着,领导眉头紧锁,气氛很是紧张。

“阿Q啊,你知不知道你们新发明的乱序执行分支预测技术闯了大祸了?”

我们几个一听傻眼了,“领导,这是从何说起啊?”

领导从椅子上站了起来,指着旁边的陌生人说到:“给你们介绍一下,这是操作系统那边过来的安全员,让他告诉你们从何说起吧!”

这位安全员向大家点了点头,指着被捆绑那人说道:“大家好,我们抓到这个线程在读取系统内核空间的数据,经过我们的初审,他交代了是通过你们CPU的乱序执行分支预测功能实现的这一目的。”

我和小A几个一听都是满脸问号,我们这两个提升工作效率的技术怎么就能泄漏系统内核数据呢?

真相大白

安全员显然看出了我们的疑惑,指着被捆绑的那个线程说道:“你把之前交代的再说一遍”

“几位大爷,你们之前是不是遇到了分支预测失败的情况?”,那人抬头看着我们。

“有啊,跟这有什么关系?失败了很正常嘛,既然是预测那就不能100%打包票能预测正确啊”,我回答道。

您说的没错,不过如果这个失败是我故意策划的呢?

听他这么一说,我的心一下悬了起来,“纳尼,你干的?”

“是的,就是我,我先故意给你连续多次小于16的参数,误导你们,误以为后面的参数还是小于16的,然后突然来一个特意构造的大于16的参数,你们果然上钩了,预测失败,提前执行了一些本不该执行的指令。”

“那又如何呢?我们只是把后面需要的数据提前准备到了缓存中,并没有进一步做什么啊”,我还是不太明白。

这就够了!

“你小子都被捆上了,就别吊胃口了,一次把话说清楚”,一旁急性子的老K忍不住了。

“好好好,我这就交代。你们把数据提前准备到了缓存中,我后面去访问这部分数据的时候,发现比访问其他内存快了很多”

“那可不,我们的缓存技术可不是吹牛的!哎等等,怎么又扯到缓存上去了?”,老K继续问道。

那人继续说道:“如果我想知道某个地址单元内的值,我就以它作为数组的偏移,去访问一片内存区域。利用你们会提前预测执行而且会把数据缓存的机制。你们虽然预测失败了,但对应的那一块数据已经在缓存中了,接着,我依次去访问那一片内存,看看谁的访问时间明显比其他部分短,那就知道哪一块被缓存了,再接着反推就能知道作为偏移的数值是多少了,按照这个思路我可以知道每一个地址单元的内容”

我们几个一边听着一边想着,琢磨了好一会儿总算弄清楚了这家伙的套路,老K气得火冒三丈,差点就想动手修理那人。

“好你个家伙,倒是挺聪明的,可惜都不用在正途上!好好的加速优化机制竟然成为了你们的帮凶”,我心中也有一团火气。

亡羊补牢

事情的真相总算弄清楚了,我们几个此刻已经汗流浃背。

经过和安全员的协商,操作系统那边推出了全新的KPTI技术来解决这个问题,也就是内核页表隔离

以前的时候,线程执行在用户态和内核态时用的是同一本地址翻译手册,也就是人们说的页表,通过这本手册,我们CPU就能通过虚拟地址找到真实的内存页面。

现在好了,让线程运行在用户态和内核态时使用不同的手册,用户态线程的手册中,内核地址空间部分是一片空白,来一招釜底抽薪!

本以为我们可以回去了,没想到领导却给我们出了难题,“这祸是你们闯下的,人家操作系统那边虽然做了保护,你们是不是也该拿出点办法来呢,要不然以后我们CPU还怎么抬得起头来?”

你有什么好办法吗,帮帮我们吧!

幕后

本文描述的是两年前爆发的大名鼎鼎的CPU的熔断幽灵漏洞。

乱序执行分支预测是现代处理器普遍采用的优化机制。和传统软件漏洞不同,硬件级别的漏洞影响更大更深也更难以修复。

通过判断内存的访问速度来获知是否有被缓存,这类技术有一个专门的术语叫侧信道,即通过一些场外信息来分析得出重要结论,进而达成正常途径无法达成的目的。

后面的文章中此类手法的故事还将继续上演,敬请期待!

特别鸣谢:网友几多风雨劲提供的技术支持

往期热门回顾

完了!CPU一味求快出事儿了!

哈希表哪家强?几大编程语言吵起来了!

内核地址空间大冒险4:线程切换

震撼!全网第一张源码分析全景图揭秘Nginx

一个整数+1引发的灾难

一网打尽!每个程序猿都该了解的黑客技术大汇总

看过无数Java GC文章,这5个问题你也未必知道!

一个Java对象的回忆录:垃圾回收

谁动了你的HTTPS流量?

路由器里的广告秘密

一个HTTP数据包的奇幻之旅

我是一个流氓软件线程

可怕!CPU竟成了黑客的帮凶!的更多相关文章

  1. 将Pytorch模型从CPU转换成GPU

    1. 如何进行迁移 对模型和相应的数据进行.cuda()处理.通过这种方式,我们就可以将内存中的数据复制到GPU的显存中去.从而可以通过GPU来进行运算了. 1.1 判定使用GPU 下载了对应的GPU ...

  2. CPU瞒着内存竟干出这种事

    还记得我吗,我是阿Q,CPU一号车间的那个阿Q. 今天忙里偷闲,来到厂里地址翻译部门转转,负责这项工作的小黑正忙得满头大汗. 看到我的到来,小黑指着旁边的座椅示意让我坐下. 坐了好一会儿,小黑才从工位 ...

  3. 就为了一个原子操作,其他CPU核心罢工了

    i++问题 "阿Q赶快回去吧,隔壁二号车间的虎子说我们改了他们的数据,上门来闹事了" 由于老K的突然出现,我不得不提前结束与小黑的交流,赶回了CPU一号车间. 见到我回来,虎子立刻 ...

  4. 一个神秘URL酿大祸,差点让我背锅!

    神秘URL 我叫小风,是Windows帝国一个普通的上班族.上一回说到因为一个跨域请求,我差点丢了饭碗,好在有惊无险,我的职场历险记还在继续. "叮叮叮叮~~~~",闹钟又把我给吵 ...

  5. 诸葛亮vs司马懿,排序算法大战谁能笑到最后?

    阵前对峙 公元234年,蜀汉丞相诸葛孔明再次北伐. 一日,与司马仲达所率魏军两军相峙,二人阵前舌战. 司马曰:"诸葛村夫,吾与汝相斗数年,斗兵斗阵斗谋略,均已疲乏.今日,何不一改陈规,斗点新 ...

  6. 乔治·霍兹(George Hotz):特斯拉、谷歌最可怕的对手!

    17岁破解iPhone,21岁攻陷索尼PS3:现在,他是埃隆·马斯克最可怕的对手.   黑客往事   许多年后,当乔治·霍兹(George Hotz)回首往事,一定会把2007年作为自己传奇人生的起点 ...

  7. CPU与内存的那些事

    下面是网上看到的一些关于内存和CPU方面的一些很不错的文章. 整理如下: 转: CPU的等待有多久? 原文标题:What Your Computer Does While You Wait 原文地址: ...

  8. 转:CPU与内存的那些事

    下面是网上看到的一些关于内存和CPU方面的一些很不错的文章. 整理如下: 转: CPU的等待有多久? 原文标题:What Your Computer Does While You Wait 原文地址: ...

  9. CPU与内存(经典问答)

    原文:http://www.cnblogs.com/xkfz007/archive/2012/10/08/2715163.html 下面是网上看到的一些关于内存和CPU方面的一些很不错的文章. 整理如 ...

随机推荐

  1. Websocket直播间聊天室教程 - GoEasy快速实现聊天室

    最近两年直播那个火啊,真的是无法形容!经常有朋友问起,我想实现一个直播间聊天或者我想开发一个聊天室, 要如何开始呢? 今天小编就手把手的教你用GoEasy做一个聊天室,当然也可以用于直播间内的互动.全 ...

  2. 数据结构(C语言版)---栈

    1.栈:仅在表尾进行插入和删除操作的线性表.后进先出LIFO. 1)表尾端(允许插入和删除的一端)为栈顶,表头端(不允许插入和删除的一端)为栈底. 2)入栈:插入元素的操作.出栈:删除栈顶元素 3)栈 ...

  3. Java数组 —— 八大排序

    (请观看本人博文--<详解 普通数组 -- Arrays类 与 浅克隆>) 在本人<数据结构与算法>专栏的讲解中,本人讲解了如何去实现数组的八大排序. 但是,在讲解的过程中,我 ...

  4. 12. 前后端联调 + ( proxy代理 ) + ( axios拦截器 ) + ( css Modules模块化方案 ) + ( css-loader ) + ( 非路由组件如何使用history ) + ( bodyParser,cookieParser中间件 ) + ( utility MD5加密库 ) + ( nodemon自动重启node ) + +

    (1) proxy 前端的端口在:localhost:3000后端的端口在:localhost:1234所以要在webpack中配置proxy选项 (proxy是代理的意思) 在package.jso ...

  5. Intellij IDEA 基础设置,个性化设置,好用的设置→_→

    Intellij IDEA 个性化设置 Appearance & Behavior 外观和行为 Keymap 快捷键 Editor 编辑器设置 Plugins 插件 Version Contr ...

  6. 美的PDF转换成Word转换器完全免费

    下载地址:百度网盘提取码:02ap 安装破解步骤:先安装主程序,末尾是full结尾的,安装完成后不要打开软件,然后接着安装破解补丁,即可破解成功! 需要的老铁们直接拿去用吧,亲测好用!有配套的功能强大 ...

  7. 分享一个404页面(猴子动态SVG图)

    说明 在CSDN看到的一个404界面,简洁大气非常棒我的个人网站已经用上了! 代码 防止原页面失效,代码 粘贴在下面 <!DOCTYPE html> <html lang=" ...

  8. audio的自动播放报错解决

    使用audio标签时,当前页面没有进行交互时,比如用户刷新了页面后,play()调用就会报错,如下图 查找资料后,发现是2018年4月以后,chrome浏览器对这块进行了优化,为了节约流量,禁止了自动 ...

  9. HDU 4009 Transfer water(最小树形图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4009 题意:给出一个村庄(x,y,z).每个村庄可以挖井或者修建水渠从其他村庄得到水.挖井有一个代价, ...

  10. 数据结构--顺序栈--C++实现

    #include <iostream> #define MaxSize 5000 using namespace std; template <typename T> clas ...