Honggfuzz Linux arch_clone 源码阅读 (setjmp, clone)

news2024/9/23 1:22:46

Honggfuzz Linux arch_clone 源码阅读 (setjmp, clone)

阅读 Honggfuzz 系统架构相关源码,在创建子进程部分遇到了几个问题,经过研究得以解决,在此记录。

Source Code

代码节选自linux/arch.c,已添加注释,主要功能是以更细控制粒度(控制flags)创建子进程,而无参数的fork无法做到。

static uint8_t arch_clone_stack[128 * 1024] __attribute__((aligned(__BIGGEST_ALIGNMENT__)));
static __thread jmp_buf env;

HF_ATTR_NO_SANITIZE_ADDRESS
HF_ATTR_NO_SANITIZE_MEMORY
__attribute__((noreturn)) static int arch_cloneFunc(void* arg HF_ATTR_UNUSED) {
    longjmp(env, 1);
}

/* Avoid problem with caching of PID/TID in glibc */
static pid_t arch_clone(uintptr_t flags) {
    if (flags & CLONE_VM) {     // if child proc share the same VM with parent (change visible)
        LOG_E("Cannot use clone(flags & CLONE_VM)");
        return -1;
    }

    if (setjmp(env) == 0) {     // save the execution context
                                // return 0 if called directly, non-zero if indirectly (return from `longjmp`)
        void* stack_mid = &arch_clone_stack[sizeof(arch_clone_stack) / 2];
        /* Parent */
        return clone(arch_cloneFunc, stack_mid, flags, NULL, NULL, NULL);
    }
    /* Child */
    return 0;
}

Procedure

  1. arch_clone 检查flags中是否有CLONE_VM (父子进程共享同一个虚拟内存空间,相互影响),fuzz情景下不允许该方式
  2. setjmp 设置longjmp的checkpoint ,后续会介绍
  3. 如果在父进程中,就将预先分配的栈arch_clone_stack取中间点
  4. 执行glibc封装的 clone

Q & A

setjmp / longjmp

C标准库函数,用于执行"nonlocal gotos"(非本地跳转),对应goto语句的函数中跳转,longjmp允许跳转到调用栈上的任意位置,并恢复执行上下文。

通过setjmp(env)保存当前点的执行上下文信息(包括栈指针、寄存器值等)到jmp_buf类型参数env中,当执行longjmp(env, r),将恢复到env保存处的执行状态,并从那里开始执行。

具体保存的上下文内容如下所示:

setjmp

这种方法可以用于模拟C++ Exception,通过longjmp的返回值传递errno

注意:longjmp在非调用栈上的跳转行为未定义,如果执行setjmp保存上下文的函数已经返回,则不可使用longjmp恢复上下文

示例:

#include <stdio.h>
#include <setjmp.h>

jmp_buf buf;

void foo() {
	puts("In foo\n");
	longjmp(buf, 0);
	puts("foo returned normally");
	return;
}
int main() {
	
	printf("Hello world!\n");
	if (setjmp(buf) == 0) {
		printf("Start call functions!\n");
		foo();
	} else {
		puts("longjmp finish, return.");
	}
	return 0;
}
  • 程序在主函数保存了执行上下文,并跳转到foo函数执行
  • foo函数通过longjmp恢复执行流到main

过程如下,在执行setjmp前,各寄存器(主要关注栈)状态如下:

1

在执行longjmp前,各寄存器状态如下:

2

执行后,跳转到保存点,各寄存器的值也已经恢复:

在这里插入图片描述

clone stack参数

为什么需要在clone时附加stack参数呢?

  • 在使用CLONE_VM时,父子进程必不可以使用同一个栈,需要为子进程单独分配一个栈空间,这时候需要传入栈指针。

但是在这个场景下,没有使用CLONE_VM,也就不存在栈冲突的情况。这是因为代码使用了glibc封装的clone,stack参数会用于存储目标函数指针fn,返回后自动进入fn参数指定的函数。在arch_clone_func中,只用到了longjmp,恢复执行上下文,栈又恢复到了和父进程相同的状态,后续没有用到最初传入的arch_clone_stack

为什么要传入stack参数的中间部分?

  • CLONE_VM时,当父子进程共享同一个栈空间,为了避免冲突,将原有栈空间分一半使用,父子进程各占一半
  • 本场景没有启用CLONE_VM,所以笔者猜测是用于避免栈指针越过buf边界导致错误,所以取中间作为传入指针(欢迎有兴趣的读者在评论区讨论)

那么,可以不创建和使用栈吗?

理论上应当是可行的,glibc为了方便clone后的子进程进行下一步栈初始化等操作,提供了一个初始的函数fn指针。如果我们没有指定CLONE_VM,则可以用raw clone (syscall)。返回后的子进程与fork类似(实际上,fork就是clone系统调用的一个特殊情景),从调用clone的位置后继续运行。以下是manual中指明的两者的区别:

C library/kernel differences

The raw clone() system call corresponds more closely to fork(2) in that execution in the child continues from the point of the call. As such, the fn and arg arguments of the clone() wrapper function are omitted.

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

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

相关文章

RabbitMq 消息可靠性问题(一) --- publisher发送时丢失

前言 消息从生产者发送到exchange, 再到 queue, 再到消费者。这个过程中有哪些有消息丢失的可能性呢&#xff1f; 发送时丢失&#xff1a; 生产者发送的消息未送达 exchange消息到达 exchange 后未到达 queue MQ 宕机&#xff0c;queue将消息丢失consumer 接收到消息后未消费…

聊聊如何运用JAVA注解处理器(APT)

什么是APT APT&#xff08;Annotation Processing Tool&#xff09;它是Java编译期注解处理器&#xff0c;它可以让开发人员在编译期对注解进行处理&#xff0c;通过APT可以获取到注解和被注解对象的相关信息&#xff0c;并根据这些信息在编译期按我们的需求生成java代码模板或…

基于DistFlow的含分布式电源配电网优化模型【IEEE39节点】(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

SpringBoot【基础篇】---- SSMP整合综合案例

SpringBoot【基础篇】---- SSMP整合综合案例1. 模块创建2. 实体类开发3. 数据层开发----基于CRUD查看MP运行日志查看 MP 的运行日志4. 数据层开发----分页功能制作5. 数据层开发----条件查询功能制作6. 业务层开发业务层快速开发7. 表现层开发8. 表现层消息一致性处理9. 前后端…

STC32G单片机内置ADC及应用编程

一 STC32G单片机内置ADC模块简介 STC32G单片机内部集成了一个12位高速ADC转换器&#xff0c;ADC的最高时钟频率为系统频率的1/2。其输入通道多达15个&#xff08;第15通道为专门测量内部1.19V参考信号源的通道&#xff09;&#xff0c;可分时切换使用。 STC15系列单片机内置AD…

AES加密

来源&#xff1a;链接: b站up主可厉害的土豆 &#xff08;据评论区说图片中有计算错误&#xff0c;但是过程是对的。只是了解过程问题不大&#xff0c;专门研究这一块的话自己可以看视频算一下&#xff09; 准备 首先&#xff0c;明文是固定长度 16字节 128位。 密钥长度可以…

C++语法(18)---- set和map

C语法&#xff08;17&#xff09;---- 二叉搜索树_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/130174864 目录 1.set的介绍 1.set使用 1.基本结构 2.insert 3.erase 4.find 5.count 2.multiset 1.count 2.find 2.map的介绍 1.map …

zookeeper + kafka集群搭建详解

目录 1.消息队列介绍 1.为什么需要消息队列 &#xff08;MO&#xff09; 2.使用消息队列的好处 3.消息队列的两种模式 2.Kafka相关介绍 1.Kafka定义 2.Kafka简介 3. Kafka的特性 3.Kafka系统架构 1. Broker&#xff08;服务器&#xff09; 2. Topic&#xff08;一个队…

GaussDB数据库存储过程介绍

文章目录一、前言二、GaussDB中的定义三、存储过程的使用场景四、存储过程的使用优缺点五、存储过程的示例及示例解析1、GaussDB存储过程语法格式2、GaussDB存储过程语法示例3、存储过程的调用方法七、总结一、前言 华为云数据库GaussDB是一款高性能、高安全性的云原生数据库&…

链表基础知识

1.链表必知必会 什么是链表? 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是指针域&#xff08;存放指向下一个节点的指针&#xff09;&#xff0c;最后一个节点的指针域指向null&#xff08;空指针的意思&#…

23北京邮电大学备考经验

目录【写在前面】本科成绩择校历程英语复习数学复习政治复习专业课复习其它建议笔记复盘压力处理恋爱关系【写在最后】【写在前面】 初试成绩&#xff1a; 本科成绩 总体&#xff1a;浙江某双非学校的软件工程专业、综合测评成绩班级前两名、浙江省省级优秀毕业生、发表过论…

【Node】Node.js 资源汇总推荐

【导读】&#xff1a;Node.js 是一个开源、跨平台的&#xff0c;用于编写服务器和命令行的 JavaScript 运行时工具。awesome-nodejs 是sindresorhus发起维护的 Node.js 资源列表&#xff0c;内容包括&#xff1a;命令行工具、日志、调试、HTTP、构建工具、文件系统、模板、Web …

Elasticjob(2.1.4) failover 、misfire及执行线程池分析

Failover 当设置failover为true时候&#xff0c;elasticjob 集群通过zookeeper 的event watcher 监听是否有instance 丢失&#xff0c;然后对丢失instance 对应的分片进行立即执行。重复一下&#xff0c;failover是立即执行&#xff0c;不是按crontab时间来触发&#xff0c;这…

基于RDF本体模型和图数据库实现知识查询与推理

基于RDF本体模型和图数据库实现知识查询与推理 基于RDF本体模型和图数据库实现知识查询与推理一、案例本体模型解释二、数据构建与查询 Here’s the table of contents: 基于RDF本体模型和图数据库实现知识查询与推理 本文主要使用ONgDB图数据库和Neosemantics组件&#xff0c;…

自建个人音乐播放器Navidrome - 内网穿透实现在外随时访问

文章目录 1. 前言2. Navidrome网站搭建2.1 Navidrome下载和安装2.1.1 安装并添加ffmpeg2.1.2下载并配置Navidrome2.1.3 添加Navidrome到系统服务 2.2. Navidrome网页测试 3. 本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4. 公网访问测试5. 结语 转…

【Android实战开发】flutter实现网络请求的方法示例

Flutter网络请求使用的是Dio。Dio是一个强大易用的dart http请求库&#xff0c;支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载……. Flutter json数据解析是使用了json_serializable package包。它是一个自动化源代码生成器&#xff0c;可以为我们…

C++快速幂详解例题

基本概念 什么是快速幂呢&#xff1f;个人理解&#xff0c;就是更快速的计算幂运算。 比如计算a^b 刚学这个算法的时候我也很疑惑&#xff0c;幂运算不是有现成的公式么&#xff0c;直接pow&#xff08;a,b&#xff09;不就好了吗&#xff1f; 后来才明白&#xff0c;pow(a,b)的…

三分钟了解什么是时序数据库

在介绍时序数据库之前&#xff0c;我们先来看看什么是时序数据。时序数据就是基于时间排序的数据&#xff0c;再通过时间坐标将这些数据连接起来&#xff0c;形成一个折线图&#xff0c;直观地展示一个指标在过去一段时间内的走势和规律&#xff0c;帮助定位数据异常点。 时序…

Oracle中Archived redolog的生成

目录 一、问题预览 二、问题解答 一、问题预览 大家都知道 Oracle 中 online redolog切换后会生成 archived redolog&#xff0c;心里默认的就是 online redolog 切换后 archived redolog 已经生成。切换示意图&#xff0c;如下图所示。 但事实真的是这样吗&#xff1f; 二、…

C++ 23 实用工具(一)

C 23 实用工具&#xff08;一&#xff09; 工具函数是非常有价值的工具。它们不仅可以用于特定的领域&#xff0c;还可以应用于任意值和函数&#xff0c;甚至可以创建新的函数并将它们绑定到变量上。 常用函数 你可以使用各种变体的 min、max 和 minmax 函数来对值和初始化列…