Are there any way that I could run application with a special capabilities? I'm trying to set capabilities with function "cap_set_flag()", by setting flag "SET_CLEAR", to all "CAP_INHERITABLE" capabilities but it doesn't work. Child application still has all capabilities, but i expect it will have only "cap_dac_override". I also my app with sudo to change capabilities.
My app:
#include <sys/capability.h>
#include <stdio.h>
#include <unistd.h>
cap_value_t newcaps[1] = { CAP_DAC_OVERRIDE, };
cap_value_t cap_list_[33] = {
CAP_CHOWN,
CAP_DAC_READ_SEARCH,
CAP_FOWNER,
CAP_FSETID,
CAP_KILL,
CAP_SETGID,
CAP_SETUID,
CAP_SETPCAP,
CAP_LINUX_IMMUTABLE,
CAP_NET_BIND_SERVICE,
CAP_NET_BROADCAST,
CAP_NET_ADMIN,
CAP_NET_RAW,
CAP_IPC_LOCK,
CAP_IPC_OWNER,
CAP_SYS_MODULE,
CAP_SYS_RAWIO,
CAP_SYS_CHROOT,
CAP_SYS_PTRACE,
CAP_SYS_PACCT,
CAP_SYS_ADMIN,
CAP_SYS_BOOT,
CAP_SYS_NICE,
CAP_SYS_RESOURCE,
CAP_SYS_TIME,
CAP_SYS_TTY_CONFIG,
CAP_MKNOD,
CAP_LEASE,
CAP_AUDIT_WRITE,
CAP_AUDIT_CONTROL,
CAP_SETFCAP,
CAP_MAC_OVERRIDE,
CAP_MAC_ADMIN
};
void test() {
cap_value_t cap_list[35];
const char *cap_name[35] = {
"cap_chown",
"cap_dac_override",
"cap_dac_read_search",
"cap_fowner",
"cap_fsetid",
"cap_kill",
"cap_setgid",
"cap_setuid",
"cap_setpcap",
"cap_linux_immutable",
"cap_net_bind_service",
"cap_net_broadcast",
"cap_net_admin",
"cap_net_raw",
"cap_ipc_lock",
"cap_ipc_owner",
"cap_sys_module",
"cap_sys_rawio",
"cap_sys_chroot",
"cap_sys_ptrace",
"cap_sys_pacct",
"cap_sys_admin",
"cap_sys_boot",
"cap_sys_nice",
"cap_sys_resource",
"cap_sys_time",
"cap_sys_tty_config",
"cap_mknod",
"cap_lease",
"cap_audit_write",
"cap_audit_control",
"cap_setfcap",
"cap_mac_override",
"cap_mac_admin",
"cap_syslog"
};
int i;
pid_t pid = getpid();
cap_t cap = cap_get_pid(pid);
cap_flag_value_t cap_flags_value;
for (i=0; i < 34; i++) {
cap_from_name(cap_name[i], &cap_list[i]);
printf("%-20s %d\t\t", cap_name[i], cap_list[i]);
printf("flags: \t\t");
cap_get_flag(cap, cap_list[i], CAP_EFFECTIVE, &cap_flags_value);
printf(" EFFECTIVE %-4s ", (cap_flags_value == CAP_SET) ? "OK" : "NOK");
cap_get_flag(cap, cap_list[i], CAP_PERMITTED, &cap_flags_value);
printf(" PERMITTED %-4s ", (cap_flags_value == CAP_SET) ? "OK" : "NOK");
cap_get_flag(cap, cap_list[i], CAP_INHERITABLE, &cap_flags_value);
printf(" INHERITABLE %-4s ", (cap_flags_value == CAP_SET) ? "OK" : "NOK");
printf("\n");
}
}
int main(int argc, char **argv[]) {
cap_t caps = cap_get_proc();
printf("Capabilities: %s\n", cap_to_text(caps, NULL));
if (cap_set_flag(caps, CAP_INHERITABLE, 33, cap_list_, CAP_CLEAR)){
printf("ERROR");
return 0;}
if (cap_set_flag(caps, CAP_EFFECTIVE, 33, cap_list_, CAP_CLEAR)){
printf("ERROR");
return 0;}
if (cap_set_flag(caps, CAP_PERMITTED, 33, cap_list_, CAP_CLEAR)){
printf("ERROR");
return 0;}
cap_set_proc(caps);
if(cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET)){
printf("ERROR2");
return 0;
}
if(cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET)){
printf("ERROR2");
return 0;
}
if(cap_set_flag(caps, CAP_PERMITTED, 1, newcaps, CAP_SET)){
printf("ERROR2");
return 0;
}
cap_set_proc(caps);
printf("Capabilities: %s\n", cap_to_text(caps, NULL));
cap_free(caps);
printf("====================Cap====================\n");
test();
printf("====================Test====================\n");
return execl("/home/ilya/testSEM/test.o", NULL);
}
My test app:
#include <stdio.h>
#include <sys/capability.h>
int main(int argc, char **argv) {
cap_value_t cap_list[35];
const char *cap_name[35] = {
"cap_chown",
"cap_dac_override",
"cap_dac_read_search",
"cap_fowner",
"cap_fsetid",
"cap_kill",
"cap_setgid",
"cap_setuid",
"cap_setpcap",
"cap_linux_immutable",
"cap_net_bind_service",
"cap_net_broadcast",
"cap_net_admin",
"cap_net_raw",
"cap_ipc_lock",
"cap_ipc_owner",
"cap_sys_module",
"cap_sys_rawio",
"cap_sys_chroot",
"cap_sys_ptrace",
"cap_sys_pacct",
"cap_sys_admin",
"cap_sys_boot",
"cap_sys_nice",
"cap_sys_resource",
"cap_sys_time",
"cap_sys_tty_config",
"cap_mknod",
"cap_lease",
"cap_audit_write",
"cap_audit_control",
"cap_setfcap",
"cap_mac_override",
"cap_mac_admin",
"cap_syslog"
};
int i;
pid_t pid = getpid();
cap_t cap = cap_get_pid(pid);
cap_flag_value_t cap_flags_value;
for (i=0; i < 34 + 1; i++) {
cap_from_name(cap_name[i], &cap_list[i]);
printf("%-20s %d\t\t", cap_name[i], cap_list[i]);
printf("flags: \t\t");
cap_get_flag(cap, cap_list[i], CAP_EFFECTIVE, &cap_flags_value);
printf(" EFFECTIVE %-4s ", (cap_flags_value == CAP_SET) ? "OK" : "NOK");
cap_get_flag(cap, cap_list[i], CAP_PERMITTED, &cap_flags_value);
printf(" PERMITTED %-4s ", (cap_flags_value == CAP_SET) ? "OK" : "NOK");
cap_get_flag(cap, cap_list[i], CAP_INHERITABLE, &cap_flags_value);
printf(" INHERITABLE %-4s ", (cap_flags_value == CAP_SET) ? "OK" : "NOK");
printf("\n");
}
}
My results:
====================Cap====================
cap_chown 0 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_dac_override 1 flags: EFFECTIVE OK PERMITTED OK INHERITABLE OK
cap_dac_read_search 2 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_fowner 3 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_fsetid 4 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_kill 5 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_setgid 6 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_setuid 7 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_setpcap 8 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_linux_immutable 9 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_net_bind_service 10 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_net_broadcast 11 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_net_admin 12 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_net_raw 13 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_ipc_lock 14 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_ipc_owner 15 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_module 16 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_rawio 17 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_chroot 18 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_ptrace 19 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_pacct 20 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_admin 21 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_boot 22 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_nice 23 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_resource 24 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_time 25 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_sys_tty_config 26 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_mknod 27 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_lease 28 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_audit_write 29 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_audit_control 30 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_setfcap 31 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_mac_override 32 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
cap_mac_admin 33 flags: EFFECTIVE NOK PERMITTED NOK INHERITABLE NOK
====================Test====================
cap_chown 0 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_dac_override 1 flags: EFFECTIVE OK PERMITTED OK INHERITABLE OK
cap_dac_read_search 2 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_fowner 3 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_fsetid 4 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_kill 5 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_setgid 6 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_setuid 7 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_setpcap 8 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_linux_immutable 9 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_net_bind_service 10 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_net_broadcast 11 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_net_admin 12 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_net_raw 13 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_ipc_lock 14 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_ipc_owner 15 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_module 16 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_rawio 17 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_chroot 18 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_ptrace 19 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_pacct 20 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_admin 21 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_boot 22 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_nice 23 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_resource 24 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_time 25 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_sys_tty_config 26 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_mknod 27 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_lease 28 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_audit_write 29 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_audit_control 30 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_setfcap 31 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_mac_override 32 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_mac_admin 33 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
cap_syslog 34 flags: EFFECTIVE OK PERMITTED OK INHERITABLE NOK
Reading your program over you have two programs:
appandtest. Theappcode you provide looks like it is invokingtest.o, but I'm going to refer to that program astestin my explanation.Try doing this:
If you run
./test(as a regular user and notroot) it will be launched with no privilege at all. Confusing, but this is how things work by design.INHERITABLE file capabilities (
=ei) are not privilege, but the potential for inheriting privilege. You can trigger that inheriting effect if you run./app(as a regular user) it will start with the singlecap_dac_overridecapability in its EFFECTIVE and PERMITTED sets (cap_dac_override=ep). Yourappcode will raise this single capability in the INHERITABLE process flag as well, to get a process withcap_dac_override=eip.When
appends by executing./test, the raised process INHERITABLE flag will combine with the file INHERITABLE flag on thetestbinary to run your code with privilege. Since it also has the EFFECTIVE file bit, this combination will cause thetestprogram to execute withcap_dac_override=eip. Note, the=epprocess capabilities ofappare not inherited directly, but only=ibits are passed on throughexecl()and the rules for capability inheritance convert the file-I and the process-I into a post-execl()process-IP.For code like this, which knows how to get and set capabilities from code, you don't really need to include the '=e.' part when adding file capabilities. All that is doing is forcing the capabilities to be EFFECTIVE as the program starts running. This feature was included so programs that don't know about capabilities can be made to run with less than full
rootprivilege. It is good practice to usecap_set_flag()andcap_set_proc()to raise the EFFECTIVE capabilities you need only when you need them.