1 // SPDX-License-Identifier: GPL-2.0
12 #include <sys/ioctl.h>
13 #include <sys/prctl.h>
16 #define pr_err(fmt, ...) \
18 fprintf(stderr, "%s:%d:" fmt ": %m\n", \
19 __func__, __LINE__, ##__VA_ARGS__); \
24 #define NS_GET_USERNS _IO(NSIO, 0x1)
25 #define NS_GET_PARENT _IO(NSIO, 0x2)
27 #define __stack_aligned__ __attribute__((aligned(16)))
29 char stack
[128] __stack_aligned__
;
33 static int child(void *args
)
35 prctl(PR_SET_PDEATHSIG
, SIGKILL
);
41 int main(int argc
, char *argv
[])
43 char *ns_strs
[] = {"pid", "user"};
44 char path
[] = "/proc/0123456789/ns/pid";
45 struct cr_clone_arg ca
;
50 pid
= clone(child
, ca
.stack_ptr
, CLONE_NEWUSER
| CLONE_NEWPID
| SIGCHLD
, NULL
);
52 return pr_err("clone");
54 for (i
= 0; i
< 2; i
++) {
55 snprintf(path
, sizeof(path
), "/proc/%d/ns/%s", pid
, ns_strs
[i
]);
56 ns
= open(path
, O_RDONLY
);
58 return pr_err("Unable to open %s", path
);
60 pns
= ioctl(ns
, NS_GET_PARENT
);
62 return pr_err("Unable to get a parent pidns");
64 snprintf(path
, sizeof(path
), "/proc/self/ns/%s", ns_strs
[i
]);
66 return pr_err("Unable to stat %s", path
);
68 return pr_err("Unable to stat the parent pidns");
69 if (st1
.st_ino
!= st2
.st_ino
)
70 return pr_err("NS_GET_PARENT returned a wrong namespace");
72 if (ioctl(pns
, NS_GET_PARENT
) >= 0 || errno
!= EPERM
)
73 return pr_err("Don't get EPERM");