如何在Linux中实现runas?

How to implement runas in Linux?

我已经尝试过 fork、setresgid、setresuid 和 execvpe — 没有用。

具体来说,任何地方都没有返回错误,子进程启动正常,我已经确认 getresuid 和 getresgid 返回的所有 6 个幻数都匹配,但子进程没有所需的权限。

相关文件位于 /dev/input/ 文件夹中。这是权限:

drwxr-xr-x    3 root     root           180 Sep 23 19:47 .
drwxr-xr-x   17 root     root          4120 Sep 23 19:47 ..
drwxr-xr-x    2 root     root           160 Sep 23 19:47 by-path
crw-rw----    1 root     input      13,  64 Sep 23 19:47 event0
crw-rw----    1 root     input      13,  65 Sep 23 19:47 event1
crw-rw----    1 root     input      13,  66 Sep 23 19:47 event2
crw-rw----    1 root     input      13,  67 Sep 23 19:47 event3
crw-rw----    1 root     input      13,  68 Sep 23 19:47 event4
crw-rw----    1 root     input      13,  69 Sep 23 19:47 event5

用户是input组的成员,所以正常情况下可以访问这些文件。但是,使用 fork/setresgid/setresuid/execvpe 启动的进程无法访问这些文件。

这是来自 strace 日志的相关行,日志是使用 -ff 选项创建的,即只包含一个进程:

setresgid(10000, 10000, 10000)          = 0
setresuid(10000, 10000, 10000)          = 0
execve("/usr/local/bin/dotnet", ["/usr/local/bin/dotnet", "/home/user/launcher/Debug/Desktop.dll"], 0xffffea463f50 /* 1 var */) = 0
.. much later
openat(AT_FDCWD, "/dev/input/event0", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 EACCES (Permission denied)

问题确实是额外的组。出乎我的意料,setresuid 没有刷新附加组的列表。

要设置它们,启动器进程首先需要调用 getgrouplist to query the list of additional groups for the target user, then after the fork call setgroups 来应用这些值。

实现 Linux 等效于 CreateProcessAsUser 的完整内核调用序列如下:

getgrouplist, fork, chdir, setresgid, setgroups, setresuid, execvpe

请注意 setresuid 如何成为 execvpe 之前的最后一步。原因是,在那个调用之后,分叉进程不再具有修改这些与安全相关的东西的权限。

P.S。我想知道 Linux 软件中有多少安全漏洞是由于开发人员在他们的程序中切换用户帐户时忘记更新额外组列表造成的?