程序启动时清除了Linux可继承功能

时间:2018-10-25 23:41:08

标签: c linux permissions file-permissions linux-capabilities

我正在尝试启动具有网络权限的程序,以便它可以以root用户身份执行iptables。我需要CAP_NET_ADMIN是可继承和允许的。似乎在启动可执行文件时清除了可继承标志,但是无效或不允许:

Script started on Thu 25 Oct 2018 11:09:45 PM UTC
[ec2-user@ip-172-31-16-197 cap_question]$ cat caps.c 
#include <stdio.h>
#include <stdlib.h>
#include <sys/capability.h>

int main(int argc, char **argv) {
    cap_t caps = cap_get_proc();
    printf("Inside the executable [%s]\n", argv[0]);
    char *cap_text = cap_to_text(caps, NULL);
    printf("capabilities %s\n", cap_text);
    cap_free(cap_text);
    cap_free(caps);
}
[ec2-user@ip-172-31-16-197 cap_question]$ cc caps.c -o caps -lcap
[ec2-user@ip-172-31-16-197 cap_question]$ sudo setcap cap_net_admin=eip caps
[ec2-user@ip-172-31-16-197 cap_question]$ getcap caps
caps = cap_net_admin+eip
[ec2-user@ip-172-31-16-197 cap_question]$ ./caps
Inside the executable [./caps]
capabilities = cap_net_admin+ep
[ec2-user@ip-172-31-16-197 cap_question]$ exit

Script done on Thu 25 Oct 2018 11:10:25 PM UTC

如您所见,可执行文件为cap_net_admin=eip。但是,当我实际运行它时,权限集是cap_net_admin=ep。我不明白为什么可执行文件在启动时会下降为可继承的。如果我要使用fork / exec iptables,它将不会获得这些权限。

我已经多次阅读threads like theseman capabilities,而我能提供的最好的解释是我的shell没有cap_net_admin=i,因此子进程没有。如何根据需要设置可继承标志来启动进程?

1 个答案:

答案 0 :(得分:1)

根据capabilities(7)

  

curl期间,内核使用以下算法计算进程的新功能:

execve(2)

P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset) P'(effective) = F(effective) ? P'(permitted) : 0 P'(inheritable) = P(inheritable) [i.e., unchanged] 表示进程中的可继承位,P(inheritable)是正在执行的文件的可继承位。如您所见,F(inheritable)仅用于确定流程的允许功能,而不用于确定可继承功能。

文件的可继承功能与流程的可继承功能进行“与”操作-这使您可以使用此标志来防止在新流程中设置某些功能,而不是习惯在新流程中添加任何内容。

如果要使功能可从流程继承,可以调用F(inheritable)。允许功能后,您就可以使其具有继承性。