gpt4 book ai didi

linux - fork 一个新的 Linux 进程并重置所有属性。属性是 fds、信号处理程序和 task_struct 中的所有其他内容

转载 作者:太空宇宙 更新时间:2023-11-04 10:19:16 24 4
gpt4 key购买 nike

TL;DR 如何在不继承所有属性(文件描述符、内存映射、工作目录、花哨的新内核功能、... ) 来自 parent ?


在 Linux 系统上创建新进程的两种传统方式是 forkclone . libc 包装器是原始系统调用的非常薄的包装器 forkclone .查看所有其他 syscalls (忽略 vfork),似乎没有其他系统调用产生新进程。

对于这个问题,让我们将 过程定义为创建一个新的task_struct。在内核中。

问题 1) forkvforkclone 是创建新进程的唯一系统调用是否正确? (考虑内核 4.x)

进程具有属性,即存储在 task_struct 中的所有内容。我选择了在 execve 中使用的名称“attributes”手册页。属性包括文件描述符、信号处理程序、seccomp 上下文、功能、内存映射、完整的虚拟内存设置……Linux 程序可能会将文件描述符泄露给它们的子程序,这是一个存在十年之久的问题。但是由于 forkclone 复制了父级的 task_struct,泄漏的不仅仅是文件描述符:即所有内容。

让我们定义一个新鲜进程作为一个新进程,其中所有进程属性都不是从父进程继承的,而是选择合理的默认值。例如,pwd 是用户的家,除了 0、1、2 之外没有文件描述符被继承,没有映射的内存区域,使用了一个新的堆栈,...

问题 2)是否有可能在 Linux 上通过一个系统调用获得一个全新进程?

问题 3)是否有可能只通过一个系统调用在某些 BSD 或 POSIX 系统上获得一个进程?

我的问题背后的意图是我不想向我的 child 泄露任何信息。但是 Linux 会不时地向 task_struct 添加新的属性。我不想在用户空间中清理,因为清理将取决于内核版本。另外,我想用一种高级语言创建一个新的进程,例如 Haskell,其中运行时(不在我的控制之下)已经用许多属性污染了父进程。这也取决于语言运行时的版本。简而言之,我不知道在用户空间中使用了哪些属性以及需要清理哪些属性。

从安全的角度来看,我对新进程的想法听起来很危险:Linux 依赖于 seccomp 过滤器和功能边界集始终传递给子进程的概念。这意味着,进程不能通过创建新进程来增加其权限。一个全新的过程会颠覆这个安全概念。

问题 4)在 Linux 上获得全新进程的最佳方式是什么(可能在用户空间中进行一些清理)?

问题 5) 问题 4 是否有不同的答案取决于我是否要在新的新鲜进程中 execve

最佳答案

Question 4) What is the best way to get a fresh process on Linux (possibly with some cleanup in the userspace)?

其中一种方法是在程序的最开始创建一个特殊进程(在打开文件、更改信号处理程序等之前)。然后您可以将此进程用作工厂,要求它为您创建新进程。

因为工厂进程是最开始创建的,所以会是“新鲜进程”,它创建的进程也会是“新鲜的”。

但是这样你就无法克服安全方面的问题。另一方面,正是为了无法克服的目的才需要安全。

顺便说一下,Linux 内核本身使用特殊线程(“kthreadd”)来创建内核线程。

这种方法的缺点是新进程将具有相同的启动函数。但是您希望新进程的堆栈是“新鲜的”,不是吗?

Question 5) Are there different answers to Question 4 depending on whether I want to execve in the new fresh process?

execve() 本身创建了几乎全新的进程。从字面上看,它继承自父只打开的文件描述符。但我不知道有什么简单的方法可以自动关闭 child 中的这些描述符。

关于linux - fork 一个新的 Linux 进程并重置所有属性。属性是 fds、信号处理程序和 task_struct 中的所有其他内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44596109/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com