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

是否存在允许我在另一个进程的上下文中进行系统调用的Linux系统调用?,linux,linux-kernel,kernel,system-calls,Linux,Linux Kernel,Kernel,System Calls,我想做的是做一个系统调用,让内核像做调用的另一个进程一样工作。你可以把它想象成模拟另一个过程。我知道我可以用ptrace处理程序的代码,但这不是很优雅,可能需要调整才能处理我正在做的任何进程。另外,我所要求的内核应该是可能的,而不必接触其他进程的内存或执行进程,当然,除非我正在执行的系统调用的影响会导致这种情况 我认为它的工作方式是有一个(特权)系统调用(我们称它为setepid,用于“set effective PID”),它接受一个PID作为参数。在setepi之后,该进程(或者可能仅该线程

我想做的是做一个系统调用,让内核像做调用的另一个进程一样工作。你可以把它想象成模拟另一个过程。我知道我可以用ptrace处理程序的代码,但这不是很优雅,可能需要调整才能处理我正在做的任何进程。另外,我所要求的内核应该是可能的,而不必接触其他进程的内存或执行进程,当然,除非我正在执行的系统调用的影响会导致这种情况

我认为它的工作方式是有一个(特权)系统调用(我们称它为
setepid
,用于“set effective PID”),它接受一个PID作为参数。在
setepi
之后,该进程(或者可能仅该线程)所进行的任何未来系统调用的行为将与进行系统调用的指定进程的行为相同。异常是
setepd
调用本身,它可以用于恢复原始上下文或以其他方式针对不同的进程

例如,以下代码可用于将已运行进程(本例中为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”
字符串常量,它作为指针传递。取决于setepid的实现方式(可能出于必要),它可能将该指针视为进程1234内存中的地址。由于在编译时在另一个进程中静态分配内存(包括常量)是没有意义的,因此要解决这一问题,需要做一些类似以下的事情:

setepid(1234);
char *buf = mmap(NULL, 12, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
setepid(0);

const char *str = "output.txt\0"; /* extra byte to make it a multiple of 4 */
/* Disclaimer: I'm not sure if I'm using ptrace correctly, but you get the idea. */
ptrace(PTRACE_ATTACH, 1234, NULL, NULL);
ptrace(PTRACE_POKEDATA, 1234, buf, *(void**)str);
ptrace(PTRACE_POKEDATA, 1234, buf+4, *(void**)(str+4));
ptrace(PTRACE_POKEDATA, 1234, buf+8, *(void**)(str+8));
ptrace(PTRACE_DETACH, 1234, NULL, NULL);

setepid(1234);

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

setepid(0);

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

如果不将代码有效地注入目标线程,您所建议的工具将无法工作,而且您已经可以使用ptrace做很多事情了

其中一个问题是,存在仅由当前线程修改的数据。因为没有其他人修改它,所以它可以在没有锁的情况下轻松读取。但是用你的方法,不变量会被打破。一个简单的例子是凭证

这也不适用于提供的玩具fd更换箱。当以fd作为参数执行任何系统调用时,必须找到目标文件指针。如果fd表是共享的,则必须引用该文件,因为此时其他人可能会关闭(fd)。内核对单线程进程进行了微优化——由于表没有共享,因此没有人关闭fd,因此以后不需要引用(和取消引用)它。再一次,当您关闭线程使用的fd时,fd表的突然修改很容易导致空闲后使用

等等


简言之,这是不可能实现的。您可以做的最接近的事情是使用ptrace注入syscalls。

如果不将代码有效地注入目标线程,您所建议的方法就无法工作,而且您已经可以使用ptrace完成很多工作

其中一个问题是,存在仅由当前线程修改的数据。因为没有其他人修改它,所以它可以在没有锁的情况下轻松读取。但是用你的方法,不变量会被打破。一个简单的例子是凭证

这也不适用于提供的玩具fd更换箱。当以fd作为参数执行任何系统调用时,必须找到目标文件指针。如果fd表是共享的,则必须引用该文件,因为此时其他人可能会关闭(fd)。内核对单线程进程进行了微优化——由于表没有共享,因此没有人关闭fd,因此以后不需要引用(和取消引用)它。再一次,当您关闭线程使用的fd时,fd表的突然修改很容易导致空闲后使用

等等


简言之,这是不可能实现的。您可以做的最接近的事情是使用ptrace注入系统调用。

是有意义的。我本想用这个做实验的,但谢谢。有道理。我本想尝试一下,但谢谢。