From dd2c1e50a6fac06f5eac7aa94865078a55021d62 Mon Sep 17 00:00:00 2001 From: smitsohu Date: Thu, 4 Mar 2021 00:05:12 +0100 Subject: private-lib hardening ensure that libraries are loaded from a default ld.so search path it is reasonable for firejail to expect that unprivileged users have no write permission on these paths; lax permissions there mean that the system is probably screwed anyway --- src/firejail/fs_lib.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index a7f5b0bfc..53a8818af 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c @@ -33,6 +33,31 @@ extern void fslib_install_system(void); static int lib_cnt = 0; static int dir_cnt = 0; +static const char *lib_dirs[] = { + "/usr/lib64", + "/lib64", + "/usr/lib", + "/lib", + "/usr/local/lib64", + "/usr/local/lib", + NULL, +}; + +// return 1 if the file is in lib_dirs[] +static int valid_full_path(const char *full_path) { + if (strstr(full_path, "..")) + return 0; + + int i = 0; + while (lib_dirs[i]) { + if (strncmp(full_path, lib_dirs[i], strlen(lib_dirs[i])) == 0 && + full_path[strlen(lib_dirs[i])] == '/') + return 1; + i++; + } + return 0; +} + char *find_in_path(const char *program) { EUID_ASSERT(); if (arg_debug) @@ -107,7 +132,8 @@ void fslib_duplicate(const char *full_path) { assert(full_path); struct stat s; - if (stat(full_path, &s) != 0 || s.st_uid != 0 || access(full_path, R_OK)) + if (stat(full_path, &s) != 0 || s.st_uid != 0 || access(full_path, R_OK) + || !valid_full_path(full_path)) return; char *dest_dir = build_dest_dir(full_path); @@ -190,7 +216,8 @@ void fslib_copy_dir(const char *full_path) { // do nothing if the directory does not exist or is not owned by root struct stat s; - if (stat(full_path, &s) != 0 || s.st_uid != 0 || !S_ISDIR(s.st_mode) || access(full_path, R_OK)) + if (stat(full_path, &s) != 0 || s.st_uid != 0 || !S_ISDIR(s.st_mode) || access(full_path, R_OK) + || !valid_full_path(full_path)) return; char *dir_name = strrchr(full_path, '/'); -- cgit v1.2.3-70-g09d2