如果以 root 身份执行的 C 程序通过调用 system(someprog) 执行另一个二进制文件,该程序是否也以 root 身份 运行?
If a C program executing as root executes another binary by calling system(someprog) does that program also run as root?
似乎来自 C 程序的 system(someprog) 调用会以与 C 程序相同的权限执行 someprog 二进制文件,但 system() 调用的文档没有说明任何有关权限的信息分叉进程。
子进程的权限与父进程相同。如果父进程以 root
运行,那么子进程也运行,除非执行的进程本身是其他用户的 SUID(如果执行的进程是另一个组的 SGID,则组可能会更改)。这是 root
必须谨慎执行操作的众多原因之一。
system()
call, you traditionally find fork()
and execl()
(or one of its close relatives) — there's a chance that Linux uses different detailed calls (clone()
, or maybe the posix_spawn()
函数族的基础)。基本的基本思想将是相同的。分叉的子进程与父进程具有相同的权限。当子进程执行另一个进程时,它具有与子进程相同的权限——除非可执行文件是 SUID 或 SGID。如果您考虑一下,当 root
运行 shell 并且 shell 代表 root
运行命令时,这些命令通常具有 root
的特权。这个跟那个没什么区别。
警惕安全隐患!
当然,执行的程序可能会对其运行权限做一些事情。另见 Calling a script from a setuid root C program - script does not run as root, mentioned by that other guy in a .
请注意 system()
通常运行等同于:
/bin/sh -c "the string you passed it with spaces preserved"
因此,了解 shell /bin/sh
的行为很重要。 Perl 分析您传递给它的 system
的字符串并避免调用 shell 除非其中有 shell 元字符。标准 C system()
函数可能没有那么聪明。
如果这对您很重要,请考虑不使用标准 system()
函数。在解析命令字符串后编写自己的调用 execvp()
或其他内容。请注意,处理此问题并非易事,因为信号和进程组之类的东西会使它复杂化。研究一本能干的书,或者system()
.
的各种开源库实现的源代码
似乎来自 C 程序的 system(someprog) 调用会以与 C 程序相同的权限执行 someprog 二进制文件,但 system() 调用的文档没有说明任何有关权限的信息分叉进程。
子进程的权限与父进程相同。如果父进程以 root
运行,那么子进程也运行,除非执行的进程本身是其他用户的 SUID(如果执行的进程是另一个组的 SGID,则组可能会更改)。这是 root
必须谨慎执行操作的众多原因之一。
system()
call, you traditionally find fork()
and execl()
(or one of its close relatives) — there's a chance that Linux uses different detailed calls (clone()
, or maybe the posix_spawn()
函数族的基础)。基本的基本思想将是相同的。分叉的子进程与父进程具有相同的权限。当子进程执行另一个进程时,它具有与子进程相同的权限——除非可执行文件是 SUID 或 SGID。如果您考虑一下,当 root
运行 shell 并且 shell 代表 root
运行命令时,这些命令通常具有 root
的特权。这个跟那个没什么区别。
警惕安全隐患!
当然,执行的程序可能会对其运行权限做一些事情。另见 Calling a script from a setuid root C program - script does not run as root, mentioned by that other guy in a
请注意 system()
通常运行等同于:
/bin/sh -c "the string you passed it with spaces preserved"
因此,了解 shell /bin/sh
的行为很重要。 Perl 分析您传递给它的 system
的字符串并避免调用 shell 除非其中有 shell 元字符。标准 C system()
函数可能没有那么聪明。
如果这对您很重要,请考虑不使用标准 system()
函数。在解析命令字符串后编写自己的调用 execvp()
或其他内容。请注意,处理此问题并非易事,因为信号和进程组之类的东西会使它复杂化。研究一本能干的书,或者system()
.