1

I am trying to launch a child-process as root from a non-root parent-process. I am thinking to use capabilities to make that work.

What I have tried so far is that, have set the file cap permitted for parent process to cap_setgid,cap_setuid,capkill+p. Then on the same parent process, I am programmatically setting the same capabilities to effective capability of the process before calling fork+exec from the parent process.

For sanity check, I have changed the chmod permission of my child-process to load as root only chmod 4755. Thus, it will only be executed as root and nothing else.

I am seeing that with these a setup, I am not been able to load the child process at all. Can anyone help me understand, what am I misisng here?

kishoredbn
  • 2,007
  • 4
  • 28
  • 47

1 Answers1

2

Try this (parent.cc):

#include <iostream>
#include <sys/capability.h>
#include <unistd.h>

int main() {
    cap_t caps = cap_get_proc();
    cap_value_t val = CAP_SETUID;
    cap_set_flag(caps, CAP_EFFECTIVE, 1, &val, CAP_SET);
    if (cap_set_proc(caps)) {
        perror("failed to raise cap_setuid");
        exit(1);
    }
    if (setuid(0)) {
        perror("unable to setuid");
        exit(1);
    }
    execl("./child.sh", "child.sh", NULL);
    std::cout << "didn't work, uid=" << getuid();
    exit(1);
}

With this (child.sh):

#!/bin/bash
id -u

Build and set things up:

$ chmod +x child.sh
$ g++ -o parent parent.cc -lcap
$ sudo setcap cap_setuid=p ./parent

If you run ./parent it should work like this:

$ ./parent 
0

This example is single threaded. If your app is single threaded, it should be sufficient. If your program is multithreaded, you might need to explore something like libpsx.

Tinkerer
  • 865
  • 7
  • 9