0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #undef NDEBUG
0021 #include <assert.h>
0022 #include <errno.h>
0023 #include <sched.h>
0024 #include <stdbool.h>
0025 #include <stdlib.h>
0026 #include <string.h>
0027 #include <sys/mount.h>
0028 #include <sys/types.h>
0029 #include <sys/stat.h>
0030 #include <fcntl.h>
0031 #include <dirent.h>
0032 #include <unistd.h>
0033 #include <stdio.h>
0034
0035 static inline bool streq(const char *a, const char *b)
0036 {
0037 return strcmp(a, b) == 0;
0038 }
0039
0040 static void make_private_proc(void)
0041 {
0042 if (unshare(CLONE_NEWNS) == -1) {
0043 if (errno == ENOSYS || errno == EPERM) {
0044 exit(4);
0045 }
0046 exit(1);
0047 }
0048 if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) == -1) {
0049 exit(1);
0050 }
0051 if (mount(NULL, "/proc", "proc", 0, "subset=pid") == -1) {
0052 exit(1);
0053 }
0054 }
0055
0056 static bool string_is_pid(const char *s)
0057 {
0058 while (1) {
0059 switch (*s++) {
0060 case '0':case '1':case '2':case '3':case '4':
0061 case '5':case '6':case '7':case '8':case '9':
0062 continue;
0063
0064 case '\0':
0065 return true;
0066
0067 default:
0068 return false;
0069 }
0070 }
0071 }
0072
0073 int main(void)
0074 {
0075 make_private_proc();
0076
0077 DIR *d = opendir("/proc");
0078 assert(d);
0079
0080 struct dirent *de;
0081
0082 bool dot = false;
0083 bool dot_dot = false;
0084 bool self = false;
0085 bool thread_self = false;
0086
0087 while ((de = readdir(d))) {
0088 if (streq(de->d_name, ".")) {
0089 assert(!dot);
0090 dot = true;
0091 assert(de->d_type == DT_DIR);
0092 } else if (streq(de->d_name, "..")) {
0093 assert(!dot_dot);
0094 dot_dot = true;
0095 assert(de->d_type == DT_DIR);
0096 } else if (streq(de->d_name, "self")) {
0097 assert(!self);
0098 self = true;
0099 assert(de->d_type == DT_LNK);
0100 } else if (streq(de->d_name, "thread-self")) {
0101 assert(!thread_self);
0102 thread_self = true;
0103 assert(de->d_type == DT_LNK);
0104 } else {
0105 if (!string_is_pid(de->d_name)) {
0106 fprintf(stderr, "d_name '%s'\n", de->d_name);
0107 assert(0);
0108 }
0109 assert(de->d_type == DT_DIR);
0110 }
0111 }
0112
0113 char c;
0114 int rv = readlink("/proc/cpuinfo", &c, 1);
0115 assert(rv == -1 && errno == ENOENT);
0116
0117 int fd = open("/proc/cpuinfo", O_RDONLY);
0118 assert(fd == -1 && errno == ENOENT);
0119
0120 return 0;
0121 }