diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firecfg/main.c | 5 | ||||
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/mountinfo.c | 52 | ||||
-rw-r--r-- | src/lib/firejail_user.c | 18 |
4 files changed, 50 insertions, 27 deletions
diff --git a/src/firecfg/main.c b/src/firecfg/main.c index 810af6ff2..84f6a5f77 100644 --- a/src/firecfg/main.c +++ b/src/firecfg/main.c | |||
@@ -379,6 +379,8 @@ int main(int argc, char **argv) { | |||
379 | exit(1); | 379 | exit(1); |
380 | } | 380 | } |
381 | 381 | ||
382 | // set umask, access database must be world-readable | ||
383 | umask(022); | ||
382 | for (j = i + 1; j < argc; j++) { | 384 | for (j = i + 1; j < argc; j++) { |
383 | printf("Adding user %s to Firejail access database in %s/firejail.users\n", argv[j], SYSCONFDIR); | 385 | printf("Adding user %s to Firejail access database in %s/firejail.users\n", argv[j], SYSCONFDIR); |
384 | firejail_user_add(argv[j]); | 386 | firejail_user_add(argv[j]); |
@@ -433,7 +435,10 @@ int main(int argc, char **argv) { | |||
433 | // add user to firejail access database - only for root | 435 | // add user to firejail access database - only for root |
434 | if (getuid() == 0) { | 436 | if (getuid() == 0) { |
435 | printf("\nAdding user %s to Firejail access database in %s/firejail.users\n", user, SYSCONFDIR); | 437 | printf("\nAdding user %s to Firejail access database in %s/firejail.users\n", user, SYSCONFDIR); |
438 | // temporarily set the umask, access database must be world-readable | ||
439 | mode_t orig_umask = umask(022); | ||
436 | firejail_user_add(user); | 440 | firejail_user_add(user); |
441 | umask(orig_umask); | ||
437 | } | 442 | } |
438 | 443 | ||
439 | // set new symlinks based on ~/.config/firejail directory | 444 | // set new symlinks based on ~/.config/firejail directory |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 8a397e3d8..2e921ad37 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -562,7 +562,7 @@ typedef struct { | |||
562 | // mountinfo.c | 562 | // mountinfo.c |
563 | MountData *get_last_mount(void); | 563 | MountData *get_last_mount(void); |
564 | int get_mount_id(const char *path); | 564 | int get_mount_id(const char *path); |
565 | char **build_mount_array(const int mountid, const char *path); | 565 | char **build_mount_array(const int mount_id, const char *path); |
566 | 566 | ||
567 | // fs_var.c | 567 | // fs_var.c |
568 | void fs_var_log(void); // mounting /var/log | 568 | void fs_var_log(void); // mounting /var/log |
diff --git a/src/firejail/mountinfo.c b/src/firejail/mountinfo.c index ab1e501a7..c89845ace 100644 --- a/src/firejail/mountinfo.c +++ b/src/firejail/mountinfo.c | |||
@@ -69,7 +69,7 @@ static void unmangle_path(char *path) { | |||
69 | static void parse_line(char *line, MountData *output) { | 69 | static void parse_line(char *line, MountData *output) { |
70 | assert(line && output); | 70 | assert(line && output); |
71 | memset(output, 0, sizeof(*output)); | 71 | memset(output, 0, sizeof(*output)); |
72 | // extract filesystem name, directory and filesystem types | 72 | // extract mount id, filesystem name, directory and filesystem types |
73 | // examples: | 73 | // examples: |
74 | // 587 543 8:1 /tmp /etc rw,relatime master:1 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered | 74 | // 587 543 8:1 /tmp /etc rw,relatime master:1 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered |
75 | // output.mountid: 587 | 75 | // output.mountid: 587 |
@@ -153,6 +153,8 @@ MountData *get_last_mount(void) { | |||
153 | 153 | ||
154 | // Extract the mount id from /proc/self/fdinfo and return it. | 154 | // Extract the mount id from /proc/self/fdinfo and return it. |
155 | int get_mount_id(const char *path) { | 155 | int get_mount_id(const char *path) { |
156 | assert(path); | ||
157 | |||
156 | int fd = open(path, O_PATH|O_CLOEXEC); | 158 | int fd = open(path, O_PATH|O_CLOEXEC); |
157 | if (fd == -1) | 159 | if (fd == -1) |
158 | return -1; | 160 | return -1; |
@@ -197,8 +199,12 @@ int get_mount_id(const char *path) { | |||
197 | return -2; | 199 | return -2; |
198 | } | 200 | } |
199 | 201 | ||
200 | // Return array with all paths that might need a remount. | 202 | // Check /proc/self/mountinfo if path has any submounts (or if path would have submounts |
201 | char **build_mount_array(const int mountid, const char *path) { | 203 | // if it was made a mount point). |
204 | // Returns an array that can be iterated over for recursive remounting. | ||
205 | char **build_mount_array(const int mount_id, const char *path) { | ||
206 | assert(path); | ||
207 | |||
202 | // open /proc/self/mountinfo | 208 | // open /proc/self/mountinfo |
203 | FILE *fp = fopen("/proc/self/mountinfo", "re"); | 209 | FILE *fp = fopen("/proc/self/mountinfo", "re"); |
204 | if (!fp) { | 210 | if (!fp) { |
@@ -207,30 +213,34 @@ char **build_mount_array(const int mountid, const char *path) { | |||
207 | exit(1); | 213 | exit(1); |
208 | } | 214 | } |
209 | 215 | ||
210 | size_t size = 32; | 216 | // array to be returned |
211 | size_t cnt = 0; | 217 | size_t cnt = 0; |
218 | size_t size = 32; | ||
212 | char **rv = malloc(size * sizeof(*rv)); | 219 | char **rv = malloc(size * sizeof(*rv)); |
213 | if (!rv) | 220 | if (!rv) |
214 | errExit("malloc"); | 221 | errExit("malloc"); |
215 | 222 | ||
216 | // read /proc/self/mountinfo | 223 | // read /proc/self/mountinfo |
217 | size_t pathlen = strlen(path); | 224 | size_t pathlen = strlen(path); |
225 | char buf[MAX_BUF]; | ||
226 | MountData mntp; | ||
218 | int found = 0; | 227 | int found = 0; |
219 | if (fgets(mbuf, MAX_BUF, fp) == NULL) { | 228 | |
229 | if (fgets(buf, MAX_BUF, fp) == NULL) { | ||
220 | fprintf(stderr, "Error: cannot read /proc/self/mountinfo\n"); | 230 | fprintf(stderr, "Error: cannot read /proc/self/mountinfo\n"); |
221 | exit(1); | 231 | exit(1); |
222 | } | 232 | } |
223 | do { | 233 | do { |
224 | // find mount point with mount id | 234 | // find mount point with mount id |
225 | if (!found) { | 235 | if (!found) { |
226 | parse_line(mbuf, &mdata); | 236 | parse_line(buf, &mntp); |
227 | if (mdata.mountid == mountid) { | 237 | if (mntp.mountid == mount_id) { |
228 | // don't remount blacklisted paths, | 238 | // give up if mount id has been reassigned, |
229 | // give up if mount id has been reassigned | 239 | // don't remount blacklisted path |
230 | if (strstr(mdata.fsname, "firejail.ro.dir") || | 240 | if (strncmp(mntp.dir, path, strlen(mntp.dir)) || |
231 | strstr(mdata.fsname, "firejail.ro.file") || | 241 | strstr(mntp.fsname, "firejail.ro.dir") || |
232 | strncmp(mdata.dir, path, strlen(mdata.dir))) | 242 | strstr(mntp.fsname, "firejail.ro.file")) |
233 | break; | 243 | break; |
234 | 244 | ||
235 | *rv = strdup(path); | 245 | *rv = strdup(path); |
236 | if (*rv == NULL) | 246 | if (*rv == NULL) |
@@ -244,24 +254,24 @@ char **build_mount_array(const int mountid, const char *path) { | |||
244 | } | 254 | } |
245 | // from here on add all mount points below path, | 255 | // from here on add all mount points below path, |
246 | // don't remount blacklisted paths | 256 | // don't remount blacklisted paths |
247 | parse_line(mbuf, &mdata); | 257 | parse_line(buf, &mntp); |
248 | if (strncmp(mdata.dir, path, pathlen) == 0 && | 258 | if (strncmp(mntp.dir, path, pathlen) == 0 && |
249 | mdata.dir[pathlen] == '/' && | 259 | mntp.dir[pathlen] == '/' && |
250 | strstr(mdata.fsname, "firejail.ro.dir") == NULL && | 260 | strstr(mntp.fsname, "firejail.ro.dir") == NULL && |
251 | strstr(mdata.fsname, "firejail.ro.file") == NULL) { | 261 | strstr(mntp.fsname, "firejail.ro.file") == NULL) { |
252 | 262 | ||
253 | if (cnt >= size) { | 263 | if (cnt == size) { |
254 | size *= 2; | 264 | size *= 2; |
255 | rv = realloc(rv, size * sizeof(*rv)); | 265 | rv = realloc(rv, size * sizeof(*rv)); |
256 | if (!rv) | 266 | if (!rv) |
257 | errExit("realloc"); | 267 | errExit("realloc"); |
258 | } | 268 | } |
259 | rv[cnt] = strdup(mdata.dir); | 269 | rv[cnt] = strdup(mntp.dir); |
260 | if (rv[cnt] == NULL) | 270 | if (rv[cnt] == NULL) |
261 | errExit("strdup"); | 271 | errExit("strdup"); |
262 | cnt++; | 272 | cnt++; |
263 | } | 273 | } |
264 | } while (fgets(mbuf, MAX_BUF, fp)); | 274 | } while (fgets(buf, MAX_BUF, fp)); |
265 | 275 | ||
266 | if (cnt == size) { | 276 | if (cnt == size) { |
267 | size++; | 277 | size++; |
diff --git a/src/lib/firejail_user.c b/src/lib/firejail_user.c index b270db459..a595d8331 100644 --- a/src/lib/firejail_user.c +++ b/src/lib/firejail_user.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "../include/firejail_user.h" | 29 | #include "../include/firejail_user.h" |
30 | #include <sys/types.h> | 30 | #include <sys/types.h> |
31 | #include <pwd.h> | 31 | #include <pwd.h> |
32 | #include <errno.h> | ||
32 | 33 | ||
33 | #define MAXBUF 4098 | 34 | #define MAXBUF 4098 |
34 | 35 | ||
@@ -113,15 +114,20 @@ int firejail_user_check(const char *name) { | |||
113 | 114 | ||
114 | // check file existence | 115 | // check file existence |
115 | char *fname = get_fname(); | 116 | char *fname = get_fname(); |
116 | if (access(fname, F_OK)) { | 117 | assert(fname); |
118 | if (access(fname, F_OK) == -1 && errno == ENOENT) { | ||
119 | // assume the user doesn't care about access checking | ||
117 | free(fname); | 120 | free(fname); |
118 | return 1; // assume the user doesn't care about access checking | 121 | return 1; |
119 | } | 122 | } |
120 | 123 | ||
121 | FILE *fp = fopen(fname, "r"); | 124 | FILE *fp = fopen(fname, "r"); |
125 | if (!fp) { | ||
126 | fprintf(stderr, "Error: cannot read %s\n", fname); | ||
127 | perror("fopen"); | ||
128 | exit(1); | ||
129 | } | ||
122 | free(fname); | 130 | free(fname); |
123 | if (!fp) | ||
124 | return 0; | ||
125 | 131 | ||
126 | char buf[MAXBUF]; | 132 | char buf[MAXBUF]; |
127 | while (fgets(buf, MAXBUF, fp)) { | 133 | while (fgets(buf, MAXBUF, fp)) { |
@@ -162,11 +168,13 @@ void firejail_user_add(const char *name) { | |||
162 | if (access(fname, F_OK) == 0) { | 168 | if (access(fname, F_OK) == 0) { |
163 | if (firejail_user_check(name)) { | 169 | if (firejail_user_check(name)) { |
164 | printf("User %s already in the database\n", name); | 170 | printf("User %s already in the database\n", name); |
171 | free(fname); | ||
165 | return; | 172 | return; |
166 | } | 173 | } |
167 | } | 174 | } |
175 | else | ||
176 | printf("Creating %s\n", fname); | ||
168 | 177 | ||
169 | printf("%s created\n", fname); | ||
170 | FILE *fp = fopen(fname, "a+"); | 178 | FILE *fp = fopen(fname, "a+"); |
171 | if (!fp) { | 179 | if (!fp) { |
172 | fprintf(stderr, "Error: cannot open %s\n", fname); | 180 | fprintf(stderr, "Error: cannot open %s\n", fname); |