Raw capture capabilities (CAP_NET_RAW, CAP_NET_ADMIN) not working outside /usr/bin and friends for packet capture program using libpcap

dirkhas picture dirkhas · Mar 17, 2015 · Viewed 9.7k times · Source

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?

Answer

Graham King picture Graham King · Jun 14, 2015

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.