Linux Capabilities
Enable Javascript to display Table of Contents.
Setting File Capabilities
File capabilities can be set with setcap and read with getcap:
root@cmp18018-100118:~# setcap 'cap_net_raw+p' /usr/bin/set_tai_offset
root@cmp18018-100118:~# getcap /usr/bin/set_tai_offset
/home/instrument/set_tai_offset = cap_net_raw+p
root@cmp18018-100118:~#
When the application is started as non-root user, the capabilities can be checked in /proc/PID/status:
root@cmp18018-100118:~# grep Cap /proc/$(pidof set_tai_offset)/status
CapInh: 0000000000000000
CapPrm: 0000000000002000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
root@cmp18018-100118:~#
Warning: Take care that the location of your binary has no nosuid mount flag set:
root@cmp18018-100118:~# mount | grep home
/dev/sda2 on /home type btrfs (rw,nosuid,nodev,relatime,ssd,space_cache,subvolid=262,subvol=/@/home,x-systemd.after=home.mount)
root@cmp18018-100118:~#
If the capability shall be effective immediately, you must add +pe instead of +p. If only the "permission" (+p) is set, you have to make it effective in the code:
#include <sys/capability.h> // sudo apt-get install libcap-dev
void enable_capabilities()
{
cap_t caps;
cap_value_t cap_list[1];
caps = cap_get_proc();
if (caps == NULL)
{
int errsv = errno;
std::cout << "Failed to receive capabilities: " << strerror(errsv) << std::endl;
exit(EXIT_FAILURE);
}
cap_list[0] = CAP_NET_RAW;
if (cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_list, CAP_SET) == -1)
{
int errsv = errno;
std::cout << "Failed to set capabilities: " << strerror(errsv) << std::endl;
exit(EXIT_FAILURE);
}
if (cap_set_proc(caps) == -1)
{
int errsv = errno;
std::cout << "Failed to apply capabilities: " << strerror(errsv) << std::endl;
exit(EXIT_FAILURE);
}
if (cap_free(caps) == -1)
{
int errsv = errno;
std::cout << "Failed to free capabilities: " << strerror(errsv) << std::endl;
exit(EXIT_FAILURE);
}
}
Source: blog.container-solutions.com