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