aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs_bin.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-11-08 08:30:10 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2017-11-08 08:30:10 -0500
commitb1b1e774a175fe2ee35aa22d02c097e13873a5a9 (patch)
tree22e3fda2f21723e05a2299ef30668aa5af1119af /src/firejail/fs_bin.c
parentMerge pull request #1637 from soredake/keepassxc (diff)
downloadfirejail-b1b1e774a175fe2ee35aa22d02c097e13873a5a9.tar.gz
firejail-b1b1e774a175fe2ee35aa22d02c097e13873a5a9.tar.zst
firejail-b1b1e774a175fe2ee35aa22d02c097e13873a5a9.zip
private-bin and private-lib fixes
Diffstat (limited to 'src/firejail/fs_bin.c')
-rw-r--r--src/firejail/fs_bin.c58
1 files changed, 23 insertions, 35 deletions
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
index a17c8dac0..364431077 100644
--- a/src/firejail/fs_bin.c
+++ b/src/firejail/fs_bin.c
@@ -99,16 +99,23 @@ static char *check_dir_or_file(const char *name) {
99static int valid_full_path_file(const char *name) { 99static int valid_full_path_file(const char *name) {
100 assert(name); 100 assert(name);
101 101
102 char *real_path = realpath(name, NULL); 102 if (*name != '/')
103 if (!real_path) 103 return 0;
104 goto errexit; 104 if (strstr(name, ".."))
105 char *fname = strrchr(real_path, '/'); 105 return 0;
106 if (!fname) 106
107 goto errexit; 107 // do we have a file?
108 if (*(++fname) == '\0') 108 struct stat s;
109 goto errexit; 109 if (stat(name, &s) == -1)
110 110 return 0;
111 int found = 0; 111 // directories not allowed
112 if (S_ISDIR(s.st_mode))
113 return 0;
114 // checking access
115 if (access(name, X_OK) == -1)
116 return 0;
117
118 // check standard paths
112 int i = 0; 119 int i = 0;
113 while (paths[i]) { 120 while (paths[i]) {
114 // private-bin-no-local can be disabled in /etc/firejail/firejail.config 121 // private-bin-no-local can be disabled in /etc/firejail/firejail.config
@@ -117,34 +124,13 @@ static int valid_full_path_file(const char *name) {
117 continue; 124 continue;
118 } 125 }
119 126
120 // check file 127 int len = strlen(paths[i]);
121 char *path; 128 if (strncmp(name, paths[i], len) == 0 && name[len] == '/' && name[len + 1] != '\0')
122 if (asprintf(&path, "%s/%s", paths[i], fname) == -1) 129 return 1;
123 errExit("asprintf");
124
125 if (strcmp(real_path, path) == 0) {
126 free(path);
127 // checking access
128 if (access(real_path, X_OK) == 0)
129 found = 1;
130 break;
131 }
132
133 free(path);
134 i++; 130 i++;
135 } 131 }
136
137 if (!found)
138 goto errexit;
139
140 free(real_path);
141 return 1;
142
143errexit:
144 if (arg_debug) 132 if (arg_debug)
145 fwarning("file %s not found\n", name); 133 printf("file %s not found\n", name);
146 if (real_path)
147 free(real_path);
148 return 0; 134 return 0;
149} 135}
150 136
@@ -205,6 +191,7 @@ static void duplicate(char *fname, FILE *fplist) {
205 char *actual_path = realpath(full_path, NULL); 191 char *actual_path = realpath(full_path, NULL);
206 if (actual_path) { 192 if (actual_path) {
207 if (valid_full_path_file(actual_path)) { 193 if (valid_full_path_file(actual_path)) {
194 // solving problems such as /bin/sh -> /bin/dash
208 // copy the real file pointed by symlink 195 // copy the real file pointed by symlink
209 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, actual_path, RUN_BIN_DIR); 196 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, actual_path, RUN_BIN_DIR);
210 char *f = strrchr(actual_path, '/'); 197 char *f = strrchr(actual_path, '/');
@@ -214,6 +201,7 @@ static void duplicate(char *fname, FILE *fplist) {
214 free(actual_path); 201 free(actual_path);
215 } 202 }
216 } 203 }
204
217 // copy a file or a symlink 205 // copy a file or a symlink
218 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR); 206 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR);
219 } 207 }