Apparently, many Linux programmers do not seem to have a good understanding on this new development. Michael Kerrisk has statistics on the usage of different Linux capabilities. Perhaps, it is easier to get what you need by just assuming the privilege of the superuser than figuring out what you do not really need, which requires perhaps higher cognitive load and activity.
This post demonstrates a few usage of capabilities from an application programmer point of view.
Packet Socket
Packet socket requires that the opening process has effective UID 0 or the CAP_NET_RAW capability. The following example program sends a message over an Ethernet.#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <netpacket/packet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_ll dest_addr;
if (argc < 3) {
printf("Usage: %s destination_host message\n", argv[0]);
exit(0);
}
sockfd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
if (sockfd == -1) {
perror("Error calling socket(AF_PACKET, SOCK_DGRAM ...): ");
exit(1);
}
/* When you send packets it is enough to specify sll_family, sll_addr,
* sll_halen, sll_ifindex. The other fields should be 0. */
memset(&dest_addr, '\0', sizeof(dest_addr));
dest_addr.sll_family = AF_PACKET;
dest_addr.sll_ifindex = 1;
dest_addr.sll_halen = ETH_ALEN;
if (ether_aton_r(argv[1],
(struct ether_addr*)&(dest_addr.sll_addr)) == NULL) {
fprintf(stderr,
"Error: %s is not in the hex-digits-and-colons format.\n",
argv[1]);
}
if (sendto(sockfd, argv[2], strlen(argv[2]), 0,
(struct sockaddr*)&dest_addr, sizeof(dest_addr)) == -1) {
perror("Error calling sendto(...): ");
exit(1);
}
printf("Info: packet sent successful\n");
close(sockfd);
return 0;
}
The program takes two command line arguments. The first argument is the Ethernet address of destination host and the second argument is the message to send.
When you run it as a non-privileged user, for instance, as follows,
$ ./sendpacket 00:0c:29:89:7a:4d "Hello, World"
you would receive an "Operation not permitted" error,
Error calling socket(AF_PACKET, SOCK_DGRAM ...): : Operation not permitted
Two methods that we can use to make it work. First, run it under root, the traditional method,
$ sudo ./sendpacket 00:0c:29:89:7a:4d "Hello, World"
Info: packet sent successful
A new method, which is a better and preferred method, is to give the program minimal but necessary privilege -- since the packet socket requires the program with CAP_NET_RAW privilege, we ought to give the program the privilege, but only the privilege.
However, before that, let us check what privilege the program has,
$ /sbin/getcap ./sendpacket
It outputs nothing, which means the program does not any privilege. Now we can give the program the privilege by
$ sudo /sbin/setcap cap_net_raw=ep ./sendpacket
Now check the program's privilege again,
$ /sbin/getcap ./sendpacket
./sendpacket = cap_net_raw+ep
Now the output indicates that the program has its effective privilege set as CAP_NET_RAW. Run the program again as a non-privileged user,
$ ./sendpacket 00:0c:29:89:7a:4d "Hello, World"
Info: packet sent successful
Notable Issues
When I tried to set capability for the program on a Virtual Machine, I received an error:Failed to set capabilities on file `./sendpacket' (Operation not supported)
This is because that the file system that the file was on is actually a VMWare HGFS that moutns a Windows NTFS. The Windows NTFS does not support the security capability. When I copied the file to an ext4 file system, the problem went away.
libcap Library
For programming Linux capabilities, you need the libcap library.On Ubuntu,
sudo apt-get install libcap-dev
On CentOS/Fedora Linux,
sudo yum install libcap-devel
Reference and Further Reading
- http://www.cis.syr.edu/~wedu/seed/Labs/Documentation/Linux/How_Linux_Capability_Works.pdf
- http://man7.org/linux/man-pages/man7/packet.7.html
- http://www.linuxjournal.com/article/5737
- http://ols.fedoraproject.org/OLS/Reprints-2008/hallyn-reprint.pdf
- http://www.cis.gvsu.edu/~kalafuta/cis458/f12/labs/lab3.html
No comments:
Post a Comment