Унаследованная возможность Linux очищена при запуске программы - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь запустить программу с сетевыми разрешениями, чтобы она могла выполнить iptables, не будучи пользователем root.Мне нужно 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, он не получил бы эти разрешения.

Я прочитал темы, подобные этим и man capabilities много раз, и лучшее объяснение яможет придумать, что моя оболочка не имеет cap_net_admin=i, и поэтому дочерний процесс не имеет.Как я могу запустить процесс с нужным флагом наследования?

1 Ответ

0 голосов
/ 26 октября 2018

Согласно capabilities(7)

Во время 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) используется только для определения разрешенных возможностей процесса, он не используется для определения наследуемых возможностей.

Унаследованные возможности файла - это AND и наследуемые возможности процесса.- это позволяет использовать этот флаг для предотвращения установки некоторых возможностей в новом процессе, он не используется для добавления чего-либо к новому процессу.

Если вы хотите сделатьВозможности, наследуемые от вашего процесса, вы можете назвать cap_set_proc().Когда возможность разрешена, вы можете сделать ее наследуемой.

...