diff options
author | netblue30 <netblue30@yahoo.com> | 2016-01-13 11:08:04 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-01-13 11:08:04 -0500 |
commit | bad6d369aeb682ba07d018927154cc833f0b9db6 (patch) | |
tree | 242e49b6349d23190d6ebc65677e71aaea4d215e /src/firejail/netfilter.c | |
parent | added kmail profile (diff) | |
download | firejail-bad6d369aeb682ba07d018927154cc833f0b9db6.tar.gz firejail-bad6d369aeb682ba07d018927154cc833f0b9db6.tar.zst firejail-bad6d369aeb682ba07d018927154cc833f0b9db6.zip |
ipv6 support
Diffstat (limited to 'src/firejail/netfilter.c')
-rw-r--r-- | src/firejail/netfilter.c | 111 |
1 files changed, 108 insertions, 3 deletions
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c index 3f667c871..70fd8801f 100644 --- a/src/firejail/netfilter.c +++ b/src/firejail/netfilter.c | |||
@@ -64,7 +64,7 @@ void netfilter(const char *fname) { | |||
64 | // buffer the filter | 64 | // buffer the filter |
65 | struct stat s; | 65 | struct stat s; |
66 | if (stat(fname, &s) == -1) { | 66 | if (stat(fname, &s) == -1) { |
67 | fprintf(stderr, "Error: cannot find network filter file\n"); | 67 | fprintf(stderr, "Error: cannot find network filter file %s\n", fname); |
68 | exit(1); | 68 | exit(1); |
69 | } | 69 | } |
70 | 70 | ||
@@ -76,13 +76,13 @@ void netfilter(const char *fname) { | |||
76 | /* coverity[toctou] */ | 76 | /* coverity[toctou] */ |
77 | FILE *fp = fopen(fname, "r"); | 77 | FILE *fp = fopen(fname, "r"); |
78 | if (!fp) { | 78 | if (!fp) { |
79 | fprintf(stderr, "Error: cannot open network filter file\n"); | 79 | fprintf(stderr, "Error: cannot open network filter file %s\n", fname); |
80 | exit(1); | 80 | exit(1); |
81 | } | 81 | } |
82 | 82 | ||
83 | size_t sz = fread(filter, 1, s.st_size, fp); | 83 | size_t sz = fread(filter, 1, s.st_size, fp); |
84 | if ((off_t)sz != s.st_size) { | 84 | if ((off_t)sz != s.st_size) { |
85 | fprintf(stderr, "Error: cannot read network filter file\n"); | 85 | fprintf(stderr, "Error: cannot read network filter file %s\n", fname); |
86 | exit(1); | 86 | exit(1); |
87 | } | 87 | } |
88 | fclose(fp); | 88 | fclose(fp); |
@@ -164,3 +164,108 @@ doexit: | |||
164 | if (allocated) | 164 | if (allocated) |
165 | free(filter); | 165 | free(filter); |
166 | } | 166 | } |
167 | |||
168 | void netfilter6(const char *fname) { | ||
169 | if (fname == NULL) | ||
170 | return; | ||
171 | |||
172 | char *filter; | ||
173 | |||
174 | // buffer the filter | ||
175 | struct stat s; | ||
176 | if (stat(fname, &s) == -1) { | ||
177 | fprintf(stderr, "Error: cannot find network filter file %s\n", fname); | ||
178 | exit(1); | ||
179 | } | ||
180 | |||
181 | filter = malloc(s.st_size + 1); // + '\0' | ||
182 | if (!filter) | ||
183 | errExit("malloc"); | ||
184 | memset(filter, 0, s.st_size + 1); | ||
185 | |||
186 | /* coverity[toctou] */ | ||
187 | FILE *fp = fopen(fname, "r"); | ||
188 | if (!fp) { | ||
189 | fprintf(stderr, "Error: cannot open network filter file %s\n", fname); | ||
190 | exit(1); | ||
191 | } | ||
192 | |||
193 | size_t sz = fread(filter, 1, s.st_size, fp); | ||
194 | if ((off_t)sz != s.st_size) { | ||
195 | fprintf(stderr, "Error: cannot read network filter file %s\n", fname); | ||
196 | exit(1); | ||
197 | } | ||
198 | fclose(fp); | ||
199 | |||
200 | // temporarily mount a tempfs on top of /tmp directory | ||
201 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
202 | errExit("mounting /tmp"); | ||
203 | |||
204 | // create the filter file | ||
205 | fp = fopen("/tmp/netfilter6", "w"); | ||
206 | if (!fp) { | ||
207 | fprintf(stderr, "Error: cannot open /tmp/netfilter6 file\n"); | ||
208 | exit(1); | ||
209 | } | ||
210 | fprintf(fp, "%s\n", filter); | ||
211 | fclose(fp); | ||
212 | |||
213 | // find iptables command | ||
214 | char *ip6tables = NULL; | ||
215 | char *ip6tables_restore = NULL; | ||
216 | if (stat("/sbin/ip6tables", &s) == 0) { | ||
217 | ip6tables = "/sbin/ip6tables"; | ||
218 | ip6tables_restore = "/sbin/ip6tables-restore"; | ||
219 | } | ||
220 | else if (stat("/usr/sbin/ip6tables", &s) == 0) { | ||
221 | ip6tables = "/usr/sbin/ip6tables"; | ||
222 | ip6tables_restore = "/usr/sbin/ip6tables-restore"; | ||
223 | } | ||
224 | if (ip6tables == NULL || ip6tables_restore == NULL) { | ||
225 | fprintf(stderr, "Error: ip6tables command not found\n"); | ||
226 | goto doexit; | ||
227 | } | ||
228 | |||
229 | // push filter | ||
230 | pid_t child = fork(); | ||
231 | if (child < 0) | ||
232 | errExit("fork"); | ||
233 | if (child == 0) { | ||
234 | if (arg_debug) | ||
235 | printf("Installing network filter:\n%s\n", filter); | ||
236 | |||
237 | int fd; | ||
238 | if((fd = open("/tmp/netfilter6", O_RDONLY)) == -1) { | ||
239 | fprintf(stderr,"Error: cannot open /tmp/netfilter6\n"); | ||
240 | exit(1); | ||
241 | } | ||
242 | dup2(fd,STDIN_FILENO); | ||
243 | close(fd); | ||
244 | |||
245 | // wipe out environment variables | ||
246 | environ = NULL; | ||
247 | execl(ip6tables_restore, ip6tables_restore, NULL); | ||
248 | // it will never get here!!! | ||
249 | } | ||
250 | // wait for the child to finish | ||
251 | waitpid(child, NULL, 0); | ||
252 | |||
253 | // debug | ||
254 | if (arg_debug) { | ||
255 | child = fork(); | ||
256 | if (child < 0) | ||
257 | errExit("fork"); | ||
258 | if (child == 0) { | ||
259 | environ = NULL; | ||
260 | execl(ip6tables, ip6tables, "-vL", NULL); | ||
261 | // it will never get here!!! | ||
262 | } | ||
263 | // wait for the child to finish | ||
264 | waitpid(child, NULL, 0); | ||
265 | } | ||
266 | |||
267 | doexit: | ||
268 | // unmount /tmp | ||
269 | umount("/tmp"); | ||
270 | free(filter); | ||
271 | } | ||