关注了就能看到更多这么棒的文章哦~

Running code within another process's address space

By Jonathan Corbet
April 16, 2021
DeepL assisted translation
https://lwn.net/Articles/852662/

描述一个进程的时候,总会提到它的关键资源之一:地址空间(address space),这是一组映射关系用来决定任意一段内存地址(memory address)在该进程中是如何使用的。通常来说地址空间对它所属的进程来说是私有的,但在有些情况下,一个进程需要对另一个进程的内存区域进行修改,比如交互式的 debugger 调试器这种情况。ptrace()系统调用使得这种行为变得可行了,但还是很慢,有时候不那么容易使用,所以长期以来人们一直在寻找其他更好的方案。Andrei Vagin 最近提出的 process_vm_exec() 供大家 review,就是希望作为一种可能的解决方案。

事实上,对于某些场景来说已经有了很好的替代 ptrace()的方案。在 2011 年,3.2 版本内核中合入了一个名为 cross-memory attach system calls 的方案,增加的系统调用名为 process_vm_readv()和 process_vm_writev()。正如它们的名字所示,它们允许一个进程从另一个进程的 memory 中进行读取和写入。这些系统调用满足了许多场景下的需求,但有时候需要对另一个进程的地址空间进行更多的访问,这时就显得不够用了。看起来除了在目标进程地址空间内运行代码之外,没有其他选择。

Vagin 的 patch set 给出了几个例子,来说明这种访问会很有用。User-mode kernel(用户模式 Linux kernel)中,比如User-mode Linux 和 gVisor,必须能够拦截由沙盒中的进程发出的系统调用,并可能需要在该进程的地址空间内运行这段代码。Checkpoint/Restore in User space(用户空间中快照以及恢复)项目需要能够深入到一个进程中来提取 checkpoint 所需的所有信息。目前这两种情况都是用 ptrace() 来处理的,但是我们希望有更好的、更快的替代品。

Vagin 提出的替代方案是一个新的系统调用:

int process_vm_exec(pid_t pid, struct sigcontext uctx, unsigned long flags,siginfo_t siginfo, sigset_t *sigmask, size_t sizemask);

调用成功的话将导致调用进程的地址空间变成 pid 指定的这个进程的地址空间。Patch 的说明邮件中指出,使用 pidfd 可能更好,但这将会使得这个系统调用与 process_vm_readv()和 process_vm_writev()不再一致了。在从新的地址空间恢复代码执行之前,uctx 中的值被用来加载处理器的寄存器(包括当前指令的指针)。这个步骤非常重要,因为在新的地址空间如果使用之前的指令指针很可能会出问题。

如果 flags 为 0,process_vm_exec()将改变地址空间,然后按照 uctx 的指示恢复执行,持续到进程进行系统调用或收到 signal 为止。这两种情况都会恢复到旧的地址空间,process_vm_exec()将终止执行并返回给调用者。siginfo 结构描述了打断另一个地址空间执行的事件是什么,如果是一个系统调用 e 的话,siginfo 会被设置成好像收到了 SIGSYS 信号一样。

相反,如果 flags 里有设置 PROCESS_VM_EXEC_SYSCALL,那么这个调用的目的是在目标进程的地址空间中调用一个系统调用。在这种情况下,uctx 应该在合适的寄存器中配置好系统调用号及其参数,就像发生过真正的系统调用一样。在系统调用的过程中,地址空间将被切换,然后在返回给调用者之前被恢复。

这组 patch 是作为一个原型来发布的,目的是希望得到大家对这种 API 反馈意见。Jann Horn 很快就回应说,这个新提出的系统调用似乎并不适合所述的应用场景,它对一个应用场景来说做了太多工作,对另一个用例来说又还不够。对于在不同的地址空间内运行代码的情况(如 User-mode Linux),他建议,不需要创建一个全新的进程,可能更好的做法是有一个系统调用来允许单独创建出新的地址空间。不过,对于 checkpoint/restore 的情况,可能仍然需要访问进程中除了地址空间之外的资源,尽管他没有明确指出这些资源可能是什么。Vagin 回应说,一个相对通用的系统调用似乎比创建多个分门别类的的系统调用要更好,哪怕这个通用系统调用并不完全适合所有应用场景。

不过,Florian Weimer 确实想到了另一种资源,会对 GNU C 库很有好处。Linux 实现 setuid()的方式和 POSIX 的要求是有区别的。Linux 只会改变当前调用线程的凭证信息(credential),而 POSIX 规定应该要改变这个进程中所有线程的凭证信息。目前,glibc 是通过向所有线程发送信号从而在 Linux 上按 POSIX 语义实现,这样它们就可以一起调用 setuid(),这种方案不是很理想。如果能在每个线程的上下文中调用 setuid(),而不用实际打断线程,那就最好了。他说,这样的功能对于实现 memory barrier 也很有用。

一方面希望创造一个在某些情况下有用的功能,另一方面又试图解决更大、更复杂的问题,这两种需求之间显然存在一些矛盾。在这种情况下,开发者必须谨慎选择他们后续的道路。如果试图做得太多,那么会非常有效地阻止其进入 mainline kernel,反而一点帮助也没有了。目前看来 process_vm_exec() 今后前景尚不清楚。它可能最终会被接受,但在这之前可能需要进行巨大的改变。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

LWN:在另一个进程的地址空间内执行代码!相关推荐

  1. 一文告诉你,如何使用Python构建一个“谷歌搜索”系统 | 内附代码

    来源 | hackernoon 编译 | 武明利 责编 | Carol 出品 | AI科技大本营(ID:rgznai100) 在这篇文章中,我将向您展示如何使用Python构建自己的答案查找系统.基本 ...

  2. 如何查询一个进程下面的线程数(进程和线程区别)

    在平时工作中,经常会听到应用程序的进程和线程的概念,那么它们两个之间究竟有什么关系或不同呢? 一.对比进程和线程 1)两者概念 -  进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程 ...

  3. Linux 内核如何描述一个进程?

    哈喽,我是吴同学,继续记录我的学习心得. 一.关于写文章 许多知识,书上或者网络上都有,就算这两个地方都没有,代码里也会有答案.但有时恰恰是 资料太多,反而让人难以检索出有用的信息. 面对同样的资料, ...

  4. linux 如何避免进程killed_Linux 内核 / 进程管理 / 如何描述一个进程?

    哈喽,我是吴同学,继续记录我的学习心得. 一.关于写文章 许多知识,书上或者网络上都有,就算这两个地方都没有,代码里也会有答案.但有时恰恰是 资料太多,反而让人难以检索出有用的信息. 面对同样的资料, ...

  5. java 进程 线程数量_如何查询一个进程下面的线程数(进程和线程区别)

    在平时工作中,经常会听到应用程序的进程和线程的概念,那么它们两个之间究竟有什么关系或不同呢? 一.对比进程和线程 1)两者概念 -  进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程 ...

  6. 【Linux】进程虚拟地址空间

    进程虚拟地址空间打破了我一直以来对于程序地址空间的认识,它真的好神奇. 我们首先来看一下下面这段代码: 1 #include<stdio.h>2 #include<unistd.h& ...

  7. 查询一个进程下面的线程及正在运行的线程

    在平时工作中,经常会听到应用程序的进程和线程的概念,那么它们两个之间究竟有什么关系或不同呢? 一.对比进程和线程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 ...

  8. 【Linux从无到有】进程的地址空间

    地址空间想必大家听的耳朵都起茧子了,栈区.堆区.静态区--其实这还有很的秘密,或许他会颠覆你的认知,那么就一起来探索吧 文章目录 进程地址空间 什么是虚拟地址空间 ? 浅谈页表 以现在的视角在看程序 ...

  9. Linux 的父进程和子进程的执行情况(附有案例代码)

    系列文章目录 该文章主要是针对面试做大致的了解,通俗易懂!!! 一.父进程.子进程的定义 1.父进程 指已创建一个或多个子进程的进程.在Linux里,除了进程0以外的所有进程都是由其他进程使用系统调用 ...

最新文章

  1. Windows内核HAL相关学习
  2. STM32串口的部分映射与完全映射
  3. 【Tools】Visual Studio 2019下载和安装
  4. python模拟购物车购物过程_Python 模拟购物车的实例讲解
  5. LeetCode 36. Valid Sudoku
  6. mvc如何嵌套第三方页面_苹果屏蔽第三方Cookie,然后呢?
  7. html给看板娘添加语音,用html代码给网页加个live2d看板娘吧
  8. 华硕电脑桌面没有计算机图标 怎么弄出来,笔记本电脑开机蓝屏没桌面图标的方法...
  9. 如何自己写一个CNV分析软件?
  10. 深度学习:GAN案例练习-minst手写数字
  11. android 手势截图,小米8手机如何截图/长截屏/手势截屏?小米8四种截图方法
  12. 华为电脑和手机一碰传_华为手机怎么一碰传连接电脑传输照片和文件
  13. 小爱同学脱离局域网远程控制开关?
  14. 基于jsp的博客系统
  15. 《千与千寻》告诉产品经理什么?
  16. 网站性能优化之DNS Prefetch
  17. Flink on Yarn报错:Container released on a *lost* node
  18. 用blockly制作诗词学习游戏
  19. 计算机手动配置信息,手动修改并设置电脑开机画面入您所愿
  20. 华为路由器接口如何区分_华为路由器的usb接口是什么意思

热门文章

  1. Unity学习笔记(四)—— 制作第三个小游戏(像模像样的)
  2. 上市公司财务报告的那点事(7):我的2017选股指南
  3. 【OpenCv】 VS C++ (零):专栏总揽与OpenCv介绍
  4. 连接电机和电调时,那三根线可以先任意顺序接
  5. 小白jenkins脱机部署日记
  6. 2022软件测试面试题 200道大厂面试真题 刷完拿到10k职位
  7. vivo手机打印不了日志_vivo手机里的log是什么意思?
  8. 金融帝国实验室(Capitalism Lab)官方中文整合包(MOD模组/专业XGQ)_v8.0.15(2022.04.03更新)
  9. one artical on pci hotplug framework
  10. Java(标识符和关键字)