diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/faudit/syscall.c | 3 | ||||
-rw-r--r-- | src/firejail/checkcfg.c | 9 | ||||
-rw-r--r-- | src/firejail/firejail.h | 5 | ||||
-rw-r--r-- | src/firejail/ls.c | 10 | ||||
-rw-r--r-- | src/firejail/netfilter.c | 231 | ||||
-rw-r--r-- | src/firejail/sbox.c | 34 | ||||
-rw-r--r-- | src/firejail/seccomp.c | 2 | ||||
-rw-r--r-- | src/firejail/util.c | 42 | ||||
-rw-r--r-- | src/firejail/x11.c | 3 | ||||
-rw-r--r-- | src/fseccomp/seccomp_print.c | 2 |
10 files changed, 133 insertions, 208 deletions
diff --git a/src/faudit/syscall.c b/src/faudit/syscall.c index 3c87305df..4cd2526ba 100644 --- a/src/faudit/syscall.c +++ b/src/faudit/syscall.c | |||
@@ -35,7 +35,8 @@ void syscall_helper(int argc, char **argv) { | |||
35 | (void) argc; | 35 | (void) argc; |
36 | 36 | ||
37 | if (strcmp(argv[2], "mount") == 0) { | 37 | if (strcmp(argv[2], "mount") == 0) { |
38 | mount(NULL, NULL, NULL, 0, NULL); | 38 | int rv = mount(NULL, NULL, NULL, 0, NULL); |
39 | (void) rv; | ||
39 | printf("\nUGLY: mount syscall permitted.\n"); | 40 | printf("\nUGLY: mount syscall permitted.\n"); |
40 | } | 41 | } |
41 | else if (strcmp(argv[2], "umount2") == 0) { | 42 | else if (strcmp(argv[2], "umount2") == 0) { |
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index 974fbb8a3..6565f488a 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c | |||
@@ -33,6 +33,7 @@ int checkcfg(int val) { | |||
33 | assert(val < CFG_MAX); | 33 | assert(val < CFG_MAX); |
34 | int line = 0; | 34 | int line = 0; |
35 | FILE *fp = NULL; | 35 | FILE *fp = NULL; |
36 | char *ptr; | ||
36 | 37 | ||
37 | if (!initialized) { | 38 | if (!initialized) { |
38 | // initialize defaults | 39 | // initialize defaults |
@@ -76,7 +77,7 @@ int checkcfg(int val) { | |||
76 | continue; | 77 | continue; |
77 | 78 | ||
78 | // parse line | 79 | // parse line |
79 | char *ptr = line_remove_spaces(buf); | 80 | ptr = line_remove_spaces(buf); |
80 | if (!ptr) | 81 | if (!ptr) |
81 | continue; | 82 | continue; |
82 | 83 | ||
@@ -286,8 +287,10 @@ int checkcfg(int val) { | |||
286 | return cfg_val[val]; | 287 | return cfg_val[val]; |
287 | 288 | ||
288 | errout: | 289 | errout: |
289 | if (fp) | 290 | assert(ptr); |
290 | fclose(fp); | 291 | free(ptr); |
292 | assert(fp); | ||
293 | fclose(fp); | ||
291 | fprintf(stderr, "Error: invalid line %d in firejail configuration file\n", line ); | 294 | fprintf(stderr, "Error: invalid line %d in firejail configuration file\n", line ); |
292 | exit(1); | 295 | exit(1); |
293 | } | 296 | } |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 4ae3cfd9f..61de17bf8 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -41,7 +41,6 @@ | |||
41 | #define RUN_CPU_CFG "/run/firejail/mnt/cpu" | 41 | #define RUN_CPU_CFG "/run/firejail/mnt/cpu" |
42 | #define RUN_GROUPS_CFG "/run/firejail/mnt/groups" | 42 | #define RUN_GROUPS_CFG "/run/firejail/mnt/groups" |
43 | #define RUN_PROTOCOL_CFG "/run/firejail/mnt/protocol" | 43 | #define RUN_PROTOCOL_CFG "/run/firejail/mnt/protocol" |
44 | #define RUN_CP_COMMAND "/run/firejail/mnt/cp" | ||
45 | #define RUN_HOME_DIR "/run/firejail/mnt/home" | 44 | #define RUN_HOME_DIR "/run/firejail/mnt/home" |
46 | #define RUN_ETC_DIR "/run/firejail/mnt/etc" | 45 | #define RUN_ETC_DIR "/run/firejail/mnt/etc" |
47 | #define RUN_BIN_DIR "/run/firejail/mnt/bin" | 46 | #define RUN_BIN_DIR "/run/firejail/mnt/bin" |
@@ -463,6 +462,7 @@ void create_empty_dir_as_root(const char *dir, mode_t mode); | |||
463 | void create_empty_file_as_root(const char *dir, mode_t mode); | 462 | void create_empty_file_as_root(const char *dir, mode_t mode); |
464 | int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode); | 463 | int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode); |
465 | void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid); | 464 | void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid); |
465 | char *read_text_file_or_exit(const char *fname); | ||
466 | 466 | ||
467 | // fs_var.c | 467 | // fs_var.c |
468 | void fs_var_log(void); // mounting /var/log | 468 | void fs_var_log(void); // mounting /var/log |
@@ -679,6 +679,8 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar | |||
679 | #define PATH_FIREMON (PREFIX "/bin/firemon") | 679 | #define PATH_FIREMON (PREFIX "/bin/firemon") |
680 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") | 680 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") |
681 | #define PATH_FCOPY (LIBDIR "/firejail/fcopy") | 681 | #define PATH_FCOPY (LIBDIR "/firejail/fcopy") |
682 | #define SBOX_STDIN_FILE "/run/firejail/mnt/sbox_stdin" | ||
683 | |||
682 | // bitmapped filters for sbox_run | 684 | // bitmapped filters for sbox_run |
683 | #define SBOX_ROOT (1 << 0) // run the sandbox as root | 685 | #define SBOX_ROOT (1 << 0) // run the sandbox as root |
684 | #define SBOX_USER (1 << 1) // run the sandbox as a regular user | 686 | #define SBOX_USER (1 << 1) // run the sandbox as a regular user |
@@ -686,6 +688,7 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar | |||
686 | #define SBOX_CAPS_NONE (1 << 3) // drop all capabilities | 688 | #define SBOX_CAPS_NONE (1 << 3) // drop all capabilities |
687 | #define SBOX_CAPS_NETWORK (1 << 4) // caps filter for programs running network programs | 689 | #define SBOX_CAPS_NETWORK (1 << 4) // caps filter for programs running network programs |
688 | #define SBOX_ALLOW_STDIN (1 << 5) // don't close stdin | 690 | #define SBOX_ALLOW_STDIN (1 << 5) // don't close stdin |
691 | #define SBOX_STDIN_FROM_FILE (1 << 6) // open file and redirect it to stdin | ||
689 | 692 | ||
690 | // run sbox | 693 | // run sbox |
691 | int sbox_run(unsigned filter, int num, ...); | 694 | int sbox_run(unsigned filter, int num, ...); |
diff --git a/src/firejail/ls.c b/src/firejail/ls.c index 4b4ae1de2..77eb35f97 100644 --- a/src/firejail/ls.c +++ b/src/firejail/ls.c | |||
@@ -259,11 +259,11 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
259 | drop_privs(0); | 259 | drop_privs(0); |
260 | 260 | ||
261 | // check access | 261 | // check access |
262 | /* coverity[toctou] */ | ||
263 | if (access(fname1, R_OK) == -1) { | 262 | if (access(fname1, R_OK) == -1) { |
264 | fprintf(stderr, "Error: Cannot access %s\n", fname1); | 263 | fprintf(stderr, "Error: Cannot access %s\n", fname1); |
265 | exit(1); | 264 | exit(1); |
266 | } | 265 | } |
266 | /* coverity[toctou] */ | ||
267 | char *rp = realpath(fname1, NULL); | 267 | char *rp = realpath(fname1, NULL); |
268 | if (!rp) { | 268 | if (!rp) { |
269 | fprintf(stderr, "Error: Cannot access %s\n", fname1); | 269 | fprintf(stderr, "Error: Cannot access %s\n", fname1); |
@@ -316,9 +316,11 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) { | |||
316 | // create a user-owned temporary file in /run/firejail directory | 316 | // create a user-owned temporary file in /run/firejail directory |
317 | char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; | 317 | char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; |
318 | int fd = mkstemp(tmp_fname); | 318 | int fd = mkstemp(tmp_fname); |
319 | SET_PERMS_FD(fd, getuid(), getgid(), 0600); | 319 | if (fd != -1) { |
320 | close(fd); | 320 | SET_PERMS_FD(fd, getuid(), getgid(), 0600); |
321 | 321 | close(fd); | |
322 | } | ||
323 | |||
322 | // copy the source file into the temporary file - we need to chroot | 324 | // copy the source file into the temporary file - we need to chroot |
323 | pid_t child = fork(); | 325 | pid_t child = fork(); |
324 | if (child < 0) | 326 | if (child < 0) |
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c index 0136ab1f8..ef4915f15 100644 --- a/src/firejail/netfilter.c +++ b/src/firejail/netfilter.c | |||
@@ -61,57 +61,6 @@ void check_netfilter_file(const char *fname) { | |||
61 | 61 | ||
62 | 62 | ||
63 | void netfilter(const char *fname) { | 63 | void netfilter(const char *fname) { |
64 | // default filter | ||
65 | char *filter = client_filter; | ||
66 | |||
67 | // custom filter | ||
68 | int allocated = 0; | ||
69 | if (netfilter_default) | ||
70 | fname = netfilter_default; | ||
71 | if (fname) { | ||
72 | assert(fname); | ||
73 | |||
74 | // open filter file | ||
75 | int fd = open(fname, O_RDONLY); | ||
76 | if (fd == -1) | ||
77 | goto errexit; | ||
78 | int size = lseek(fd, 0, SEEK_END); | ||
79 | if (size == -1) | ||
80 | goto errexit; | ||
81 | if (lseek(fd, 0 , SEEK_SET) == -1) | ||
82 | goto errexit; | ||
83 | |||
84 | // read filter | ||
85 | filter = malloc(size + 1); // + '\0' | ||
86 | if (filter == NULL) | ||
87 | goto errexit; | ||
88 | memset(&filter[0], 0, sizeof(filter)); | ||
89 | int rd = 0; | ||
90 | while (rd < size) { | ||
91 | int rv = read(fd, (unsigned char *) filter + rd, size - rd); | ||
92 | if (rv == -1) | ||
93 | goto errexit; | ||
94 | rd += rv; | ||
95 | } | ||
96 | |||
97 | // close file | ||
98 | close(fd); | ||
99 | allocated = 1; | ||
100 | } | ||
101 | |||
102 | // temporarily mount a tempfs on top of /tmp directory | ||
103 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
104 | errExit("mounting /tmp"); | ||
105 | |||
106 | // create the filter file | ||
107 | FILE *fp = fopen("/tmp/netfilter", "w"); | ||
108 | if (!fp) { | ||
109 | fprintf(stderr, "Error: cannot open /tmp/netfilter file\n"); | ||
110 | exit(1); | ||
111 | } | ||
112 | fprintf(fp, "%s\n", filter); | ||
113 | fclose(fp); | ||
114 | |||
115 | // find iptables command | 64 | // find iptables command |
116 | struct stat s; | 65 | struct stat s; |
117 | char *iptables = NULL; | 66 | char *iptables = NULL; |
@@ -125,113 +74,49 @@ void netfilter(const char *fname) { | |||
125 | iptables_restore = "/usr/sbin/iptables-restore"; | 74 | iptables_restore = "/usr/sbin/iptables-restore"; |
126 | } | 75 | } |
127 | if (iptables == NULL || iptables_restore == NULL) { | 76 | if (iptables == NULL || iptables_restore == NULL) { |
128 | fprintf(stderr, "Error: iptables command not found\n"); | 77 | fprintf(stderr, "Error: iptables command not found, netfilter not configured\n"); |
129 | goto doexit; | 78 | return; |
130 | } | 79 | } |
131 | 80 | ||
132 | // push filter | 81 | // read filter |
133 | pid_t child = fork(); | 82 | char *filter = client_filter; |
134 | if (child < 0) | 83 | int allocated = 0; |
135 | errExit("fork"); | 84 | if (netfilter_default) |
136 | if (child == 0) { | 85 | fname = netfilter_default; |
137 | if (arg_debug) | 86 | if (fname) { |
138 | printf("Installing network filter:\n%s\n", filter); | 87 | filter = read_text_file_or_exit(fname); |
139 | 88 | allocated = 1; | |
140 | int fd; | ||
141 | if((fd = open("/tmp/netfilter", O_RDONLY)) == -1) { | ||
142 | fprintf(stderr,"Error: cannot open /tmp/netfilter\n"); | ||
143 | exit(1); | ||
144 | } | ||
145 | dup2(fd,STDIN_FILENO); | ||
146 | |||
147 | // wipe out environment variables | ||
148 | clearenv(); | ||
149 | execl(iptables_restore, iptables_restore, NULL); | ||
150 | perror("execl"); | ||
151 | _exit(1); | ||
152 | } | 89 | } |
153 | // wait for the child to finish | ||
154 | waitpid(child, NULL, 0); | ||
155 | 90 | ||
156 | // debug | 91 | // create the filter file |
157 | if (arg_debug) { | 92 | FILE *fp = fopen(SBOX_STDIN_FILE, "w"); |
158 | child = fork(); | 93 | if (!fp) { |
159 | if (child < 0) | 94 | fprintf(stderr, "Error: cannot open %s\n", SBOX_STDIN_FILE); |
160 | errExit("fork"); | 95 | exit(1); |
161 | if (child == 0) { | ||
162 | // elevate privileges in order to get grsecurity working | ||
163 | if (setreuid(0, 0)) | ||
164 | errExit("setreuid"); | ||
165 | if (setregid(0, 0)) | ||
166 | errExit("setregid"); | ||
167 | environ = NULL; | ||
168 | assert(getenv("LD_PRELOAD") == NULL); | ||
169 | execl(iptables, iptables, "-vL", NULL); | ||
170 | perror("execl"); | ||
171 | _exit(1); | ||
172 | } | ||
173 | // wait for the child to finish | ||
174 | waitpid(child, NULL, 0); | ||
175 | } | 96 | } |
97 | fprintf(fp, "%s\n", filter); | ||
98 | fclose(fp); | ||
99 | |||
176 | 100 | ||
177 | doexit: | 101 | // push filter |
178 | // unmount /tmp | 102 | if (arg_debug) |
179 | umount("/tmp"); | 103 | printf("Installing network filter:\n%s\n", filter); |
104 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP | SBOX_STDIN_FROM_FILE, 1, iptables_restore); | ||
105 | unlink(SBOX_STDIN_FILE); | ||
106 | |||
107 | // debug | ||
108 | if (arg_debug) | ||
109 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, iptables, "-vL"); | ||
180 | 110 | ||
181 | if (allocated) | 111 | if (allocated) |
182 | free(filter); | 112 | free(filter); |
183 | return; | 113 | return; |
184 | |||
185 | errexit: | ||
186 | fprintf(stderr, "Error: cannot read network filter %s\n", fname); | ||
187 | exit(1); | ||
188 | } | 114 | } |
189 | 115 | ||
190 | void netfilter6(const char *fname) { | 116 | void netfilter6(const char *fname) { |
191 | if (fname == NULL) | 117 | if (fname == NULL) |
192 | return; | 118 | return; |
193 | 119 | ||
194 | char *filter; | ||
195 | |||
196 | // open filter file | ||
197 | int fd = open(fname, O_RDONLY); | ||
198 | if (fd == -1) | ||
199 | goto errexit; | ||
200 | int size = lseek(fd, 0, SEEK_END); | ||
201 | if (size == -1) | ||
202 | goto errexit; | ||
203 | if (lseek(fd, 0 , SEEK_SET) == -1) | ||
204 | goto errexit; | ||
205 | |||
206 | // read filter | ||
207 | filter = malloc(size + 1); // + '\0' | ||
208 | if (filter == NULL) | ||
209 | goto errexit; | ||
210 | memset(&filter[0], 0, sizeof(filter)); | ||
211 | int rd = 0; | ||
212 | while (rd < size) { | ||
213 | int rv = read(fd, (unsigned char *) filter + rd, size - rd); | ||
214 | if (rv == -1) | ||
215 | goto errexit; | ||
216 | rd += rv; | ||
217 | } | ||
218 | |||
219 | // close file | ||
220 | close(fd); | ||
221 | |||
222 | // temporarily mount a tempfs on top of /tmp directory | ||
223 | if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) | ||
224 | errExit("mounting /tmp"); | ||
225 | |||
226 | // create the filter file | ||
227 | FILE *fp = fopen("/tmp/netfilter6", "w"); | ||
228 | if (!fp) { | ||
229 | fprintf(stderr, "Error: cannot open /tmp/netfilter6 file\n"); | ||
230 | exit(1); | ||
231 | } | ||
232 | fprintf(fp, "%s\n", filter); | ||
233 | fclose(fp); | ||
234 | |||
235 | // find iptables command | 120 | // find iptables command |
236 | char *ip6tables = NULL; | 121 | char *ip6tables = NULL; |
237 | char *ip6tables_restore = NULL; | 122 | char *ip6tables_restore = NULL; |
@@ -245,56 +130,30 @@ void netfilter6(const char *fname) { | |||
245 | ip6tables_restore = "/usr/sbin/ip6tables-restore"; | 130 | ip6tables_restore = "/usr/sbin/ip6tables-restore"; |
246 | } | 131 | } |
247 | if (ip6tables == NULL || ip6tables_restore == NULL) { | 132 | if (ip6tables == NULL || ip6tables_restore == NULL) { |
248 | fprintf(stderr, "Error: ip6tables command not found\n"); | 133 | fprintf(stderr, "Error: ip6tables command not found, netfilter6 not configured\n"); |
249 | goto doexit; | 134 | return; |
250 | } | 135 | } |
251 | 136 | ||
252 | // push filter | 137 | // create the filter file |
253 | pid_t child = fork(); | 138 | char *filter = read_text_file_or_exit(fname); |
254 | if (child < 0) | 139 | FILE *fp = fopen(SBOX_STDIN_FILE, "w"); |
255 | errExit("fork"); | 140 | if (!fp) { |
256 | if (child == 0) { | 141 | fprintf(stderr, "Error: cannot open /tmp/netfilter6 file\n"); |
257 | if (arg_debug) | 142 | exit(1); |
258 | printf("Installing network filter:\n%s\n", filter); | ||
259 | |||
260 | int fd; | ||
261 | if((fd = open("/tmp/netfilter6", O_RDONLY)) == -1) { | ||
262 | fprintf(stderr,"Error: cannot open /tmp/netfilter6\n"); | ||
263 | exit(1); | ||
264 | } | ||
265 | dup2(fd,STDIN_FILENO); | ||
266 | |||
267 | // wipe out environment variables | ||
268 | clearenv(); | ||
269 | execl(ip6tables_restore, ip6tables_restore, NULL); | ||
270 | perror("execl"); | ||
271 | _exit(1); | ||
272 | } | 143 | } |
273 | // wait for the child to finish | 144 | fprintf(fp, "%s\n", filter); |
274 | waitpid(child, NULL, 0); | 145 | fclose(fp); |
275 | 146 | ||
147 | // push filter | ||
148 | if (arg_debug) | ||
149 | printf("Installing network filter:\n%s\n", filter); | ||
150 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP | SBOX_STDIN_FROM_FILE, 1, ip6tables_restore); | ||
151 | unlink(SBOX_STDIN_FILE); | ||
152 | |||
276 | // debug | 153 | // debug |
277 | if (arg_debug) { | 154 | if (arg_debug) |
278 | child = fork(); | 155 | sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, ip6tables, "-vL"); |
279 | if (child < 0) | ||
280 | errExit("fork"); | ||
281 | if (child == 0) { | ||
282 | clearenv(); | ||
283 | execl(ip6tables, ip6tables, "-vL", NULL); | ||
284 | perror("execl"); | ||
285 | _exit(1); | ||
286 | } | ||
287 | // wait for the child to finish | ||
288 | waitpid(child, NULL, 0); | ||
289 | } | ||
290 | 156 | ||
291 | doexit: | ||
292 | // unmount /tmp | ||
293 | umount("/tmp"); | ||
294 | free(filter); | 157 | free(filter); |
295 | return; | 158 | return; |
296 | |||
297 | errexit: | ||
298 | fprintf(stderr, "Error: cannot read network filter %s\n", fname); | ||
299 | exit(1); | ||
300 | } | 159 | } |
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c index dbfdd445a..f28bbaf1a 100644 --- a/src/firejail/sbox.c +++ b/src/firejail/sbox.c | |||
@@ -138,20 +138,34 @@ int sbox_run(unsigned filter, int num, ...) { | |||
138 | if (child == 0) { | 138 | if (child == 0) { |
139 | // clean the new process | 139 | // clean the new process |
140 | clearenv(); | 140 | clearenv(); |
141 | int max = 20; // getdtablesize() is overkill for a firejail process | 141 | |
142 | for (i = 3; i < max; i++) | 142 | if (filter & SBOX_STDIN_FROM_FILE) { |
143 | close(i); // close open files | 143 | int fd; |
144 | if ((filter & SBOX_ALLOW_STDIN) == 0) { | 144 | if((fd = open(SBOX_STDIN_FILE, O_RDONLY)) == -1) { |
145 | int fd = open("/dev/null",O_RDWR, 0); | 145 | fprintf(stderr,"Error: cannot open /tmp/netfilter\n"); |
146 | if (fd != -1) { | 146 | exit(1); |
147 | dup2 (fd, STDIN_FILENO); | ||
148 | if (fd > 2) | ||
149 | close (fd); | ||
150 | } | 147 | } |
148 | dup2(fd,STDIN_FILENO); | ||
149 | } | ||
150 | else if ((filter & SBOX_ALLOW_STDIN) == 0) { | ||
151 | int fd = open("/dev/null",O_RDWR, 0); | ||
152 | if (fd != -1) | ||
153 | dup2(fd, STDIN_FILENO); | ||
151 | else // the user could run the sandbox without /dev/null | 154 | else // the user could run the sandbox without /dev/null |
152 | close(STDIN_FILENO); | 155 | close(STDIN_FILENO); |
153 | close(fd); | ||
154 | } | 156 | } |
157 | |||
158 | // close all other file descriptors | ||
159 | int max = 20; // getdtablesize() is overkill for a firejail process | ||
160 | for (i = 3; i < max; i++) | ||
161 | close(i); // close open files | ||
162 | |||
163 | if (arg_debug) { | ||
164 | printf("sbox file descriptors:\n"); | ||
165 | int rv = system("ls -l /proc/self/fd"); | ||
166 | (void) rv; | ||
167 | } | ||
168 | |||
155 | umask(027); | 169 | umask(027); |
156 | 170 | ||
157 | // apply filters | 171 | // apply filters |
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index dd133b2ba..cdbbe4fdd 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c | |||
@@ -72,7 +72,7 @@ int seccomp_load(const char *fname) { | |||
72 | struct sock_filter *filter = malloc(size); | 72 | struct sock_filter *filter = malloc(size); |
73 | if (filter == NULL) | 73 | if (filter == NULL) |
74 | goto errexit; | 74 | goto errexit; |
75 | memset(&filter[0], 0, sizeof(filter)); | 75 | memset(filter, 0, size); |
76 | int rd = 0; | 76 | int rd = 0; |
77 | while (rd < size) { | 77 | while (rd < size) { |
78 | int rv = read(fd, (unsigned char *) filter + rd, size - rd); | 78 | int rv = read(fd, (unsigned char *) filter + rd, size - rd); |
diff --git a/src/firejail/util.c b/src/firejail/util.c index c3e00a110..75f2acdb9 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -777,3 +777,45 @@ void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) { | |||
777 | 777 | ||
778 | ASSERT_PERMS(fname, uid, gid, mode); | 778 | ASSERT_PERMS(fname, uid, gid, mode); |
779 | } | 779 | } |
780 | |||
781 | char *read_text_file_or_exit(const char *fname) { | ||
782 | assert(fname); | ||
783 | |||
784 | // open file | ||
785 | int fd = open(fname, O_RDONLY); | ||
786 | if (fd == -1) { | ||
787 | fprintf(stderr, "Error: cannot read %s\n", fname); | ||
788 | exit(1); | ||
789 | } | ||
790 | |||
791 | int size = lseek(fd, 0, SEEK_END); | ||
792 | if (size == -1) | ||
793 | goto errexit; | ||
794 | if (lseek(fd, 0 , SEEK_SET) == -1) | ||
795 | goto errexit; | ||
796 | |||
797 | // allocate memory | ||
798 | char *data = malloc(size + 1); // + '\0' | ||
799 | if (data == NULL) | ||
800 | goto errexit; | ||
801 | memset(data, 0, size + 1); | ||
802 | |||
803 | // read file | ||
804 | int rd = 0; | ||
805 | while (rd < size) { | ||
806 | int rv = read(fd, (unsigned char *) data + rd, size - rd); | ||
807 | if (rv == -1) { | ||
808 | goto errexit; | ||
809 | } | ||
810 | rd += rv; | ||
811 | } | ||
812 | |||
813 | // close file | ||
814 | close(fd); | ||
815 | return data; | ||
816 | |||
817 | errexit: | ||
818 | close(fd); | ||
819 | fprintf(stderr, "Error: cannot read %s\n", fname); | ||
820 | exit(1); | ||
821 | } \ No newline at end of file | ||
diff --git a/src/firejail/x11.c b/src/firejail/x11.c index 807f2d5f0..e67260490 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c | |||
@@ -252,7 +252,7 @@ void x11_start_xephyr(int argc, char **argv) { | |||
252 | } | 252 | } |
253 | 253 | ||
254 | for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) { | 254 | for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) { |
255 | if (pos >= (sizeof(server_argv)/sizeof(*server_argv))) { | 255 | if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { |
256 | fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n"); | 256 | fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n"); |
257 | exit(1); | 257 | exit(1); |
258 | } | 258 | } |
@@ -716,6 +716,7 @@ void x11_xorg(void) { | |||
716 | } | 716 | } |
717 | if (set_perms(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) | 717 | if (set_perms(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) |
718 | errExit("set_perms"); | 718 | errExit("set_perms"); |
719 | /* coverity[toctou] */ | ||
719 | unlink(tmpfname); | 720 | unlink(tmpfname); |
720 | 721 | ||
721 | // mount | 722 | // mount |
diff --git a/src/fseccomp/seccomp_print.c b/src/fseccomp/seccomp_print.c index af240307c..e22c682dc 100644 --- a/src/fseccomp/seccomp_print.c +++ b/src/fseccomp/seccomp_print.c | |||
@@ -45,7 +45,7 @@ static void load_seccomp(const char *fname) { | |||
45 | filter = malloc(size); | 45 | filter = malloc(size); |
46 | if (filter == NULL) | 46 | if (filter == NULL) |
47 | goto errexit; | 47 | goto errexit; |
48 | memset(&filter[0], 0, sizeof(filter)); | 48 | memset(filter, 0, size); |
49 | int rd = 0; | 49 | int rd = 0; |
50 | while (rd < size) { | 50 | while (rd < size) { |
51 | int rv = read(fd, (unsigned char *) filter + rd, size - rd); | 51 | int rv = read(fd, (unsigned char *) filter + rd, size - rd); |