diff options
author | smitsohu <smitsohu@gmail.com> | 2021-03-25 15:14:36 +0100 |
---|---|---|
committer | smitsohu <smitsohu@gmail.com> | 2021-03-25 17:20:08 +0100 |
commit | 2295b1c91a32a56f34209ca40a4a9c1bddbdbdd2 (patch) | |
tree | 62ba3324880de1739d070f299ce138ca91888b35 /src | |
parent | fix hardening comment (diff) | |
download | firejail-2295b1c91a32a56f34209ca40a4a9c1bddbdbdd2.tar.gz firejail-2295b1c91a32a56f34209ca40a4a9c1bddbdbdd2.tar.zst firejail-2295b1c91a32a56f34209ca40a4a9c1bddbdbdd2.zip |
private-lib: trim ending slashes and dots
Currently pathological endings like in
/foo/bar/./. are mapped to RUN_LIB_DIR,
with the effect that the mount is skipped
because this directory always exists at
this point in time.
Even though it's harmless, it is wrong
behaviour, so handle trailing slashes and
dots before doing the mounts. Also avoids
running into an assertion if there is a trailing
slash.
Plus few small cosmetic changes to make
things more explicit.
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/fs_lib.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index 0491fd9b1..85fb70854 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c | |||
@@ -52,8 +52,9 @@ static int valid_full_path(const char *full_path) { | |||
52 | 52 | ||
53 | int i = 0; | 53 | int i = 0; |
54 | while (masked_lib_dirs[i]) { | 54 | while (masked_lib_dirs[i]) { |
55 | if (strncmp(full_path, masked_lib_dirs[i], strlen(masked_lib_dirs[i])) == 0 && | 55 | size_t len = strlen(masked_lib_dirs[i]); |
56 | full_path[strlen(masked_lib_dirs[i])] == '/') | 56 | if (strncmp(full_path, masked_lib_dirs[i], len) == 0 && |
57 | full_path[len] == '/') | ||
57 | return 1; | 58 | return 1; |
58 | i++; | 59 | i++; |
59 | } | 60 | } |
@@ -120,7 +121,8 @@ static char *build_dest_name(const char *full_path) { | |||
120 | char *fname = strrchr(full_path, '/'); | 121 | char *fname = strrchr(full_path, '/'); |
121 | assert(fname); | 122 | assert(fname); |
122 | fname++; | 123 | fname++; |
123 | assert(*fname != '\0'); | 124 | // no trailing slash or dot |
125 | assert(fname[0] != '\0' && (fname[0] != '.' || fname[1] != '\0')); | ||
124 | 126 | ||
125 | char *dest; | 127 | char *dest; |
126 | if (asprintf(&dest, "%s/%s", build_dest_dir(full_path), fname) == -1) | 128 | if (asprintf(&dest, "%s/%s", build_dest_dir(full_path), fname) == -1) |
@@ -174,7 +176,8 @@ void fslib_mount(const char *full_path) { | |||
174 | assert(full_path); | 176 | assert(full_path); |
175 | struct stat s; | 177 | struct stat s; |
176 | 178 | ||
177 | if (!valid_full_path(full_path) || | 179 | if (*full_path == '\0' || |
180 | !valid_full_path(full_path) || | ||
178 | access(full_path, F_OK) != 0 || | 181 | access(full_path, F_OK) != 0 || |
179 | stat(full_path, &s) != 0 || | 182 | stat(full_path, &s) != 0 || |
180 | s.st_uid != 0) | 183 | s.st_uid != 0) |
@@ -229,13 +232,14 @@ void fslib_mount_libs(const char *full_path, unsigned user) { | |||
229 | if (ptr) | 232 | if (ptr) |
230 | *ptr = '\0'; | 233 | *ptr = '\0'; |
231 | 234 | ||
235 | trim_trailing_slash_or_dot(buf); | ||
232 | fslib_mount(buf); | 236 | fslib_mount(buf); |
233 | } | 237 | } |
234 | fclose(fp); | 238 | fclose(fp); |
235 | unlink(RUN_LIB_FILE); | 239 | unlink(RUN_LIB_FILE); |
236 | } | 240 | } |
237 | 241 | ||
238 | // fname should be a valid full path at this point | 242 | // fname should be a full path at this point |
239 | static void load_library(const char *fname) { | 243 | static void load_library(const char *fname) { |
240 | assert(fname); | 244 | assert(fname); |
241 | assert(*fname == '/'); | 245 | assert(*fname == '/'); |
@@ -293,6 +297,11 @@ static void install_list_entry(const char *lib) { | |||
293 | assert(globbuf.gl_pathv[j]); | 297 | assert(globbuf.gl_pathv[j]); |
294 | //printf("glob %s\n", globbuf.gl_pathv[j]); | 298 | //printf("glob %s\n", globbuf.gl_pathv[j]); |
295 | // GLOB_NOCHECK - no pattern matched returns the original pattern; try to load it anyway | 299 | // GLOB_NOCHECK - no pattern matched returns the original pattern; try to load it anyway |
300 | |||
301 | // foobar/* includes foobar/. and foobar/.. | ||
302 | const char *base = gnu_basename(globbuf.gl_pathv[j]); | ||
303 | if (strcmp(base, ".") == 0 || strcmp(base, "..") == 0) | ||
304 | continue; | ||
296 | load_library(globbuf.gl_pathv[j]); | 305 | load_library(globbuf.gl_pathv[j]); |
297 | } | 306 | } |
298 | 307 | ||
@@ -321,10 +330,13 @@ void fslib_install_list(const char *lib_list) { | |||
321 | fprintf(stderr, "Error: invalid private-lib argument\n"); | 330 | fprintf(stderr, "Error: invalid private-lib argument\n"); |
322 | exit(1); | 331 | exit(1); |
323 | } | 332 | } |
333 | trim_trailing_slash_or_dot(ptr); | ||
324 | install_list_entry(ptr); | 334 | install_list_entry(ptr); |
325 | 335 | ||
326 | while ((ptr = strtok(NULL, ",")) != NULL) | 336 | while ((ptr = strtok(NULL, ",")) != NULL) { |
337 | trim_trailing_slash_or_dot(ptr); | ||
327 | install_list_entry(ptr); | 338 | install_list_entry(ptr); |
339 | } | ||
328 | free(dlist); | 340 | free(dlist); |
329 | fs_logger_print(); | 341 | fs_logger_print(); |
330 | } | 342 | } |