diff options
author | netblue30 <netblue30@yahoo.com> | 2017-08-04 08:07:45 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-08-04 08:07:45 -0400 |
commit | b35aed22f8334ceeafbf388d024b4b8a7a6dec7e (patch) | |
tree | b469bb3d96984e3ec26aa57984e4e41e3638a704 /src | |
parent | Merge branch 'master' of https://github.com/netblue30/firejail (diff) | |
download | firejail-b35aed22f8334ceeafbf388d024b4b8a7a6dec7e.tar.gz firejail-b35aed22f8334ceeafbf388d024b4b8a7a6dec7e.tar.zst firejail-b35aed22f8334ceeafbf388d024b4b8a7a6dec7e.zip |
private-lib: bringing in private-lib list from command line
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/fs_lib.c | 114 |
1 files changed, 98 insertions, 16 deletions
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index 576b4a0df..94d87a151 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c | |||
@@ -23,24 +23,51 @@ | |||
23 | #include <sys/types.h> | 23 | #include <sys/types.h> |
24 | #include <unistd.h> | 24 | #include <unistd.h> |
25 | 25 | ||
26 | static const char * const lib_paths[] = { | ||
27 | "/lib", | ||
28 | "/lib/x86_64-linux-gnu", | ||
29 | "/lib64", | ||
30 | "/usr/lib", | ||
31 | "/usr/lib/x86_64-linux-gnu", | ||
32 | LIBDIR, | ||
33 | "/usr/local/lib", | ||
34 | NULL | ||
35 | }; // Note: this array is duplicated in src/fldd/main.c | ||
36 | |||
37 | static void copy_libs(const char *exe, const char *dir, const char *file); | ||
38 | |||
26 | static void duplicate(const char *fname, const char *private_run_dir) { | 39 | static void duplicate(const char *fname, const char *private_run_dir) { |
27 | if (arg_debug) | 40 | if (arg_debug) |
28 | printf("copying %s to private %s\n", fname, private_run_dir); | 41 | printf("copying %s to private %s\n", fname, private_run_dir); |
29 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", fname, private_run_dir); | 42 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", fname, private_run_dir); |
30 | } | 43 | } |
31 | 44 | ||
32 | static void copy_libs(const char *exe, const char *dir, const char *file) { | 45 | |
46 | // requires full path for exe | ||
47 | static void copy_exe(const char *exe, const char *dir, const char *file) { | ||
48 | // if exe does not exist or the user does not have read access to it | ||
49 | // print a warning and exit the function. | ||
50 | if (access(exe, R_OK)) { | ||
51 | fwarning("cannot find %s executable for private-lib, skipping...\n", exe); | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | copy_libs(exe, dir, file); | ||
56 | } | ||
57 | |||
58 | // requires full path for lib | ||
59 | static void copy_libs(const char *lib, const char *dir, const char *output_file) { | ||
33 | // create an empty RUN_LIB_FILE and allow the user to write to it | 60 | // create an empty RUN_LIB_FILE and allow the user to write to it |
34 | unlink(file); // in case is there | 61 | unlink(output_file); // in case is there |
35 | create_empty_file_as_root(file, 0644); | 62 | create_empty_file_as_root(output_file, 0644); |
36 | if (chown(file, getuid(), getgid())) | 63 | if (chown(output_file, getuid(), getgid())) |
37 | errExit("chown"); | 64 | errExit("chown"); |
38 | 65 | ||
39 | // run fldd to extact the list of file | 66 | // run fldd to extact the list of file |
40 | sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, exe, file); | 67 | sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, lib, output_file); |
41 | 68 | ||
42 | // open the list of libraries and install them on by one | 69 | // open the list of libraries and install them on by one |
43 | FILE *fp = fopen(file, "r"); | 70 | FILE *fp = fopen(output_file, "r"); |
44 | if (!fp) | 71 | if (!fp) |
45 | errExit("fopen"); | 72 | errExit("fopen"); |
46 | 73 | ||
@@ -56,22 +83,67 @@ static void copy_libs(const char *exe, const char *dir, const char *file) { | |||
56 | fclose(fp); | 83 | fclose(fp); |
57 | } | 84 | } |
58 | 85 | ||
86 | // return 1 if the file is valid | ||
87 | static char *valid_library(const char *lib) { | ||
88 | // filename check | ||
89 | int len = strlen(lib); | ||
90 | if (strcspn(lib, "\\&!?\"'<>%^(){}[];,*") != (size_t)len || | ||
91 | strstr(lib, "..")) { | ||
92 | fprintf(stderr, "Error: \"%s\" is an invalid library\n", lib); | ||
93 | exit(1); | ||
94 | } | ||
95 | |||
96 | // find the library | ||
97 | int i; | ||
98 | for (i = 0; lib_paths[i]; i++) { | ||
99 | char *fname; | ||
100 | if (asprintf(&fname, "%s/%s", lib_paths[i], lib) == -1) | ||
101 | errExit("asprintf"); | ||
102 | |||
103 | // existing file owned by root | ||
104 | struct stat s; | ||
105 | if (stat(fname, &s) == 0 && s.st_uid == 0) { | ||
106 | return fname; | ||
107 | } | ||
108 | free(fname); | ||
109 | } | ||
110 | |||
111 | fwarning("%s library not found, skipping...\n", lib); | ||
112 | return NULL; | ||
113 | } | ||
114 | |||
59 | 115 | ||
60 | void fs_private_lib(void) { | 116 | void fs_private_lib(void) { |
61 | // char *private_list = cfg.lib_private_keep; | 117 | char *private_list = cfg.lib_private_keep; |
118 | |||
119 | if (arg_debug) | ||
120 | printf("Starting private-lib processing: program %s, shell %s\n", | ||
121 | (cfg.original_program_index > 0)? cfg.original_argv[cfg.original_program_index]: "none", | ||
122 | (arg_shell_none)? "none": cfg.shell); | ||
62 | 123 | ||
63 | // create /run/firejail/mnt/lib directory | 124 | // create /run/firejail/mnt/lib directory |
64 | mkdir_attr(RUN_LIB_DIR, 0755, 0, 0); | 125 | mkdir_attr(RUN_LIB_DIR, 0755, 0, 0); |
65 | 126 | ||
127 | // fix libselinux linking problem on Debian stretch; the library is | ||
128 | // linked in most basic command utilities (ls, cp, find etc.), and it | ||
129 | // seems to have a path hardlinked under /lib/x86_64-linux-gnu directory. | ||
130 | struct stat s; | ||
131 | if (stat("/lib/x86_64-linux-gnu/libselinux.so.1", &s) == 0) { | ||
132 | mkdir_attr(RUN_LIB_DIR "/x86_64-linux-gnu", 0755, 0, 0); | ||
133 | duplicate("/lib/x86_64-linux-gnu/libselinux.so.1", RUN_LIB_DIR "/x86_64-linux-gnu"); | ||
134 | } | ||
135 | |||
66 | // copy the libs in the new lib directory for the main exe | 136 | // copy the libs in the new lib directory for the main exe |
67 | if (cfg.original_program_index > 0) | 137 | if (cfg.original_program_index > 0) |
68 | copy_libs(cfg.original_argv[cfg.original_program_index], RUN_LIB_DIR, RUN_LIB_FILE); | 138 | copy_exe(cfg.original_argv[cfg.original_program_index], RUN_LIB_DIR, RUN_LIB_FILE); |
69 | 139 | ||
70 | // for the shell | 140 | // for the shell |
71 | if (!arg_shell_none) | 141 | if (!arg_shell_none) { |
72 | copy_libs(cfg.shell, RUN_LIB_DIR, RUN_LIB_FILE); | 142 | copy_exe(cfg.shell, RUN_LIB_DIR, RUN_LIB_FILE); |
143 | // a shell is useless without ls command | ||
144 | copy_libs("/bin/ls", RUN_LIB_DIR, RUN_LIB_FILE); | ||
145 | } | ||
73 | 146 | ||
74 | #if 0 // TODO - work in progress | ||
75 | // for the listed libs | 147 | // for the listed libs |
76 | if (private_list && *private_list != '\0') { | 148 | if (private_list && *private_list != '\0') { |
77 | if (arg_debug) | 149 | if (arg_debug) |
@@ -82,14 +154,24 @@ void fs_private_lib(void) { | |||
82 | errExit("strdup"); | 154 | errExit("strdup"); |
83 | 155 | ||
84 | char *ptr = strtok(dlist, ","); | 156 | char *ptr = strtok(dlist, ","); |
85 | copy_libs_for_lib(ptr, RUN_LIB_DIR); | 157 | char *lib = valid_library(ptr); |
86 | 158 | if (lib) { | |
87 | while ((ptr = strtok(NULL, ",")) != NULL) | 159 | duplicate(lib, RUN_LIB_DIR); |
88 | copy_libs_for_lib(ptr, RUN_LIB_DIR); | 160 | copy_libs(lib, RUN_LIB_DIR, RUN_LIB_FILE); |
161 | free(lib); | ||
162 | } | ||
163 | |||
164 | while ((ptr = strtok(NULL, ",")) != NULL) { | ||
165 | lib = valid_library(ptr); | ||
166 | if (lib) { | ||
167 | duplicate(lib, RUN_LIB_DIR); | ||
168 | copy_libs(lib, RUN_LIB_DIR, RUN_LIB_FILE); | ||
169 | free(lib); | ||
170 | } | ||
171 | } | ||
89 | free(dlist); | 172 | free(dlist); |
90 | fs_logger_print(); | 173 | fs_logger_print(); |
91 | } | 174 | } |
92 | #endif | ||
93 | 175 | ||
94 | // for our trace and tracelog libs | 176 | // for our trace and tracelog libs |
95 | if (arg_trace) | 177 | if (arg_trace) |