The way capabilities work in Linux is documented in man 7 capabilities.
Processes' capabilities in the effective set are against which permission checks are done. File capabilities are used during an execv call (which happens when you want to run another program1) to calculate the new capability sets for the process.
Files have two sets for capabilities, permitted and inheritable and effective bit.
Processes have three capability sets: effective, permitted and inheritable. There is also a bounding set, which limits which capabilities may be added later to a process' inherited set and affects how capabilities are calculated during a call to execv. Capabilities can only be dropped from the bounding set, not added.
Permissions checks for a process are checked against the process' effective set. A process can raise its capabilities from the permitted to the effective set (using capget and capset syscalls, the recommended APIs are respectively cap_get_proc and cap_set_proc).
Inheritable and bounding sets and file capabilities come into play during an execv syscall. During execv, new effective and permitted sets are calculated and the inherited and bounding sets stay unchanged. The algorithm is described in the capabilities man page:
P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset) P'(effective) = F(effective) ? P'(permitted) : 0 P'(inheritable) = P(inheritable) [i.e., unchanged]Where P is the old capability set, P' is the capability set after execv and F is the file capability set.
If a capability is in both processes' inheritable set and the file's inheritable set (intersection/logical AND), it is added to the permitted set. The file's permitted set is added (union/logical OR) to it (if it is within the bounding set).
If the effective bit in file capabilities is set, all permitted capabilities are raised to effective after execv.
Capabilities in kernel are actually set for threads, but regarding file capabilities this distinction is usually relevant only if the process alters its own capabilities.
In your example capabilities cap_net_raw , cap_net_admin and cap_dac_override are added to the inherited and permitted sets and the effective bit is set. When your binary is executed, the process will have those capabilities in the effective and permitted sets if they are not limited by a bounding set.
[1] For the fork syscall, all the capabilities and the bounding set are copied from parent process. Changes in uid also have their own semantics for how capabilities are set in the effective and permitted sets.
Answer from sebasth on Stack ExchangeThe way capabilities work in Linux is documented in man 7 capabilities.
Processes' capabilities in the effective set are against which permission checks are done. File capabilities are used during an execv call (which happens when you want to run another program1) to calculate the new capability sets for the process.
Files have two sets for capabilities, permitted and inheritable and effective bit.
Processes have three capability sets: effective, permitted and inheritable. There is also a bounding set, which limits which capabilities may be added later to a process' inherited set and affects how capabilities are calculated during a call to execv. Capabilities can only be dropped from the bounding set, not added.
Permissions checks for a process are checked against the process' effective set. A process can raise its capabilities from the permitted to the effective set (using capget and capset syscalls, the recommended APIs are respectively cap_get_proc and cap_set_proc).
Inheritable and bounding sets and file capabilities come into play during an execv syscall. During execv, new effective and permitted sets are calculated and the inherited and bounding sets stay unchanged. The algorithm is described in the capabilities man page:
P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset) P'(effective) = F(effective) ? P'(permitted) : 0 P'(inheritable) = P(inheritable) [i.e., unchanged]Where P is the old capability set, P' is the capability set after execv and F is the file capability set.
If a capability is in both processes' inheritable set and the file's inheritable set (intersection/logical AND), it is added to the permitted set. The file's permitted set is added (union/logical OR) to it (if it is within the bounding set).
If the effective bit in file capabilities is set, all permitted capabilities are raised to effective after execv.
Capabilities in kernel are actually set for threads, but regarding file capabilities this distinction is usually relevant only if the process alters its own capabilities.
In your example capabilities cap_net_raw , cap_net_admin and cap_dac_override are added to the inherited and permitted sets and the effective bit is set. When your binary is executed, the process will have those capabilities in the effective and permitted sets if they are not limited by a bounding set.
[1] For the fork syscall, all the capabilities and the bounding set are copied from parent process. Changes in uid also have their own semantics for how capabilities are set in the effective and permitted sets.
Setting a capability on a file
sudo setcap 'cap_net_bind_service=ep' file_name
Setting multiple capabilities on a file
sudo setcap 'cap_net_bind_service=ep cap_sys_admin=ep' file_name
Removing all capabilities from a file
sudo setcap -r file_name
Checking capabilities for a file
getcap file_name
List of possible capabilities (some are really interesting)
https://linux.die.net/man/7/capabilities
Pitfall: setting capabilities does not really work for scripts. If you want your Python script to work, you need to set the capabilities on the Python executable itself. It's not ideal.
Note: setcap always overwrites the entire capability set when you run it. Most of the time, you see examples using setcap with + or - syntax, which I believe is a confusing piece of junk and does NOT work as you would expect from other tools like chmod. You can't use setcap multiple times to add different capabilities, it needs to be done in a single command.
Which package provides the setcap command?
What is the setcap command and its purpose?
Searching for setcap
I believe setcap is contained in this package libcap2-bin. I found this by googling for "debian setcap" which led me to this man page:
- https://manpages.debian.org/jessie/libcap2-bin/setcap.8.en.html
The title of the man page tells you which package it resides in:
/ jessie / libcap2-bin / setcap(8)
Now that we "think" we know the package's name we can search for it:
- https://packages.debian.org/jessie/libcap2-bin
If you scroll down to the bottom of that page you'll see all the various architectures. Click the link for amd64:
- https://packages.debian.org/jessie/amd64/libcap2-bin/filelist
Found it
And there's setcap:
File list of package libcap2-bin in jessie of architecture amd64
/sbin/capsh
/sbin/getcap
/sbin/getpcaps
/sbin/setcap
/usr/share/doc/libcap2-bin/README.Debian
/usr/share/doc/libcap2-bin/changelog.Debian.gz
/usr/share/doc/libcap2-bin/changelog.gz
/usr/share/doc/libcap2-bin/copyright
/usr/share/man/man1/capsh.1.gz
/usr/share/man/man1/getpcaps.1.gz
/usr/share/man/man5/capability.conf.5.gz
/usr/share/man/man8/getcap.8.gz
/usr/share/man/man8/pam_cap.8.gz
/usr/share/man/man8/setcap.8.gz
Just do a search to see if a package has that command using
apt-file search setcap
if apt-file is not install first get it installed then re-issue above :
sudo apt install apt-file -y && sudo apt-file update
apt-file search setcap
the entry you want appears as
libcap2-bin: /sbin/setcap
now you know which package has it so install using
sudo apt-get install libcap2-bin
to see contents of an installed package issue
dpkg -L some-package
dpkg -L libcap2-bin
output includes these
/sbin/getcap
/sbin/setcap
so now you know how to install setcap and its get counterpart getcap
I was experiencing this too, and was able to get it working by building and installing the latest version of libcap from source. This may not be the best solution, but it worked for me.
libcap-2.53
$ git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/morgan/libcap
$ cd libcap
$ git checkout libcap-2.53
$ make
$ make test
$ make sudotest
$ sudo make install
I ran the tests to confirm everything was working before install.
Once it had been installed I was able to run the commands listed in the perf-security doc as expected.
This question is 2 years old but I think it might be useful to answer anyway.
A had a similar problem and I noticed that /usr/bin/perf was a shell script.
$ file /usr/bin/perf
/usr/bin/perf: Bourne-Again shell script, ASCII text executable
It called /usr/lib/linux-tools/6.5.0-26-generic/perf (my kernel version is 6.5.0-26-generic), which was a symbolic link for /usr/lib/linux-hwe-6.5-tools-6.5.0-26/perf. When I called setcap in the real executable file it finally worked.
$ sudo setcap cap_sys_admin,cap_sys_ptrace,cap_syslog=ep /usr/lib/linux-hwe-6.5-tools-6.5.0-26/perf
The setcap on the file stores the capabilities in an extended attribute with a call to setxattr. This extended attribute is stored like other attributes (ownership, rights...) in the filesystem.
Since kernel 2.6.24, the kernel supports associating capability sets with an executable file using setcap(8). The file capability sets are stored in an extended attribute (see setxattr(2)) named security.capability.
So, you don't have to reset your cap on each reboot.
The changes are permanent but I have experienced issues when used with nodejs.
You can use authbind to provide permission by user
sudo touch /etc/authbind/byport/80
sudo chown user:user /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80
I found the solution. I had to add this to the libcap recipe
PACKAGECONFIG_class-native = "attr"
As the generated binaries (setcap & getcap) are depending on libattr, and this has to be configured manually.
I found that it's already configured for the target package
PACKAGECONFIG ??= "attr ${@bb.utils.contains('DISTRO_FEATURES', 'pam', 'pam', '', d)}"
Sorry for disturbing.
I can't comment yet so comment here.
The command setcap should be provided by libcap-native. And please double check whether it exists in tmp/work/x86_64-linux/libcap-native/2.25-r0/image/:
$ find tmp/work/x86_64-linux/libcap-native/2.25-r0/sysroot-destdir/ -name setcap tmp/work/x86_64-linux/libcap-native/2.25-r0/sysroot-destdir/buildarea3/kkang/cgp9/builds/qemumips64-Apr24/tmp/sysroots/x86_64-linux/usr/sbin/setcap
You can find setcap here after remove the prefix:
$ ls /buildarea3/kkang/cgp9/builds/qemumips64-Apr24/tmp/sysroots/x86_64-linux/usr/sbin/setcap /buildarea3/kkang/cgp9/builds/qemumips64-Apr24/tmp/sysroots/x86_64-linux/usr/sbin/setcap