1

I am trying to test the "capset" call in ubuntu system. This is the codes:

int cap_mask
cap_header.pid = getpid() ;
cap_header.version = _LINUX_CAPABILITY_VERSION_3;

if( capget(&cap_header, &cap_data) < 0)
{
    printf("%s\n", strerror(errno));
    exit(EXIT_FAILURE);
}

printf("capheader: %x  %d\n", cap_header.version, cap_header.pid);
printf("capdata: %x  %x  %x\n", cap_data.effective, cap_data.permitted, cap_data.inheritable);


cap_mask |= (1 << CAP_NET_BIND_SERVICE);
cap_data.effective = cap_mask;
cap_data.permitted = cap_mask;
cap_data.inheritable = 0;

if( capset(&cap_header, &cap_data) < 0)
{
    printf("%s\n", strerror(errno));
    exit(EXIT_FAILURE);
}
printf("%d\n", capget(&cap_header, &cap_data));
printf("capheader: %x  %d\n", cap_header.version, cap_header.pid);
printf("capdata: %x  %x  %x\n", cap_data.effective, cap_data.permitted, cap_data.inheritable);
return 0;

After running the binary, the outputs are:

capheader: 20080522  24315
capdata: 0  0  0
Operation not permitted

It seems that the capset fail with the error "operation not permitted" While if I comment this line

/*cap_mask | = (1<< CAP_NET_BIND_SERVICE)*/

The call capset will succeed with the outputs:

capheader: 20080522  24464
capdata: 0  0  0
0
capheader: 20080522  24464
capdata: 0  0  0

Do you know why the capset fail at the 1st run?

AllenHu
  • 561
  • 2
  • 5
  • 13
  • `cap_mask` is uninitialized, so the OR operation invokes undefined behavior. Perhaps the OR operation results in an illegal value, and you're just getting lucky that when you comment that out, whatever arbitrary garbage `cap_mask` begins with is legal. Also, be careful bit shifting signed numbers: https://stackoverflow.com/questions/4009885/arithmetic-bit-shift-on-a-signed-integer – yano Jun 14 '18 at 04:33
  • Thanks, but as I initialize the cap_mask to be 0(int cap_mask = 0), the issue remains. So it is not the root cause. – AllenHu Jun 14 '18 at 06:09
  • And it is very interesting that capset can be run when I run the program as the "root" user, (that is, $sudo ./program). But It is the file attribute by "ls": -rwxrwxr-x – AllenHu Jun 14 '18 at 06:24
  • take a look at [man 7 capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html). Just because you have permission to execute a binary (as indicated by your `ls` output) doesn't mean you have permission to execute everything. I'm not familiar with `capset`, but it looks like you need to be a root user to execute that system call, or add your current user name to a group capable of making that system call. Also worth reading [man capset](https://linux.die.net/man/2/capset) – yano Jun 14 '18 at 07:00
  • as a further illustration, consider `ifconfig`. When I do `ls -l /usr/sbin/ifconfig` I get the permissions `-rwxr-xr-x`. When I execute `ifconfig` I get a list of all my network interfaces. However, if I try to start manipulating those interfaces (ie `ifconfig enp2s0 down`) I get the following error `SIOCSIFFLAGS: Operation not permitted`. Just because you have permission to execute a file doesn't mean you have permission to execute everything that file is capable of doing. – yano Jun 14 '18 at 07:06
  • You'd have to look at the source code for the `capset` system call in the kernel, but I'd guess that whatever capability maps to 0 (or whatever your indeterminate value was before) doesn't perform/require any permission checks whereas setting the `CAP_NET_BIND_SERVICE` capability does require root privileges. This is worth a look too I think: https://stackoverflow.com/questions/14779868/what-causes-system-calls-in-linux-to-run-at-elevated-permissions – yano Jun 14 '18 at 07:12

0 Answers0