2011-05-27 47 views
6

在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

回答

10

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

2

據「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

1

從手動提取,也出現了一些變化。據它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).