linuxrustcontainers

How to change user to root after clone with CLONE_NEWUSER?


After clone with CLONE_NEWUSER, the uid seems not 0. Is that expected behaviour? And how to change the user to root?

Here's the example of my code:

    let mut stack = [0u8; 1024 * 1024];
    let flags = CloneFlags::empty()
        .union(CloneFlags::CLONE_NEWUSER)
        .union(CloneFlags::CLONE_NEWNET)
        .union(CloneFlags::CLONE_NEWPID)
        .union(CloneFlags::CLONE_NEWNS);

    let pid = unsafe {
        nix::sched::clone(
            Box::new(|| match run_container(cxt.clone(), container.clone()) {
                Ok(()) => 0,
                Err(e) => {
                    tracing::error!("Failed to run container: {e}");
                    -1
                }
            }),
            &mut stack,
            flags,
            // The SIGCHLD signal is required for wait/waitpid;
            // otherwise, ECHILD will be reported.
            Some(libc::SIGCHLD),
        )?
    };

...

fn run_container(cxt: cfg::Context, container: Container) -> ChariotResult<()> {
    tracing::debug!("Run sandbox <{}> in <{}> as <{}>.", container.name, getpid(), getuid());
...
}

The debug log is:

...
2024-10-15T14:55:47.267206Z DEBUG chariot::cmd::runc: Run sandbox <busybox> in <1> as <65534>.
...

Is that possible to switch current user to root after clone?


Solution

  • See man capabilities, man namespaces and man user_namespaces:

    The newly created process starts out with root-equivalent capabilities, not necessarily with the root uid.

    Unmapped user and group IDs There are various places where an unmapped user ID (group ID) may be exposed to user space. For example, the first process in a new user namespace may call getuid(2) before a user ID mapping has been defined for the namespace. In most such cases, an unmapped user ID is con‐ verted to the overflow user ID (group ID); the default value for the overflow user ID (group ID) is 65534. See the descriptions of /proc/sys/kernel/overflowuid and /proc/sys/kernel/overflowgid in proc(5).