78 lines
3.7 KiB
C
78 lines
3.7 KiB
C
#include<sys/prctl.h>
|
|
#include<sys/mount.h>
|
|
#include<sys/stat.h>
|
|
|
|
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: %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: %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) {
|
|
#define setup "./setup.sh"
|
|
//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]);
|
|
mnt_prepare("minrootfs",params->shared_folder);
|
|
//if(chdir("shared")) die("faled to chdir: %m");
|
|
sethostname(hostname,sizeof(hostname));
|
|
//if(chdir("..")) die("faled to chdir: %m");
|
|
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;
|
|
#undef setup
|
|
}
|