From ccd01529adc647e75b618aa35c1742cffd17c694 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Thu, 4 Jul 2019 12:22:07 -0400 Subject: fix #2820 - adjustable file copy limit; export FIREJAIL_DEBUG into sbox --- src/fcopy/main.c | 19 ++++++++++++++++--- src/firejail/checkcfg.c | 6 ++++++ src/firejail/firejail.h | 1 + src/firejail/sbox.c | 24 +++++++++++++++++------- 4 files changed, 40 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/fcopy/main.c b/src/fcopy/main.c index 9fca2a39b..3f507a361 100644 --- a/src/fcopy/main.c +++ b/src/fcopy/main.c @@ -25,9 +25,11 @@ #include int arg_quiet = 0; +int arg_debug = 0; static int arg_follow_link = 0; -#define COPY_LIMIT (500 * 1024 *1024) +static int copy_limit = 500 * 1024 *1024; // 500 MB +#define COPY_LIMIT ( static int size_limit_reached = 0; static unsigned file_cnt = 0; static unsigned size_cnt = 0; @@ -184,8 +186,8 @@ static int fs_copydir(const char *infname, const struct stat *st, int ftype, str mode_t mode = s.st_mode; // recalculate size - if ((s.st_size + size_cnt) > COPY_LIMIT) { - fprintf(stderr, "Error fcopy: size limit of %dMB reached\n", (COPY_LIMIT / 1024) / 1024); + if ((s.st_size + size_cnt) > copy_limit) { + fprintf(stderr, "Error fcopy: size limit of %dMB reached\n", (copy_limit / 1024) / 1024); size_limit_reached = 1; free(outfname); return 0; @@ -330,6 +332,9 @@ int main(int argc, char **argv) { char *quiet = getenv("FIREJAIL_QUIET"); if (quiet && strcmp(quiet, "yes") == 0) arg_quiet = 1; + char *debug = getenv("FIREJAIL_DEBUG"); + if (debug && strcmp(debug, "yes") == 0) + arg_debug = 1; char *src; char *dest; @@ -384,6 +389,14 @@ int main(int argc, char **argv) { exit(1); } + // extract copy limit size from env variable, if any + char *cl = getenv("FIREJAIL_FILE_COPY_LIMIT"); + if (cl) { + copy_limit = atoi(cl) * 1024 * 1024; + if (arg_debug) + printf("file copy limit %d bytes\n", copy_limit); + } + // copy files if ((arg_follow_link ? stat : lstat)(src, &s) == -1) { fprintf(stderr, "Error fcopy: src %s: %s\n", src, strerror(errno)); diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index b11d795a9..f94b95d60 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c @@ -207,6 +207,12 @@ int checkcfg(int val) { goto errout; cfg_val[CFG_ARP_PROBES] = arp_probes; } + + // file copy limit + else if (strncmp(ptr, "file-copy-limit ", 16) == 0) { + if (setenv("FIREJAIL_FILE_COPY_LIMIT", ptr + 16, 1) == -1) + errExit("setenv"); + } else goto errout; diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 630adc3d7..7664c8037 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -720,6 +720,7 @@ enum { CFG_PRIVATE_CACHE, CFG_CGROUP, CFG_NAME_CHANGE, + // CFG_FILE_COPY_LIMIT - file copy limit handled using setenv/getenv CFG_MAX // this should always be the last entry }; extern char *xephyr_screen; diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c index 7dca9aa99..f387d25fa 100644 --- a/src/firejail/sbox.c +++ b/src/firejail/sbox.c @@ -129,8 +129,24 @@ int sbox_run(unsigned filter, int num, ...) { if (child < 0) errExit("fork"); if (child == 0) { - // clean the new process + // preserve firejail-specific env vars + char *cl = getenv("FIREJAIL_FILE_COPY_LIMIT"); + if (cl) { + // duplicate the value, who knows what's going to happen with it in clearenv! + cl = strdup(cl); + if (!cl) + errExit("strdup"); + } clearenv(); + if (cl) { + if (setenv("FIREJAIL_FILE_COPY_LIMIT", cl, 1) == -1) + errExit("setenv"); + free(cl); + } + if (arg_quiet) // --quiet is passed as an environment variable + setenv("FIREJAIL_QUIET", "yes", 1); + if (arg_debug) // --debug is passed as an environment variable + setenv("FIREJAIL_DEBUG", "yes", 1); if (filter & SBOX_STDIN_FROM_FILE) { int fd; @@ -196,12 +212,6 @@ int sbox_run(unsigned filter, int num, ...) { else if (filter & SBOX_USER) drop_privs(1); - clearenv(); - - // --quiet is passed as an environment variable - if (arg_quiet) - setenv("FIREJAIL_QUIET", "yes", 1); - if (arg[0]) // get rid of scan-build warning execvp(arg[0], arg); else -- cgit v1.2.3-70-g09d2