是linux fork不安全

时间:2015-07-13 17:01:06

标签: linux security linux-kernel exec fork

我正在阅读此article

它说fork创建了自己的副本,fork man也这样说

  

。父级的整个虚拟地址空间将复制到子级

这是否意味着子进程可以读取我的所有进程内存状态?

子进程可以转储整个父内存状态,并且可以对其进行分析以提取父变量及其值。吗

但该文章还说,两个进程无法准备好彼此的数据。 所以我很困惑?

2 个答案:

答案 0 :(得分:4)

是的,子进程可以在fork(2)之后读取所有父进程状态的原始副本(但在写入时,只影响其自己的地址空间)。但是,大多数情况下,孩子最终会使用execve(2)来启动一个新程序,这将“清除”并替换原始父母的地址空间的副本(通过新的地址空间)。请注意,execvemmap(2)(另请参阅shared memory中的shm_overview(7) ...)是更改address spacevirtual memory的常用方法一些process(以及内核如何处理page faults)。

内核使用(并设置MMU)lazy copy on write机制来使子地址空间成为父项的地址空间的副本,因此fork在实践中非常有效。

另请阅读proc(5),然后输入以下命令:

cat /proc/self/maps
cat /proc/$$/maps
sudo cat /proc/1/maps

并了解正在发生的事情

另请阅读fork上的wikipage和Advanced Linux Programming本书。

没有不安全因素,因为如果孩子正在更改某些数据(例如变量,堆或堆栈位置......),它不会影响父进程。

如果执行fork的程序在某个虚拟内存位置保留了一些密码,则子进程只要执行相同的程序就能读取该位置。一旦孩子成功execve(这是常见情况,以及任何shell正在做的事情),之前的地址空间就会消失并被新的地址空间取代,在ELF可执行文件中描述{ {1}} - ed program。

Unix模型中没有“谎言”或“不安全”。但与其他几个操作系统相反,Unix& POSIX有两个单独的system calls用于创建新进程(exec)和执行新程序(fork)。其他系统可能会混合两种能力进行单spawn次操作。 posix_spawn通常由execve& fork(以及system(3)popen(3)也是如此,同时使用waitpid(2)& execve ....)。

这种Unix方法(已经分开/bin/sh& fork)的优点是在execve之后和孩子fork之前你可以做很多事情有用的东西(例如关闭无用的文件描述符,......)。不分离这两个特征的操作系统可能需要具有相当复杂的产生原语。

在极少数情况下execve 后跟一些fork。一些MPI实现可能会这样做,您也可以这样做。但是你知道你能够通过你自己的副本阅读所有父母的地址空间 - 所以你觉得不安全感正在变成一个有用的功能。在过去,你有过时的vfork阻止了父母。今天不需要使用它;实际上,execve通常是通过clone(2)实现的,您不应该直接在实践中使用(请参阅futex(7) ...),但只能通过POSIX pthreads。但是将fork视为过程的神奇克隆者可能有所帮助。

编码时(即使在C中)不要忘记测试forkfork的失败。见perror(3)

PS。 execve系统调用与multiverse想法一样难以理解。两者都在“分叉”时间!

答案 1 :(得分:2)

当您致电fork()时,新流程将可以访问父进程内存的副本(即变量,文件描述符等)。

这与线程相反,其中所有线程共享相同的内存空间,即在一个线程中修改的变量将在所有其他线程中获得新值。

因此,如果,分叉后,父进程修改内存,子进程将不会看到该更改 - 因为内存已被复制,子进程的内存不会被更改。