fork和execve继承无特权的父进程的能力

问题描述:

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

任何有关如何继承无特权父进程的能力的建议fork后跟execve

+0

似乎在目前是不可能保存execve的能力后,不设定文件的功能。请参阅[\ [RFC \]功能仍然不能由普通程序继承](http://www.gossamer-threads.com/lists/linux/kernel/1641892) – Lekensteyn 2013-01-10 21:32:18

+0

叉可以通过它们,exec不能(除了与环境)。 Exec可以通过继承,但是execed文件也需要这个继承集。 – 2017-08-27 16:56:34

execve()上,正在执行的文件(在本例中为udhcpc)的文件功能集被检查并与线程的功能集合在一起。特别是,该文件的Inheritable集合为AND,其中线程的Inheritable集合用于确定新集合Permitted,并且必须设置文件的Effective位,以便从Permitted集合中复制新集合Effective

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

+0

嗨,Thaks为您提供宝贵的答案。我正在使用内核2.6.18-7.1。我无法找到setcap命令来提供可执行文件的功能。我认为它在最新的内核中可用。在内核2.6.18-7.1中有没有其他的方法可以做到这一点。感谢Eswar – Eswar 2011-05-31 08:38:31

+0

@ user736403:对不起,我不确定这些旧内核的情况如何。 – caf 2011-05-31 10:36:41

据“Linux的编程接口”由迈克尔·凯里斯克(无淀粉出版社,2010年):

由于内核2.6.24,有可能功能附加到文件中。 为了完成功能的实现,在内核2.6.25和2.6.26的 中添加了各种其他功能。

工具sucapexeccap是你应该查找的。但是,如果我记得仅限于限制,而不是授予能力。请看:

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

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

从手动提取,也出现了一些变化。据它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).