TL;DR: Why are cap_net_raw
, cap_net_admin
capabilities only working in /usr/bin
(or /usr/sbin
), but not other places? Can this be configured someplace?
I'm having problems assigning capabilities to my C program utilizing libpcap in Ubuntu 14.04. Even after assigning capabilities using setcap(8)
and checking it using getcap(8)
, I still get a permission error. It seems capabilities only work for executables in \usr\bin
and friends.
My program test.c
looks as follows:
#include <stdio.h>
#include <pcap.h>
int main(int argc, char **argv) {
if (argc != 2) {
printf("Specify interface \n");
return -1;
}
char errbuf[PCAP_ERRBUF_SIZE];
struct pcap* pcap = pcap_open_live(argv[1], BUFSIZ, 1, 0, errbuf);
if (pcap == NULL) {
printf("%s\n", errbuf);
return -1;
}
return 0;
}
and is compiled with
gcc test.c -lpcap
generating a.out
executable. I set capabilities:
sudo setcap cap_net_raw,cap_net_admin=eip ./a.out
And check to see that it looks right:
getcap a.out
which gives me
a.out = cap_net_admin,cap_net_raw+eip
Running a.out
gives me:
./a.out eth0
eth0: You don't have permission to capture on that device (socket: Operation not permitted)
Running with sudo
works as expected (program prints nothing and exits).
Here's the interesting part: If I move a.out
to /usr/bin
(and reapply the capabilities), it works. Vice versa: taking the capability-enabled /usr/bin/dumpcap
from wireshark
(which works fine for users in the wireshark
group) and moving it out of /usr/bin
, say to my home dir, reapplying the same capabilities, it doesn't work. Moving it back, it works.
SO: Why are these capabilities only working in /usr/bin
(and /usr/sbin
), but not other places? Can this be configured someplace?
Featured on Meta We’ve made changes to our Terms of Service & Privacy Policy - January 2022 New post summary designs on greatest hits now, everywhere else eventually 2021: a year in moderation Sunsetting Jobs & Developer Story Related 0 Libpcap does not capture whole packet 1
If we drop the CAP_NET_RAW capabilities for ping, then the ping utility should no longer work. Besides the output of capsh itself, the tcpdump command itself should also raise an error. The error clearly shows that the ping command is not allowed to open an ICMP socket. Now we know for sure that this works as expected.
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.
The getpcaps tool uses the capget () system call to query the available capabilities for a particular thread. This system call only needs to provide the PID to obtain more information. Binaries can have capabilities that can be used while executing. For example, it's very common to find ping binary with cap_net_raw capability:
This might be because your home directory is mounted with nosuid
, which seems to prevent capabilities working. Ubuntu encrypts the home directory, and mounts that with ecryptfs as nosuid.
Binaries with capabilities work for me in /usr/
, and /home/
, but not my home directory.
The only reference I could find to nosuid
defeating capabilities is this link: http://www.gossamer-threads.com/lists/linux/kernel/1860853#1860853. I would love to find an authoritative source.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With