aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/netfilter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/netfilter.c')
-rw-r--r--src/firejail/netfilter.c111
1 files changed, 62 insertions, 49 deletions
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c
index 1df4b7a0f..0136ab1f8 100644
--- a/src/firejail/netfilter.c
+++ b/src/firejail/netfilter.c
@@ -69,31 +69,33 @@ void netfilter(const char *fname) {
69 if (netfilter_default) 69 if (netfilter_default)
70 fname = netfilter_default; 70 fname = netfilter_default;
71 if (fname) { 71 if (fname) {
72 // buffer the filter 72 assert(fname);
73 struct stat s; 73
74 if (stat(fname, &s) == -1) { 74 // open filter file
75 fprintf(stderr, "Error: cannot find network filter file %s\n", fname); 75 int fd = open(fname, O_RDONLY);
76 exit(1); 76 if (fd == -1)
77 } 77 goto errexit;
78 78 int size = lseek(fd, 0, SEEK_END);
79 filter = malloc(s.st_size + 1); // + '\0' 79 if (size == -1)
80 if (!filter) 80 goto errexit;
81 errExit("malloc"); 81 if (lseek(fd, 0 , SEEK_SET) == -1)
82 memset(filter, 0, s.st_size + 1); 82 goto errexit;
83 83
84 /* coverity[toctou] */ 84 // read filter
85 FILE *fp = fopen(fname, "r"); 85 filter = malloc(size + 1); // + '\0'
86 if (!fp) { 86 if (filter == NULL)
87 fprintf(stderr, "Error: cannot open network filter file %s\n", fname); 87 goto errexit;
88 exit(1); 88 memset(&filter[0], 0, sizeof(filter));
89 } 89 int rd = 0;
90 90 while (rd < size) {
91 size_t sz = fread(filter, 1, s.st_size, fp); 91 int rv = read(fd, (unsigned char *) filter + rd, size - rd);
92 if ((off_t)sz != s.st_size) { 92 if (rv == -1)
93 fprintf(stderr, "Error: cannot read network filter file %s\n", fname); 93 goto errexit;
94 exit(1); 94 rd += rv;
95 } 95 }
96 fclose(fp); 96
97 // close file
98 close(fd);
97 allocated = 1; 99 allocated = 1;
98 } 100 }
99 101
@@ -178,6 +180,11 @@ doexit:
178 180
179 if (allocated) 181 if (allocated)
180 free(filter); 182 free(filter);
183 return;
184
185errexit:
186 fprintf(stderr, "Error: cannot read network filter %s\n", fname);
187 exit(1);
181} 188}
182 189
183void netfilter6(const char *fname) { 190void netfilter6(const char *fname) {
@@ -186,38 +193,38 @@ void netfilter6(const char *fname) {
186 193
187 char *filter; 194 char *filter;
188 195
189 // buffer the filter 196 // open filter file
190 struct stat s; 197 int fd = open(fname, O_RDONLY);
191 if (stat(fname, &s) == -1) { 198 if (fd == -1)
192 fprintf(stderr, "Error: cannot find network filter file %s\n", fname); 199 goto errexit;
193 exit(1); 200 int size = lseek(fd, 0, SEEK_END);
194 } 201 if (size == -1)
195 202 goto errexit;
196 filter = malloc(s.st_size + 1); // + '\0' 203 if (lseek(fd, 0 , SEEK_SET) == -1)
197 if (!filter) 204 goto errexit;
198 errExit("malloc"); 205
199 memset(filter, 0, s.st_size + 1); 206 // read filter
200 207 filter = malloc(size + 1); // + '\0'
201 /* coverity[toctou] */ 208 if (filter == NULL)
202 FILE *fp = fopen(fname, "r"); 209 goto errexit;
203 if (!fp) { 210 memset(&filter[0], 0, sizeof(filter));
204 fprintf(stderr, "Error: cannot open network filter file %s\n", fname); 211 int rd = 0;
205 exit(1); 212 while (rd < size) {
206 } 213 int rv = read(fd, (unsigned char *) filter + rd, size - rd);
207 214 if (rv == -1)
208 size_t sz = fread(filter, 1, s.st_size, fp); 215 goto errexit;
209 if ((off_t)sz != s.st_size) { 216 rd += rv;
210 fprintf(stderr, "Error: cannot read network filter file %s\n", fname);
211 exit(1);
212 } 217 }
213 fclose(fp); 218
219 // close file
220 close(fd);
214 221
215 // temporarily mount a tempfs on top of /tmp directory 222 // temporarily mount a tempfs on top of /tmp directory
216 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 223 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
217 errExit("mounting /tmp"); 224 errExit("mounting /tmp");
218 225
219 // create the filter file 226 // create the filter file
220 fp = fopen("/tmp/netfilter6", "w"); 227 FILE *fp = fopen("/tmp/netfilter6", "w");
221 if (!fp) { 228 if (!fp) {
222 fprintf(stderr, "Error: cannot open /tmp/netfilter6 file\n"); 229 fprintf(stderr, "Error: cannot open /tmp/netfilter6 file\n");
223 exit(1); 230 exit(1);
@@ -228,6 +235,7 @@ void netfilter6(const char *fname) {
228 // find iptables command 235 // find iptables command
229 char *ip6tables = NULL; 236 char *ip6tables = NULL;
230 char *ip6tables_restore = NULL; 237 char *ip6tables_restore = NULL;
238 struct stat s;
231 if (stat("/sbin/ip6tables", &s) == 0) { 239 if (stat("/sbin/ip6tables", &s) == 0) {
232 ip6tables = "/sbin/ip6tables"; 240 ip6tables = "/sbin/ip6tables";
233 ip6tables_restore = "/sbin/ip6tables-restore"; 241 ip6tables_restore = "/sbin/ip6tables-restore";
@@ -284,4 +292,9 @@ doexit:
284 // unmount /tmp 292 // unmount /tmp
285 umount("/tmp"); 293 umount("/tmp");
286 free(filter); 294 free(filter);
295 return;
296
297errexit:
298 fprintf(stderr, "Error: cannot read network filter %s\n", fname);
299 exit(1);
287} 300}