aboutsummaryrefslogtreecommitdiff
path: root/main.c
blob: a20f6ff980d6ad54819d8464f3fd236e09de213c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/types.h>
#include <sched.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include "utils.h"

void sigint_handler(int sig) { }

int main(int argc, char **argv) {
	pid_t ppid = getpid();

	if (!fork()) {
		system(aprintf("newuidmap %d 0 %d 1 1 65537 65536", ppid, getuid()));
		system(aprintf("newgidmap %d 0 %d 1 1 65537 65536", ppid, getgid()));
		kill(ppid, SIGINT);
		return 0;
	}

	unshare(CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWPID);

	signal(SIGINT, sigint_handler);
	pause();
	errno = 0; // Just clear error from pause()

	pid_t chpid = fork();
	if (chpid) {
		int stat;
		waitpid(chpid, &stat, 0);
		return stat;
	}

	// mount /sys and /proc
	mount("none", "/", NULL, MS_REC | MS_PRIVATE, NULL);
	assert_perror(errno);
	mount("none", "/proc", NULL, MS_REC | MS_PRIVATE, NULL);
	assert_perror(errno);
	mount("none", "/sys", NULL, MS_REC | MS_PRIVATE, NULL);
	assert_perror(errno);
	mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL);
	assert_perror(errno);

	// mount proc to root
	// rbind mount dev and sys to root

	// TODO verify that all upper directories have +rx rights
	// TODO chroot
	execv("/bin/sh", NULL);
}