1*268af17aSAlexey Dobriyan /*
2*268af17aSAlexey Dobriyan * Copyright (c) 2021 Alexey Dobriyan <adobriyan@gmail.com>
3*268af17aSAlexey Dobriyan *
4*268af17aSAlexey Dobriyan * Permission to use, copy, modify, and distribute this software for any
5*268af17aSAlexey Dobriyan * purpose with or without fee is hereby granted, provided that the above
6*268af17aSAlexey Dobriyan * copyright notice and this permission notice appear in all copies.
7*268af17aSAlexey Dobriyan *
8*268af17aSAlexey Dobriyan * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*268af17aSAlexey Dobriyan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*268af17aSAlexey Dobriyan * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*268af17aSAlexey Dobriyan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*268af17aSAlexey Dobriyan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*268af17aSAlexey Dobriyan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*268af17aSAlexey Dobriyan * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*268af17aSAlexey Dobriyan */
16*268af17aSAlexey Dobriyan /*
17*268af17aSAlexey Dobriyan * Test that "mount -t proc -o subset=pid" hides everything but pids,
18*268af17aSAlexey Dobriyan * /proc/self and /proc/thread-self.
19*268af17aSAlexey Dobriyan */
20*268af17aSAlexey Dobriyan #undef NDEBUG
21*268af17aSAlexey Dobriyan #include <assert.h>
22*268af17aSAlexey Dobriyan #include <errno.h>
23*268af17aSAlexey Dobriyan #include <sched.h>
24*268af17aSAlexey Dobriyan #include <stdbool.h>
25*268af17aSAlexey Dobriyan #include <stdlib.h>
26*268af17aSAlexey Dobriyan #include <string.h>
27*268af17aSAlexey Dobriyan #include <sys/mount.h>
28*268af17aSAlexey Dobriyan #include <sys/types.h>
29*268af17aSAlexey Dobriyan #include <sys/stat.h>
30*268af17aSAlexey Dobriyan #include <fcntl.h>
31*268af17aSAlexey Dobriyan #include <dirent.h>
32*268af17aSAlexey Dobriyan #include <unistd.h>
33*268af17aSAlexey Dobriyan #include <stdio.h>
34*268af17aSAlexey Dobriyan
streq(const char * a,const char * b)35*268af17aSAlexey Dobriyan static inline bool streq(const char *a, const char *b)
36*268af17aSAlexey Dobriyan {
37*268af17aSAlexey Dobriyan return strcmp(a, b) == 0;
38*268af17aSAlexey Dobriyan }
39*268af17aSAlexey Dobriyan
make_private_proc(void)40*268af17aSAlexey Dobriyan static void make_private_proc(void)
41*268af17aSAlexey Dobriyan {
42*268af17aSAlexey Dobriyan if (unshare(CLONE_NEWNS) == -1) {
43*268af17aSAlexey Dobriyan if (errno == ENOSYS || errno == EPERM) {
44*268af17aSAlexey Dobriyan exit(4);
45*268af17aSAlexey Dobriyan }
46*268af17aSAlexey Dobriyan exit(1);
47*268af17aSAlexey Dobriyan }
48*268af17aSAlexey Dobriyan if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) {
49*268af17aSAlexey Dobriyan exit(1);
50*268af17aSAlexey Dobriyan }
51*268af17aSAlexey Dobriyan if (mount(NULL, "/proc", "proc", 0, "subset=pid") == -1) {
52*268af17aSAlexey Dobriyan exit(1);
53*268af17aSAlexey Dobriyan }
54*268af17aSAlexey Dobriyan }
55*268af17aSAlexey Dobriyan
string_is_pid(const char * s)56*268af17aSAlexey Dobriyan static bool string_is_pid(const char *s)
57*268af17aSAlexey Dobriyan {
58*268af17aSAlexey Dobriyan while (1) {
59*268af17aSAlexey Dobriyan switch (*s++) {
60*268af17aSAlexey Dobriyan case '0':case '1':case '2':case '3':case '4':
61*268af17aSAlexey Dobriyan case '5':case '6':case '7':case '8':case '9':
62*268af17aSAlexey Dobriyan continue;
63*268af17aSAlexey Dobriyan
64*268af17aSAlexey Dobriyan case '\0':
65*268af17aSAlexey Dobriyan return true;
66*268af17aSAlexey Dobriyan
67*268af17aSAlexey Dobriyan default:
68*268af17aSAlexey Dobriyan return false;
69*268af17aSAlexey Dobriyan }
70*268af17aSAlexey Dobriyan }
71*268af17aSAlexey Dobriyan }
72*268af17aSAlexey Dobriyan
main(void)73*268af17aSAlexey Dobriyan int main(void)
74*268af17aSAlexey Dobriyan {
75*268af17aSAlexey Dobriyan make_private_proc();
76*268af17aSAlexey Dobriyan
77*268af17aSAlexey Dobriyan DIR *d = opendir("/proc");
78*268af17aSAlexey Dobriyan assert(d);
79*268af17aSAlexey Dobriyan
80*268af17aSAlexey Dobriyan struct dirent *de;
81*268af17aSAlexey Dobriyan
82*268af17aSAlexey Dobriyan bool dot = false;
83*268af17aSAlexey Dobriyan bool dot_dot = false;
84*268af17aSAlexey Dobriyan bool self = false;
85*268af17aSAlexey Dobriyan bool thread_self = false;
86*268af17aSAlexey Dobriyan
87*268af17aSAlexey Dobriyan while ((de = readdir(d))) {
88*268af17aSAlexey Dobriyan if (streq(de->d_name, ".")) {
89*268af17aSAlexey Dobriyan assert(!dot);
90*268af17aSAlexey Dobriyan dot = true;
91*268af17aSAlexey Dobriyan assert(de->d_type == DT_DIR);
92*268af17aSAlexey Dobriyan } else if (streq(de->d_name, "..")) {
93*268af17aSAlexey Dobriyan assert(!dot_dot);
94*268af17aSAlexey Dobriyan dot_dot = true;
95*268af17aSAlexey Dobriyan assert(de->d_type == DT_DIR);
96*268af17aSAlexey Dobriyan } else if (streq(de->d_name, "self")) {
97*268af17aSAlexey Dobriyan assert(!self);
98*268af17aSAlexey Dobriyan self = true;
99*268af17aSAlexey Dobriyan assert(de->d_type == DT_LNK);
100*268af17aSAlexey Dobriyan } else if (streq(de->d_name, "thread-self")) {
101*268af17aSAlexey Dobriyan assert(!thread_self);
102*268af17aSAlexey Dobriyan thread_self = true;
103*268af17aSAlexey Dobriyan assert(de->d_type == DT_LNK);
104*268af17aSAlexey Dobriyan } else {
105*268af17aSAlexey Dobriyan if (!string_is_pid(de->d_name)) {
106*268af17aSAlexey Dobriyan fprintf(stderr, "d_name '%s'\n", de->d_name);
107*268af17aSAlexey Dobriyan assert(0);
108*268af17aSAlexey Dobriyan }
109*268af17aSAlexey Dobriyan assert(de->d_type == DT_DIR);
110*268af17aSAlexey Dobriyan }
111*268af17aSAlexey Dobriyan }
112*268af17aSAlexey Dobriyan
113*268af17aSAlexey Dobriyan char c;
114*268af17aSAlexey Dobriyan int rv = readlink("/proc/cpuinfo", &c, 1);
115*268af17aSAlexey Dobriyan assert(rv == -1 && errno == ENOENT);
116*268af17aSAlexey Dobriyan
117*268af17aSAlexey Dobriyan int fd = open("/proc/cpuinfo", O_RDONLY);
118*268af17aSAlexey Dobriyan assert(fd == -1 && errno == ENOENT);
119*268af17aSAlexey Dobriyan
120*268af17aSAlexey Dobriyan return 0;
121*268af17aSAlexey Dobriyan }
122