aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2021-03-04 00:05:12 +0100
committerLibravatar smitsohu <smitsohu@gmail.com>2021-03-04 00:16:30 +0100
commitdd2c1e50a6fac06f5eac7aa94865078a55021d62 (patch)
tree29af318e3b367949ee83065485df30cbd47d27a9 /src
parentjailtest fix (diff)
downloadfirejail-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
Diffstat (limited to 'src')
-rw-r--r--src/firejail/fs_lib.c31
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);
33static int lib_cnt = 0; 33static int lib_cnt = 0;
34static int dir_cnt = 0; 34static int dir_cnt = 0;
35 35
36static 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[]
47static 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
36char *find_in_path(const char *program) { 61char *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, '/');