#include #include #include static void procfs_prepare() { if (mkdir("/proc", 0555) && errno != EEXIST) die("Failed to mkdir /proc: %m\n"); if (mount("proc", "/proc", "proc", 0, "")) die("Failed to mount proc: %m\n"); } #define hostname "runner" #define put_old "oldfs" //#define shared_folder "../shared" //#define shared_mountpoint "shared" void mnt_prepare(char* rootfs, char* shared_mountpoint) { //char* shared_folder = malloc(strlen(shared_mountpoint)+4); //strcpy(shared_folder,"../"); //strcat(shared_folder,shared_mountpoint); char* shared_folder=NULL; asprintf(&shared_folder,"../%s",shared_mountpoint); if (mount(rootfs,rootfs,"ext4",MS_BIND,"")) die("failed to mount %s: %m", rootfs); //if (mount(shared_mountpoint,shared_mountpoint,"ext4",MS_BIND,"")) die("failed to mount %s: %m",shared_mountpoint); if (chdir(rootfs)) die("falied to cd:%m"); //if (mount("/sys","sys","sysfs",0,"")) die("failed to mount sysfs: %m"); //if (mount("/dev","dev","udev",0,"")) die("failed to mount: %m"); if (mkdir("shared", 0777) && errno != EEXIST) die("Failed to mkdir %s: %m\n", shared_mountpoint); if (mount(shared_folder,"shared","ext4",MS_BIND,"")) die("failed to mount shared folder: %m"); if (mkdir(put_old, 0000) && errno != EEXIST) die("Failed to mkdir %s: %m\n", put_old); if (syscall(SYS_pivot_root, ".", put_old)) die("Failed to pivot_root from %s to %s: %m\n", rootfs, put_old); if (chdir("/")) die("Failed to chdir to new root: %m\n"); procfs_prepare(); if (umount2(put_old, MNT_DETACH)) die("Failed to umount put_old %s: %m\n", put_old); if (rmdir(put_old)) die("Failed to rmdir: %m"); free(shared_folder); } void ro_fs(char* shared_mountpoint) { char* shared_folder = malloc(strlen(shared_mountpoint)+4); strcpy(shared_folder,"../"); strcat(shared_folder,shared_mountpoint); if (mount("/","/","ext4",MS_REMOUNT | MS_RDONLY | MS_BIND,"")) die("failed to mount: %m"); if (mount(shared_mountpoint,"shared","ext4",MS_REMOUNT | MS_RDONLY | MS_BIND,"")) die("failed to mount: %m"); free(shared_folder); } //#undef shared_mountpoint //#undef shared_folder #undef put_old void await_setup(int pipe) { // wait for signal from parent char buf[2]; if (read(pipe, buf, 2) != 2) die("Failed to read from pipe: %m\n"); } static int nsrun(void* arg) { //die when parent dies if (prctl(PR_SET_PDEATHSIG, SIGKILL)) die("cannot PR_SET_PDEATHSIG for child process: %m\n"); struct params *params = (struct params*) arg; await_setup(params->fd[0]); if(chdir("shared")) die("failed to chdir: %m"); //int out_fd=open("out",O_WRONLY|O_CREAT); //if(out_fd==-1) die("unable to open out file:%m"); //else dup2(out_fd,STDOUT_FILENO); if(chdir("..")) die("failed to chdir: %m"); mnt_prepare("minrootfs",params->shared_folder); sethostname(hostname,sizeof(hostname)); ro_fs(params->shared_folder); if(setgid(1000)) die("failed to setgid:%m"); if(setuid(1000)) die("failed to setuid:%m"); char** argv = params->argv; char* cmd = argv[0]; char* env[]={ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "PWD=/", NULL, }; if (execve(cmd,argv,env) == -1) die("failed to exec,%m"); return 1; }