aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/netfilter.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-01-13 11:08:04 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2016-01-13 11:08:04 -0500
commitbad6d369aeb682ba07d018927154cc833f0b9db6 (patch)
tree242e49b6349d23190d6ebc65677e71aaea4d215e /src/firejail/netfilter.c
parentadded kmail profile (diff)
downloadfirejail-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.c111
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
168void 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
267doexit:
268 // unmount /tmp
269 umount("/tmp");
270 free(filter);
271}