是否有Linux系统调用允许我在另一个进程的上下文中进行系统调用?

时间:2016-12-21 00:09:21

标签: linux linux-kernel kernel system-calls

我想要做的是进行系统调用,并让内核充当调用它的不同进程。你可以把它想象成冒充另一个过程。我知道我可以使用ptrace搞乱程序的代码,但这不是很优雅,可能需要调整以适应我正在做的任何过程。此外,我所要求的内核应该可以在不必触及其他进程的内存或执行过程的情况下进行,除非系统调用的影响我执行会导致这种情况。< / p>

我认为它可行的方式是进行(特权)系统调用(让我们称之为setepid,为#34;设置有效PID&#34;)接受PID作为参数。在setepid之后,该进程(或者可能只是该线程)进行的任何未来系统调用将表现为就像进行系统调用的指定进程一样。例外情况是setepid调用本身,可用于恢复原始上下文或以其他方式定位不同的进程。

例如,以下代码可用于将已在运行的进程的标准输出(本例中为PID 1234)重定向到位于进程1234的当前工作目录中的文件output.txt

setepid(1234); /* perform following system calls on process 1234 */

int fd = open("output.txt", O_WRONLY|O_CREAT|O_TRUNC);
if (fd > 0) {
    dup2(fd, 1);
    close(fd);
}

setepid(0); /* done acting as 1234, restore original context */

这可能存在的一个问题是"output.txt"字符串常量,它作为指针传递。根据{{​​1}}的实现方式,可能是出于必要,可能会将该指针视为进程1234内存中的地址。因为在编译时在另一个进程中静态分配内存(包括常量)甚至没有意义,所以绕过它会需要像这样丑陋的东西:

setepid

我假设这种机制不存在,但我希望我错了。如果我的假设是正确的,是否有任何问题会阻止在未来的Linux版本中添加它?在内核模块中实现它是否简单(甚至可能)?这听起来像是一个危险的,但功能强大且可能有用的工具。

1 个答案:

答案 0 :(得分:3)

如果没有有效地将代码注入目标线程,那么你提出的建议是行不通的。你可以用ptrace做很多事情。

其中一个问题是数据只能由当前线程修改。由于没有其他人修改它,因此可以在没有锁的情况下轻松读取。但是随着你的方法,不变量会破裂。一个简单的例子就是凭证。

这对于提供的玩具fd更换案例不起作用。当执行任何以fd作为参数的系统调用时,必须找到目标文件指针。如果共享fd表,则必须引用该文件,因为其他人可以在此期间关闭(fd)。内核对单线程进程有一个微优化 - 因为表没有共享,所以没有人关闭fd,因此以后不需要引用(和取消)它。再一次,当你关闭线程使用的fd时,突然修改fd表很容易导致free-after-free。

等等。

简而言之,这是不可能的。你可以做的最接近的事情就是用ptrace注入系统调用。