Skip to content

chroot: setuid: Invalid argument #45

@ghistrash

Description

@ghistrash

Hello! Привет!

My use case is trying to use the unprivileged chroot as a simple tool to manage software environment:
like a python virtual env, but system-wide.

The error occurs happening when both, -n and -u options are present:

$ chroot -n -u 1000 new_root/ /bin/sh
chroot: setuid: Invalid argument

As I understand, the problem is that there is no UID/GID mapping from inside
an user namespace, created by unshare(CLONE_NEWUSER), to outside, the parent namespace, because invoking without -u option will:
$ chroot -n new_root/ /bin/sh
$ id
uid=65534(nobody) gid=65534(nobody)

Perhaps.. something like this could be a solution: make mapping? I am not sure..

// ... src.freebsd/coreutils/chroot.c
`
if (nonprivileged) {

FILE *fd;
uid_t chroot_caller_uid = getuid();
gid_t chroot_caller_gid = getgid();
error = unshare(CLONE_NEWUSER);
if (error != 0)
	err(1, "unshare");


if (user != NULL) {
	fd = fopen("/proc/self/uid_map", "w");
	if (fd == NULL) 
		err(1, "fopen: failed to open /proc/self/uid_map");

	error = fprintf(
          fd,
          "%lu %lu 1\n", // can not map more than one uid?..
          (unsigned long int) uid, // uid inside user namespace
          (unsigned long int) chroot_caller_uid // uid outside user namespace
      );
	if (error < 0) 
			err(1, "fprintf: failed to write to `/proc/self/uid_map`");
	fclose(fd);
}

// the same for a group

// ...
`

Then:

$ id
$ uid=1000(<user>) gid=1000(<group>)

$ chroot -n -u 1000 new_root/ /bin/sh - 1000 inside is mapped to 1000 outside of an user-namespaced chroot

$ chroot -n -u 0 new_root/ /bin/sh - 0 inside is mapped to 1000 outside of an user-namespaced chroot

$ doas chroot -n -u 0 new_root/ /bin/sh - 0 inside is mapped to 0 outside of an user-namespaced chroot

$ chroot -n new_root/ /bin/sh - 65534(nobody) inside is mapped to 1000 outside of an user-namespaced chroot (the same as is now)

I think this is expected or even desired behavior.

Or -n -u together was not meant to be intentionally?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions