2011-11-11 17 views
7

如果进程B在正在执行的进程A(通常的write()系统调用)中写入一些数据到进程A的映像中,该怎么办?它会不会导致进程A执行的错误?在Linux上写入正在执行的进程映像

我是Linux新手。据我所知,Unix历史上并没有强制强制文件锁定(就像Windows一样)。所以写作是很有可能的。

我在网上搜索没有结果。当我问我这个Linux经验丰富的同事的这个问题时,他们都回答了这个过程,A的形象完全在内存中。尽管如此,从我读过的内容中,内核可以轻松地将一些页面从内存中交换回映像文件,例如,当内存条件不足时,内存条件会受到压力。所以,在磁盘上,一些页面可能会被另一个写入器进程损坏;之后,可以将它们交换回RAM并执行。

+0

检查有:http://stackoverflow.com/questions/4453781/what-happens-when-you-overwrite-a-memory-mapped-executable – Antoine

回答

2

您是否正在考虑写入pid_t 1234的另一个进程/proc/1234/mem的进程?

或者您是否正在考虑写入另一个进程的ELF可执行文件的进程?

这两种情况都很少见,而且Linux特定(其他Posix没有这些),所以我不知道在这种情况下会发生什么。但至少许可机器应该保护一些。

另请参阅ETXTBSY错误。

在实践中(如图strace -f /usr/bin/gcc hello.c -o hello)编译器和链接open之前删除的可执行-ing它编写的可执行文件,所以大多数编译从来不写了一个老可执行文件:

870 stat("hello", {st_mode=S_IFREG|0755, st_size=6096, ...}) = 0 
870 unlink("hello")     = 0 
870 open("hello", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0777) = 17 
870 fstat(17, {st_mode=S_IFREG|0755, st_size=0, ...}) = 0 

所以要写入一个可执行文件,你必须努力。当然,当你这样做时,顽皮的碰撞可能会发生。

+0

我意味着第二种情况。 –

+0

ETXTBSY可能是这里最大的线索,根据我的经验,如果您尝试覆盖正在运行的可执行文件的某些部分,则会出现ETXTBSY错误。并且请注意,覆盖文件的内容与删除文件以及在posix系统上使用相同文件名创建新文件非常不同。 – nos

+0

Antoine链接的问题有详细的讨论。我认为ETXTBSY已经不再发生了(除了静态链接的可执行文件)。 –

1

你读过的是什么建议可以将页面交换回“映像文件”?

如果系统内存不足,页面将被交换到磁盘上的交换分区,这与可执行文件不同。直到下次运行该文件时,写入可执行文件才会生效。

如果能以某种方式写入到交换文件的确切页面(这很困难,因为您必须准确知道数据写入磁盘的位置和时间)。如果你这样做了,你可能会修改目标代码。您是否建议破坏可执行文件,或者在运行时更改程序的一些巧妙方法?

+0

我很关心目标代码损坏的不良可能性。我怀疑内核使用交换分区作为可执行映像;就我所能想到的而言,这太浪费了。内核反而以类似于普通mmap的方式映射图像。 –

+0

干净的页面根本没有被换出 - 它们只是被丢弃,要从它们映射的文件中重新加载,如果它们再次需要的话。 – caf

相关问题