【问题标题】:If a C program executing as root executes another binary by calling system(someprog) does that program also run as root?如果以 root 身份执行的 C 程序通过调用 system(someprog) 执行另一个二进制文件,该程序是否也以 root 身份运行?
【发布时间】:2020-03-27 22:39:22
【问题描述】:

似乎来自 C 程序的 system(someprog) 调用将以与 C 程序相同的权限执行 someprog 二进制文件,但是 system() 调用的文档没有说明分叉的权限过程。

【问题讨论】:

  • 真正的问题是this one
  • 我正在运行一个可执行程序,而不是脚本。另一个问题涵盖了很多其他方面。
  • 您实际上正在运行脚本。 system() 始终将字符串作为 shell 脚本运行。因此,您需要考虑 shell 在解释 "someprog" 之类的字符串时可能会做的任何事情

标签: c linux permissions fork glibc


【解决方案1】:

子进程的权限与父进程的权限相同。如果父进程以root 运行,则子进程也以root 运行,除非执行的进程本身是其他用户的SUID(如果执行的进程是另一个组的SGID,则组可能会更改)。这是root 必须小心执行的众多原因之一。

system() 调用的基础上,您通常会找到fork()execl()(或其近亲之一)——Linux 有可能使用不同的详细调用(clone(),或者可能是posix_spawn() 系列的功能)。基本的基本思想将是相同的。分叉的子进程与父进程具有相同的权限。当子进程执行另一个进程时,它具有与子进程相同的权限——除非可执行文件是 SUID 或 SGID。如果您考虑一下,当root 运行一个shell 并且shell 代表root 运行命令时,这些命令通常具有root 的权限。这和那个没有什么不同。

警惕安全隐患!

当然,被执行的程序可能会对它运行时的权限做一些事情。另见Calling a script from a setuid root C program - script does not run as rootthat other guycomment 中提及。

请注意,system() 通常运行相当于:

/bin/sh -c "the string you passed it with spaces preserved"

因此,了解 shell /bin/sh 的行为很重要。 Perl 分析您传递给它的system 的字符串,并避免调用shell,除非其中有shell 元字符。标准的 C system() 函数可能没有那么聪明。

如果对您很重要,请考虑不使用标准的system() 函数。编写自己的调用execvp() 或解析命令字符串后的任何内容。请注意,处理此问题并非易事,因为诸如信号和进程组之类的事情会使它复杂化。学习一本称职的书,或者system()的各种开源库实现的源代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多