Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / tools / testing / selftests / nsfs / owner.c
1 #define _GNU_SOURCE
2 #include <sched.h>
3 #include <unistd.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <signal.h>
7 #include <errno.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <sys/ioctl.h>
12 #include <sys/prctl.h>
13 #include <sys/wait.h>
14
15 #define NSIO    0xb7
16 #define NS_GET_USERNS   _IO(NSIO, 0x1)
17
18 #define pr_err(fmt, ...) \
19                 ({ \
20                         fprintf(stderr, "%s:%d:" fmt ": %m\n", \
21                                 __func__, __LINE__, ##__VA_ARGS__); \
22                         1; \
23                 })
24
25 int main(int argc, char *argvp[])
26 {
27         int pfd[2], ns, uns, init_uns;
28         struct stat st1, st2;
29         char path[128];
30         pid_t pid;
31         char c;
32
33         if (pipe(pfd))
34                 return 1;
35
36         pid = fork();
37         if (pid < 0)
38                 return pr_err("fork");
39         if (pid == 0) {
40                 prctl(PR_SET_PDEATHSIG, SIGKILL);
41                 if (unshare(CLONE_NEWUTS | CLONE_NEWUSER))
42                         return pr_err("unshare");
43                 close(pfd[0]);
44                 close(pfd[1]);
45                 while (1)
46                         sleep(1);
47                 return 0;
48         }
49         close(pfd[1]);
50         if (read(pfd[0], &c, 1) != 0)
51                 return pr_err("Unable to read from pipe");
52         close(pfd[0]);
53
54         snprintf(path, sizeof(path), "/proc/%d/ns/uts", pid);
55         ns = open(path, O_RDONLY);
56         if (ns < 0)
57                 return pr_err("Unable to open %s", path);
58
59         uns = ioctl(ns, NS_GET_USERNS);
60         if (uns < 0)
61                 return pr_err("Unable to get an owning user namespace");
62
63         if (fstat(uns, &st1))
64                 return pr_err("fstat");
65
66         snprintf(path, sizeof(path), "/proc/%d/ns/user", pid);
67         if (stat(path, &st2))
68                 return pr_err("stat");
69
70         if (st1.st_ino != st2.st_ino)
71                 return pr_err("NS_GET_USERNS returned a wrong namespace");
72
73         init_uns = ioctl(uns, NS_GET_USERNS);
74         if (uns < 0)
75                 return pr_err("Unable to get an owning user namespace");
76
77         if (ioctl(init_uns, NS_GET_USERNS) >= 0 || errno != EPERM)
78                 return pr_err("Don't get EPERM");
79
80         if (unshare(CLONE_NEWUSER))
81                 return pr_err("unshare");
82
83         if (ioctl(ns, NS_GET_USERNS) >= 0 || errno != EPERM)
84                 return pr_err("Don't get EPERM");
85         if (ioctl(init_uns, NS_GET_USERNS) >= 0 || errno != EPERM)
86                 return pr_err("Don't get EPERM");
87
88         kill(pid, SIGKILL);
89         wait(NULL);
90         return 0;
91 }