diff options
author | smitsohu <smitsohu@gmail.com> | 2021-03-04 00:05:12 +0100 |
---|---|---|
committer | smitsohu <smitsohu@gmail.com> | 2021-03-04 00:16:30 +0100 |
commit | dd2c1e50a6fac06f5eac7aa94865078a55021d62 (patch) | |
tree | 29af318e3b367949ee83065485df30cbd47d27a9 | |
parent | jailtest fix (diff) | |
download | firejail-dd2c1e50a6fac06f5eac7aa94865078a55021d62.tar.gz firejail-dd2c1e50a6fac06f5eac7aa94865078a55021d62.tar.zst firejail-dd2c1e50a6fac06f5eac7aa94865078a55021d62.zip |
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
-rw-r--r-- | src/firejail/fs_lib.c | 31 |
1 files 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); | |||
33 | static int lib_cnt = 0; | 33 | static int lib_cnt = 0; |
34 | static int dir_cnt = 0; | 34 | static int dir_cnt = 0; |
35 | 35 | ||
36 | static const char *lib_dirs[] = { | ||
37 | "/usr/lib64", | ||
38 | "/lib64", | ||
39 | "/usr/lib", | ||
40 | "/lib", | ||
41 | "/usr/local/lib64", | ||
42 | "/usr/local/lib", | ||
43 | NULL, | ||
44 | }; | ||
45 | |||
46 | // return 1 if the file is in lib_dirs[] | ||
47 | static int valid_full_path(const char *full_path) { | ||
48 | if (strstr(full_path, "..")) | ||
49 | return 0; | ||
50 | |||
51 | int i = 0; | ||
52 | while (lib_dirs[i]) { | ||
53 | if (strncmp(full_path, lib_dirs[i], strlen(lib_dirs[i])) == 0 && | ||
54 | full_path[strlen(lib_dirs[i])] == '/') | ||
55 | return 1; | ||
56 | i++; | ||
57 | } | ||
58 | return 0; | ||
59 | } | ||
60 | |||
36 | char *find_in_path(const char *program) { | 61 | char *find_in_path(const char *program) { |
37 | EUID_ASSERT(); | 62 | EUID_ASSERT(); |
38 | if (arg_debug) | 63 | if (arg_debug) |
@@ -107,7 +132,8 @@ void fslib_duplicate(const char *full_path) { | |||
107 | assert(full_path); | 132 | assert(full_path); |
108 | 133 | ||
109 | struct stat s; | 134 | struct stat s; |
110 | if (stat(full_path, &s) != 0 || s.st_uid != 0 || access(full_path, R_OK)) | 135 | if (stat(full_path, &s) != 0 || s.st_uid != 0 || access(full_path, R_OK) |
136 | || !valid_full_path(full_path)) | ||
111 | return; | 137 | return; |
112 | 138 | ||
113 | char *dest_dir = build_dest_dir(full_path); | 139 | char *dest_dir = build_dest_dir(full_path); |
@@ -190,7 +216,8 @@ void fslib_copy_dir(const char *full_path) { | |||
190 | 216 | ||
191 | // do nothing if the directory does not exist or is not owned by root | 217 | // do nothing if the directory does not exist or is not owned by root |
192 | struct stat s; | 218 | struct stat s; |
193 | if (stat(full_path, &s) != 0 || s.st_uid != 0 || !S_ISDIR(s.st_mode) || access(full_path, R_OK)) | 219 | if (stat(full_path, &s) != 0 || s.st_uid != 0 || !S_ISDIR(s.st_mode) || access(full_path, R_OK) |
220 | || !valid_full_path(full_path)) | ||
194 | return; | 221 | return; |
195 | 222 | ||
196 | char *dir_name = strrchr(full_path, '/'); | 223 | char *dir_name = strrchr(full_path, '/'); |