diff options
author | netblue30 <netblue30@yahoo.com> | 2016-03-11 07:47:35 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-03-11 07:47:35 -0500 |
commit | 94231ecb35b7628fbda2688058189dfe29dcacbb (patch) | |
tree | b0d489b0d6c6ac19423af7ae2b78fe9e6e5c97d0 /src/firejail/ls.c | |
parent | cleanup (diff) | |
download | firejail-94231ecb35b7628fbda2688058189dfe29dcacbb.tar.gz firejail-94231ecb35b7628fbda2688058189dfe29dcacbb.tar.zst firejail-94231ecb35b7628fbda2688058189dfe29dcacbb.zip |
--get option
Diffstat (limited to 'src/firejail/ls.c')
-rw-r--r-- | src/firejail/ls.c | 184 |
1 files changed, 135 insertions, 49 deletions
diff --git a/src/firejail/ls.c b/src/firejail/ls.c index fe6348312..6a8d6acbd 100644 --- a/src/firejail/ls.c +++ b/src/firejail/ls.c | |||
@@ -184,7 +184,7 @@ static void print_directory(const char *path) { | |||
184 | free(namelist); | 184 | free(namelist); |
185 | } | 185 | } |
186 | 186 | ||
187 | void ls_name(const char *name, const char *path) { | 187 | void sandboxfs_name(int op, const char *name, const char *path) { |
188 | EUID_ASSERT(); | 188 | EUID_ASSERT(); |
189 | 189 | ||
190 | if (!name || strlen(name) == 0) { | 190 | if (!name || strlen(name) == 0) { |
@@ -197,10 +197,10 @@ void ls_name(const char *name, const char *path) { | |||
197 | exit(1); | 197 | exit(1); |
198 | } | 198 | } |
199 | 199 | ||
200 | ls(pid, path); | 200 | sandboxfs(op, pid, path); |
201 | } | 201 | } |
202 | 202 | ||
203 | void ls(pid_t pid, const char *path) { | 203 | void sandboxfs(int op, pid_t pid, const char *path) { |
204 | EUID_ASSERT(); | 204 | EUID_ASSERT(); |
205 | 205 | ||
206 | // if the pid is that of a firejail process, use the pid of the first child process | 206 | // if the pid is that of a firejail process, use the pid of the first child process |
@@ -225,16 +225,6 @@ void ls(pid_t pid, const char *path) { | |||
225 | } | 225 | } |
226 | } | 226 | } |
227 | 227 | ||
228 | EUID_ROOT(); | ||
229 | // chroot | ||
230 | char *rootdir; | ||
231 | if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) | ||
232 | errExit("asprintf"); | ||
233 | if (chroot(rootdir) < 0) | ||
234 | errExit("chroot"); | ||
235 | if (chdir("/") < 0) | ||
236 | errExit("chdir"); | ||
237 | |||
238 | // full path or file in current directory? | 228 | // full path or file in current directory? |
239 | char *fname; | 229 | char *fname; |
240 | if (*path == '/') { | 230 | if (*path == '/') { |
@@ -251,55 +241,151 @@ void ls(pid_t pid, const char *path) { | |||
251 | exit(1); | 241 | exit(1); |
252 | } | 242 | } |
253 | 243 | ||
254 | // access chek is performed with the real UID | 244 | // sandbox root directory |
255 | if (access(fname, R_OK) == -1) { | 245 | char *rootdir; |
256 | fprintf(stderr, "Error: Cannot access file %s\n", fname); | 246 | if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) |
257 | exit(1); | 247 | errExit("asprintf"); |
258 | } | ||
259 | 248 | ||
260 | // list directory contents | 249 | if (op == SANDBOX_FS_LS) { |
261 | struct stat s; | 250 | EUID_ROOT(); |
262 | if (stat(fname, &s) == -1) { | 251 | // chroot |
263 | fprintf(stderr, "Error: Cannot access file %s\n", fname); | 252 | if (chroot(rootdir) < 0) |
264 | exit(1); | 253 | errExit("chroot"); |
254 | if (chdir("/") < 0) | ||
255 | errExit("chdir"); | ||
256 | |||
257 | // access chek is performed with the real UID | ||
258 | if (access(fname, R_OK) == -1) { | ||
259 | fprintf(stderr, "Error: Cannot access file %s\n", fname); | ||
260 | exit(1); | ||
261 | } | ||
262 | |||
263 | // list directory contents | ||
264 | struct stat s; | ||
265 | if (stat(fname, &s) == -1) { | ||
266 | fprintf(stderr, "Error: Cannot access file %s\n", fname); | ||
267 | exit(1); | ||
268 | } | ||
269 | if (S_ISDIR(s.st_mode)) { | ||
270 | char *rp = realpath(fname, NULL); | ||
271 | if (!rp) { | ||
272 | fprintf(stderr, "Error: Cannot access file %s\n", fname); | ||
273 | exit(1); | ||
274 | } | ||
275 | if (arg_debug) | ||
276 | printf("realpath %s\n", rp); | ||
277 | |||
278 | char *dir; | ||
279 | if (asprintf(&dir, "%s/", rp) == -1) | ||
280 | errExit("asprintf"); | ||
281 | |||
282 | print_directory(dir); | ||
283 | free(rp); | ||
284 | free(dir); | ||
285 | } | ||
286 | else { | ||
287 | char *rp = realpath(fname, NULL); | ||
288 | if (!rp) { | ||
289 | fprintf(stderr, "Error: Cannot access file %s\n", fname); | ||
290 | exit(1); | ||
291 | } | ||
292 | if (arg_debug) | ||
293 | printf("realpath %s\n", rp); | ||
294 | char *split = strrchr(rp, '/'); | ||
295 | if (split) { | ||
296 | *split = '\0'; | ||
297 | char *rp2 = split + 1; | ||
298 | if (arg_debug) | ||
299 | printf("path %s, file %s\n", rp, rp2); | ||
300 | print_file_or_dir(rp, rp2, 1); | ||
301 | } | ||
302 | free(rp); | ||
303 | } | ||
265 | } | 304 | } |
266 | if (S_ISDIR(s.st_mode)) { | 305 | |
267 | char *rp = realpath(fname, NULL); | 306 | // get file from sandbox |
268 | if (!rp) { | 307 | else if (op == SANDBOX_FS_GET) { |
308 | // check source file (sandbox) | ||
309 | char *src_fname; | ||
310 | if (asprintf(&src_fname, "%s%s", rootdir, fname) == -1) | ||
311 | errExit("asprintf"); | ||
312 | EUID_ROOT(); | ||
313 | struct stat s; | ||
314 | if (stat(src_fname, &s) == -1) { | ||
269 | fprintf(stderr, "Error: Cannot access file %s\n", fname); | 315 | fprintf(stderr, "Error: Cannot access file %s\n", fname); |
270 | exit(1); | 316 | exit(1); |
271 | } | 317 | } |
272 | if (arg_debug) | 318 | |
273 | printf("realpath %s\n", rp); | 319 | |
320 | // try to open the source file - we need to chroot | ||
321 | pid_t child = fork(); | ||
322 | if (child < 0) | ||
323 | errExit("fork"); | ||
324 | if (child == 0) { | ||
325 | // chroot | ||
326 | if (chroot(rootdir) < 0) | ||
327 | errExit("chroot"); | ||
328 | if (chdir("/") < 0) | ||
329 | errExit("chdir"); | ||
330 | |||
331 | // drop privileges | ||
332 | drop_privs(0); | ||
333 | |||
334 | // try to read the file | ||
335 | if (access(fname, R_OK) == -1) { | ||
336 | fprintf(stderr, "Error: Cannot read file %s\n", fname); | ||
337 | exit(1); | ||
338 | } | ||
339 | exit(0); | ||
340 | } | ||
274 | 341 | ||
275 | char *dir; | 342 | // wait for the child to finish |
276 | if (asprintf(&dir, "%s/", rp) == -1) | 343 | int status = NULL; |
277 | errExit("asprintf"); | 344 | waitpid(child, &status, 0); |
345 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); | ||
346 | else | ||
347 | exit(1); | ||
348 | EUID_USER(); | ||
278 | 349 | ||
279 | print_directory(dir); | 350 | // check destination file (host) |
280 | free(rp); | 351 | char *dest_fname = strrchr(fname, '/'); |
281 | free(dir); | 352 | if (!dest_fname || *(++dest_fname) == '\0') { |
282 | } | 353 | fprintf(stderr, "Error: invalid file name %s\n", fname); |
283 | else { | ||
284 | char *rp = realpath(fname, NULL); | ||
285 | if (!rp) { | ||
286 | fprintf(stderr, "Error: Cannot access file %s\n", fname); | ||
287 | exit(1); | 354 | exit(1); |
288 | } | 355 | } |
289 | if (arg_debug) | 356 | |
290 | printf("realpath %s\n", rp); | 357 | if (access(dest_fname, F_OK) == -1) { |
291 | char *split = strrchr(rp, '/'); | 358 | // try to create the file |
292 | if (split) { | 359 | FILE *fp = fopen(dest_fname, "w"); |
293 | *split = '\0'; | 360 | if (!fp) { |
294 | char *rp2 = split + 1; | 361 | fprintf(stderr, "Error: cannot create %s file\n", dest_fname); |
295 | if (arg_debug) | 362 | exit(1); |
296 | printf("path %s, file %s\n", rp, rp2); | 363 | } |
297 | print_file_or_dir(rp, rp2, 1); | 364 | fclose(fp); |
298 | } | 365 | } |
299 | free(rp); | 366 | else { |
367 | if (access(dest_fname, W_OK) == -1) { | ||
368 | fprintf(stderr, "Error: cannot writee %s file\n", dest_fname); | ||
369 | exit(1); | ||
370 | } | ||
371 | } | ||
372 | // copy file | ||
373 | EUID_ROOT(); | ||
374 | copy_file(src_fname, dest_fname); | ||
375 | if (chown(dest_fname, getuid(), getgid()) == -1) | ||
376 | errExit("chown"); | ||
377 | if (chmod(dest_fname, 0644) == -1) | ||
378 | errExit("chmod"); | ||
379 | EUID_USER(); | ||
300 | } | 380 | } |
381 | |||
382 | // put file in sandbox | ||
383 | else if (op == SANDBOX_FS_LS) { | ||
384 | printf("todo!\n"); | ||
385 | } | ||
301 | 386 | ||
302 | free(fname); | 387 | free(fname); |
388 | free(rootdir); | ||
303 | 389 | ||
304 | exit(0); | 390 | exit(0); |
305 | } | 391 | } |