I’m trying to mount /proc
and /dev
after pivot_root
, but it’s failed if the child process is create with CLONE_NEWUSER
. Refer to the following section for the code.
After removed CLONE_NEWUSER
when clone
, everthing works.
#define _GNU_SOURCE
#include <err.h>
#include <limits.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>
static int
pivot_root(const char *new_root, const char *put_old)
{
return syscall(SYS_pivot_root, new_root, put_old);
}
#define STACK_SIZE (1024 * 1024)
static int /* Startup function for cloned child */
child(void *arg)
{
char **args = arg;
char *new_root = args[0];
/* Ensure that 'new_root' and its parent mount don't have
shared propagation (which would cause pivot_root() to
return an error), and prevent propagation of mount
events to the initial mount namespace. */
if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) == -1)
err(EXIT_FAILURE, "mount-MS_PRIVATE");
/* Ensure that 'new_root' is a mount point. */
if (mount(new_root, new_root, NULL, MS_BIND, NULL) == -1)
err(EXIT_FAILURE, "mount-MS_BIND");
/* And pivot the root filesystem. */
if (pivot_root(new_root, new_root) == -1)
err(EXIT_FAILURE, "pivot_root");
/* Switch the current working directory to "/". */
if (chdir("/") == -1)
err(EXIT_FAILURE, "chdir");
/* Unmount old root and remove mount point. */
if (mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL) == -1)
err(EXIT_FAILURE, "mount-MS_PRIVATE");
if (umount2("/", MNT_DETACH) == -1)
perror("umount2");
if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NODEV | MS_NOEXEC, NULL) == -1)
err(EXIT_FAILURE, "mount-proc");
if (mount("tmpfs", "/dev", "tmpfs", MS_STRICTATIME | MS_NOSUID, NULL) == -1)
err(EXIT_FAILURE, "mount-proc");
/* Execute the command specified in argv[1]... */
execv(args[1], &args[1]);
err(EXIT_FAILURE, "execv");
}
int
main(int argc, char *argv[])
{
char *stack;
/* Create a child process in a new mount namespace. */
stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
if (stack == MAP_FAILED)
err(EXIT_FAILURE, "mmap");
if (clone(child, stack + STACK_SIZE,
CLONE_NEWNS |
CLONE_NEWPID |
CLONE_NEWNET |
CLONE_NEWUSER |
SIGCHLD, &argv[1]) == -1)
err(EXIT_FAILURE, "clone");
/* Parent falls through to here; wait for child. */
if (wait(NULL) == -1)
err(EXIT_FAILURE, "wait");
exit(EXIT_SUCCESS);
}
Here’s the example without CLONE_NEWUSER
:
sudo ./pivot_root_demo /opt/chariot/containers/busybox/rootfs /bin/ls /proc
1 consoles dynamic_debug ioports kpagecgroup meminfo pagetypeinfo softirqs timer_list zoneinfo
acpi cpuinfo execdomains irq kpagecount misc partitions stat tty
bootconfig crypto fb kallsyms kpageflags modules pressure swaps uptime
buddyinfo devices filesystems kcore latency_stats mounts schedstat sys version
bus diskstats fs key-users loadavg mtd scsi sysrq-trigger version_signature
cgroups dma interrupts keys locks mtrr self sysvipc vmallocinfo
cmdline driver iomem kmsg mdstat net slabinfo thread-self vmstat
But when I add CLONE_NEWUSER
when during clone
, I’ll get the following error:
sudo ./pivot_root_demo /opt/chariot/containers/busybox/rootfs /bin/ls /proc
pivot_root_demo: mount-proc: Operation not permitted
You need to sign in to view this answers
Leave feedback about this