aboutsummaryrefslogtreecommitdiffstats
path: root/src/jailtest/noexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jailtest/noexec.c')
-rw-r--r--src/jailtest/noexec.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/jailtest/noexec.c b/src/jailtest/noexec.c
new file mode 100644
index 000000000..d2f85514a
--- /dev/null
+++ b/src/jailtest/noexec.c
@@ -0,0 +1,94 @@
1#include "jailtest.h"
2#include <sys/wait.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5
6static unsigned char *execfile = NULL;
7static int execfile_len = 0;
8
9void noexec_setup(void) {
10 // grab a copy of myself
11 char *self = realpath("/proc/self/exe", NULL);
12 if (self) {
13 struct stat s;
14 if (access(self, X_OK) == 0 && stat(self, &s) == 0) {
15 assert(s.st_size);
16 execfile = malloc(s.st_size);
17
18 int fd = open(self, O_RDONLY);
19 if (fd == -1)
20 errExit("open");
21 int len = 0;
22 do {
23 int rv = read(fd, execfile + len, s.st_size - len);
24 if (rv == -1)
25 errExit("read");
26 if (rv == 0) {
27 // something went wrong!
28 free(execfile);
29 execfile = NULL;
30 printf("Warning: I cannot grab a copy of myself, skipping noexec test...\n");
31 break;
32 }
33 len += rv;
34 }
35 while (len < s.st_size);
36 execfile_len = s.st_size;
37 close(fd);
38 }
39 }
40}
41
42
43void noexec_test(const char *path) {
44 assert(user_uid);
45
46 // I am root in sandbox mount namespace
47 if (!execfile)
48 return;
49
50 char *fname;
51 if (asprintf(&fname, "%s/jailtest-noexec-%d", path, getpid()) == -1)
52 errExit("asprintf");
53
54 pid_t child = fork();
55 if (child == -1)
56 errExit("fork");
57
58 if (child == 0) { // child
59 // drop privileges
60 if (setgid(user_gid) != 0)
61 errExit("setgid");
62 if (setuid(user_uid) != 0)
63 errExit("setuid");
64 int fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0700);
65 if (fd == -1) {
66 printf(" I cannot create files in %s, skipping noexec...\n", path);
67 exit(1);
68 }
69
70 int len = 0;
71 while (len < execfile_len) {
72 int rv = write(fd, execfile + len, execfile_len - len);
73 if (rv == -1 || rv == 0) {
74 printf(" I cannot create files in %s, skipping noexec....\n", path);
75 exit(1);
76 }
77 len += rv;
78 }
79 fchmod(fd, 0700);
80 close(fd);
81
82 char *arg;
83 if (asprintf(&arg, "--hello=%s", path) == -1)
84 errExit("asprintf");
85 int rv = execl(fname, fname, arg, NULL);
86 (void) rv; // if we get here execl failed
87 exit(0);
88 }
89
90 int status;
91 wait(&status);
92 int rv = unlink(fname);
93 (void) rv;
94} \ No newline at end of file