【问题标题】:fork and execve to inherit unprivileged parent process' capabilitiesfork 和 execve 继承非特权父进程的能力
【发布时间】:2011-05-27 15:28:07
【问题描述】:

在 Linux 系统中,非特权用户启动程序。创建的进程具有CAP_NET_RAW,CAP_NET_ADMIN 的功能,其模式为effective,permitted,inheritable。 该进程然后通过调用fork 和execv 来调用另一个程序udhcpc 来创建一个子进程,但是子进程没有像预期的那样继承CAP_NET_RAW,CAP_NET_ADMIN 的能力。即使在设置功能之前我已经调用了prctl(PR_SET_KEEPCAPS, 1)。

关于如何在fork 后跟execve 继承非特权父进程的能力有什么建议吗?

【问题讨论】:

标签: linux linux-capabilities


【解决方案1】:

在execve() 上,正在执行的文件(在本例中为udhcpc)的文件能力集被检查并与线程的能力集相结合。特别是,文件的Inheritable 集是AND-ed 和线程的Inheritable 集以确定新的Permitted 集,并且必须设置文件的Effective 位才能获得新的Effective 集从Permitted 集合中复制。

这意味着在您的情况下,您必须使用 setcap cap_net_raw,cap_net_admin=ei /path/to/udhcpc 才能获得所需的效果(除了在父进程中设置功能 - prctl() 不是必需的)。

【讨论】:

  • 您好,谢谢您的宝贵回答。我正在使用内核 2.6.18-7.1。我找不到命令 setcap 来提供可执行文件的功能。我认为它在最新的内核中可用。在内核 2.6.18-7.1 中有没有其他方法可以做到这一点。感谢 Eswar
  • @user736403:抱歉,我不确定那些旧内核的情况如何。
【解决方案2】:

根据 Michael Kerrisk 的“Linux 编程接口”(No Starch Press,2010 年):

从内核 2.6.24 开始,可以将功能附加到文件。 在内核 2.6.25 和 2.6.26 中添加了各种其他功能 为了完成功能的实现。

sucap 和 execcap 是您应该查找的工具。但是,如果我记得它们仅限于限制,而不是授予功能。看看:

http://www.linuxjournal.com/article/5737

和

http://lkml.indiana.edu/hypermail/linux/kernel/0503.1/2540.html

【讨论】:

    【解决方案3】:

    摘自手册,有一些改动。根据它fork 不会改变功能。现在有一个环境设置,这似乎是你想要做的。

       Ambient (since Linux 4.3):
              This is a set of capabilities that are preserved across an execve(2) of a program that is not privileged.  The ambient capability set obeys the invariant that no capability can ever
              be ambient if it is not both permitted and inheritable.
    
              The ambient capability set can be directly modified using
              prctl(2).  Ambient capabilities are automatically lowered if
              either of the corresponding permitted or inheritable
              capabilities is lowered.
    
              Executing a program that changes UID or GID due to the set-
              user-ID or set-group-ID bits or executing a program that has
              any file capabilities set will clear the ambient set.  Ambient
              capabilities are added to the permitted set and assigned to
              the effective set when execve(2) is called.
    
       A child created via fork(2) inherits copies of its parent's
       capability sets.  See below for a discussion of the treatment of
       capabilities during execve(2).
    

    …

           P'(ambient) = (file is privileged) ? 0 : P(ambient)
    
           P'(permitted) = (P(inheritable) & F(inheritable)) |
                           (F(permitted) & cap_bset) | P'(ambient)
    
           P'(effective) = F(effective) ? P'(permitted) : P'(ambient)
    
           P'(inheritable) = P(inheritable)    [i.e., unchanged]
    
       where:
    
           P         denotes the value of a thread capability set before the
                     execve(2)
    
           P'        denotes the value of a thread capability set after the
                     execve(2)
    
           F         denotes a file capability set
    
           cap_bset  is the value of the capability bounding set (described
                     below).
    

    【讨论】:

      【解决方案4】:

      拥有一个可以执行任何具有特定功能的程序的包装程序很有用,无需在目标程序上设置功能。这样的包装器对于从构建目录运行软件(setcap 会很麻烦)或运行 Python 之类的解释器(不合适)特别有用。

      正如其他答案中所解释的,环境功能解决了这个问题,但它们仅在内核 4.3 之后才可用。可以通过让包装器直接加载目标程序而不是使用exec 来解决此问题。我的意思是打开可执行文件,映射相关部分,设置堆栈等,然后跳转到它的代码。这是一项相当复杂的任务,但幸运的是 Wine 项目中的 wine-preloader 程序正是这样做的(以及与此目的无关的其他一些事情)。

      以 root 身份运行类似的东西来设置包装器:

      cp /usr/bin/wine-preloader /path/to/wrapper
      setcap cap_net_raw+ep /path/to/wrapper # set whatever capabilities you need
      

      现在我们有了一个wine-preloader 的副本,它能够运行任何具有这些功能的程序:

      /path/to/wrapper /path/to/executable arguments...
      

      这可行,但有一些陷阱:

      • 目标程序必须是可执行文件的路径,在PATH中找不到程序。
      • 如果目标程序是带有解释器的脚本 (#!),则它不起作用。
      • wine-preloader 打印一条关于无法找到某物的消息(但它仍然可以正常运行程序)。

      【讨论】:

        猜你喜欢
        • 2018-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多