diff options
author | 2017-07-29 17:39:48 +0300 | |
---|---|---|
committer | 2017-07-30 16:48:16 +0000 | |
commit | fee33da1683746369ed15638f3d010d2a2a525fb (patch) | |
tree | f88017b70b3a92d253000482689ba4f9fd51abc6 | |
parent | Private /lib feature (diff) | |
download | firejail-fee33da1683746369ed15638f3d010d2a2a525fb.tar.gz firejail-fee33da1683746369ed15638f3d010d2a2a525fb.tar.zst firejail-fee33da1683746369ed15638f3d010d2a2a525fb.zip |
Improve loading of seccomp filter
Also fixes a memory leak and double load.
-rw-r--r-- | src/firejail/seccomp.c | 23 |
1 files changed, 8 insertions, 15 deletions
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index 29f928ee7..6e0fc0919 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #ifdef HAVE_SECCOMP | 21 | #ifdef HAVE_SECCOMP |
22 | #include <sys/mman.h> | ||
22 | #include "firejail.h" | 23 | #include "firejail.h" |
23 | #include "../include/seccomp.h" | 24 | #include "../include/seccomp.h" |
24 | 25 | ||
@@ -64,24 +65,14 @@ int seccomp_load(const char *fname) { | |||
64 | int size = lseek(fd, 0, SEEK_END); | 65 | int size = lseek(fd, 0, SEEK_END); |
65 | if (size == -1) | 66 | if (size == -1) |
66 | goto errexit; | 67 | goto errexit; |
67 | if (lseek(fd, 0 , SEEK_SET) == -1) | ||
68 | goto errexit; | ||
69 | unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter); | 68 | unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter); |
70 | if (arg_debug) | 69 | if (arg_debug) |
71 | printf("configuring %d seccomp entries from %s\n", entries, fname); | 70 | printf("configuring %d seccomp entries from %s\n", entries, fname); |
72 | 71 | ||
73 | // read filter | 72 | // read filter |
74 | struct sock_filter *filter = malloc(size); | 73 | struct sock_filter *filter = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); |
75 | if (filter == NULL) | 74 | if (filter == MAP_FAILED) |
76 | goto errexit; | 75 | goto errexit; |
77 | memset(filter, 0, size); | ||
78 | int rd = 0; | ||
79 | while (rd < size) { | ||
80 | int rv = read(fd, (unsigned char *) filter + rd, size - rd); | ||
81 | if (rv == -1) | ||
82 | goto errexit; | ||
83 | rd += rv; | ||
84 | } | ||
85 | 76 | ||
86 | // close file | 77 | // close file |
87 | close(fd); | 78 | close(fd); |
@@ -91,14 +82,16 @@ int seccomp_load(const char *fname) { | |||
91 | .len = entries, | 82 | .len = entries, |
92 | .filter = filter, | 83 | .filter = filter, |
93 | }; | 84 | }; |
85 | int r = 0; | ||
94 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | 86 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { |
95 | if (!err_printed) | 87 | if (!err_printed) |
96 | fwarning("seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); | 88 | fwarning("seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); |
97 | err_printed = 1; | 89 | err_printed = 1; |
98 | return 1; | 90 | r = 1; |
99 | } | 91 | } |
100 | 92 | ||
101 | return 0; | 93 | munmap(filter, size); |
94 | return r; | ||
102 | 95 | ||
103 | errexit: | 96 | errexit: |
104 | fprintf(stderr, "Error: cannot read %s\n", fname); | 97 | fprintf(stderr, "Error: cannot read %s\n", fname); |
@@ -194,7 +187,7 @@ int seccomp_filter_drop(int enforce_seccomp) { | |||
194 | sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3, | 187 | sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3, |
195 | PATH_FSECCOMP, "print", RUN_SECCOMP_CFG); | 188 | PATH_FSECCOMP, "print", RUN_SECCOMP_CFG); |
196 | 189 | ||
197 | return seccomp_load(RUN_SECCOMP_CFG); | 190 | return 0; |
198 | } | 191 | } |
199 | 192 | ||
200 | // keep filter for seccomp option | 193 | // keep filter for seccomp option |