diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/fs_hostname.c | 101 |
2 files changed, 78 insertions, 25 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index c6c6c76cc..b0b7e4e77 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -52,6 +52,8 @@ | |||
52 | #define RUN_LIB_DIR "/run/firejail/mnt/lib" | 52 | #define RUN_LIB_DIR "/run/firejail/mnt/lib" |
53 | #define RUN_LIB_FILE "/run/firejail/mnt/libfiles" | 53 | #define RUN_LIB_FILE "/run/firejail/mnt/libfiles" |
54 | #define RUN_LIB_BIN "/run/firejail/mnt/binfiles" | 54 | #define RUN_LIB_BIN "/run/firejail/mnt/binfiles" |
55 | #define RUN_DNS_ETC "/run/firejail/mnt/dns-etc" | ||
56 | |||
55 | 57 | ||
56 | #define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" // protocol filter | 58 | #define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" // protocol filter |
57 | #define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" // configured filter | 59 | #define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" // configured filter |
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c index 15c8f5e36..97ce468a6 100644 --- a/src/firejail/fs_hostname.c +++ b/src/firejail/fs_hostname.c | |||
@@ -92,39 +92,90 @@ void fs_resolvconf(void) { | |||
92 | if (cfg.dns1 == 0) | 92 | if (cfg.dns1 == 0) |
93 | return; | 93 | return; |
94 | 94 | ||
95 | struct stat s; | 95 | if (arg_debug) |
96 | printf("mirroring /etc directory\n"); | ||
97 | if (mkdir(RUN_DNS_ETC, 0755)) | ||
98 | errExit("mkdir"); | ||
99 | fs_logger("tmpfs /etc"); | ||
96 | 100 | ||
97 | // create a new /etc/resolv.conf | 101 | DIR *dir = opendir("/etc"); |
98 | if (stat("/etc/resolv.conf", &s) == 0) { | 102 | if (!dir) |
99 | if (arg_debug) | 103 | errExit("opendir"); |
100 | printf("Creating a new /etc/resolv.conf file\n"); | 104 | |
101 | FILE *fp = fopen(RUN_RESOLVCONF_FILE, "w"); | 105 | struct stat s; |
102 | if (!fp) { | 106 | struct dirent *entry; |
103 | fprintf(stderr, "Error: cannot create %s\n", RUN_RESOLVCONF_FILE); | 107 | while ((entry = readdir(dir))) { |
104 | exit(1); | 108 | if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) |
109 | continue; | ||
110 | // for resolv.conf we create a brand new file | ||
111 | if (strcmp(entry->d_name, "resolv.conf") == 0) | ||
112 | continue; | ||
113 | // printf("linking %s\n", entry->d_name); | ||
114 | |||
115 | char *src; | ||
116 | if (asprintf(&src, "/etc/%s", entry->d_name) == -1) | ||
117 | errExit("asprintf"); | ||
118 | if (stat(src, &s) != 0) { | ||
119 | free(src); | ||
120 | continue; | ||
105 | } | 121 | } |
106 | 122 | ||
107 | if (cfg.dns1) | 123 | char *dest; |
108 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns1)); | 124 | if (asprintf(&dest, "%s/%s", RUN_DNS_ETC, entry->d_name) == -1) |
109 | if (cfg.dns2) | 125 | errExit("asprintf"); |
110 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2)); | ||
111 | if (cfg.dns3) | ||
112 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3)); | ||
113 | 126 | ||
114 | // mode and owner | 127 | if (is_link(src)) { |
115 | SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH); | 128 | char *rp =realpath(src, NULL); |
129 | if (rp == NULL) { | ||
130 | free(src); | ||
131 | free(dest); | ||
132 | continue; | ||
133 | } | ||
134 | if (symlink(rp, dest)) | ||
135 | errExit("symlink"); | ||
136 | } | ||
137 | else if (S_ISDIR(s.st_mode)) | ||
138 | create_empty_dir_as_root(dest, s.st_mode); | ||
139 | else | ||
140 | create_empty_file_as_root(dest, s.st_mode); | ||
141 | // bind-mount src on top of dest | ||
142 | if (mount(src, dest, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
143 | errExit("mount bind mirroring /etc"); | ||
144 | fs_logger2("clone", src); | ||
145 | |||
146 | free(src); | ||
147 | free(dest); | ||
148 | } | ||
149 | closedir(dir); | ||
116 | 150 | ||
117 | fclose(fp); | 151 | // mount bind our private etc directory on top of /etc |
152 | if (arg_debug) | ||
153 | printf("Mount-bind %s on top of /etc\n", RUN_DNS_ETC); | ||
154 | if (mount(RUN_DNS_ETC, "/etc", NULL, MS_BIND|MS_REC, NULL) < 0) | ||
155 | errExit("mount bind mirroring /etc"); | ||
156 | fs_logger("mount /etc"); | ||
118 | 157 | ||
119 | // bind-mount the file on top of /etc/hostname | 158 | if (arg_debug) |
120 | if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0) | 159 | printf("Creating a new /etc/resolv.conf file\n"); |
121 | errExit("mount bind /etc/resolv.conf"); | 160 | FILE *fp = fopen("/etc/resolv.conf", "w"); |
122 | fs_logger("create /etc/resolv.conf"); | 161 | if (!fp) { |
123 | } | 162 | fprintf(stderr, "Error: cannot create /etc/resolv.conf file\n"); |
124 | else { | ||
125 | fprintf(stderr, "Error: cannot set DNS servers, /etc/resolv.conf file is missing\n"); | ||
126 | exit(1); | 163 | exit(1); |
127 | } | 164 | } |
165 | |||
166 | if (cfg.dns1) | ||
167 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns1)); | ||
168 | if (cfg.dns2) | ||
169 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2)); | ||
170 | if (cfg.dns3) | ||
171 | fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3)); | ||
172 | |||
173 | // mode and owner | ||
174 | SET_PERMS_STREAM(fp, 0, 0, 0644); | ||
175 | |||
176 | fclose(fp); | ||
177 | |||
178 | fs_logger("create /etc/resolv.conf"); | ||
128 | } | 179 | } |
129 | 180 | ||
130 | char *fs_check_hosts_file(const char *fname) { | 181 | char *fs_check_hosts_file(const char *fname) { |