From 88258569cb5f455dd39447867e559bfba20d91c7 Mon Sep 17 00:00:00 2001 From: Topi Miettinen Date: Sun, 5 Apr 2020 11:08:44 +0300 Subject: Simple sanity checks for arguments and environment Restrict number of program arguments and their length as well as number of environment variables and their length. --- src/firejail/firejail.h | 3 +++ src/firejail/main.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index dae2dfd7b..1be2bc1da 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -350,6 +350,7 @@ extern mode_t orig_umask; extern unsigned long long start_timestamp; #define MAX_ARGS 128 // maximum number of command arguments (argc) +#define MAX_ARG_LEN (PATH_MAX + 32) // --foobar=PATH extern char *fullargv[MAX_ARGS]; extern int fullargc; @@ -639,6 +640,8 @@ int check_namespace_virt(void); int check_kernel_procs(void); void run_no_sandbox(int argc, char **argv); +#define MAX_ENVS 100 // some sane maximum number of environment variables +#define MAX_ENV_LEN (PATH_MAX + 32) // FOOBAR=SOME_PATH // env.c typedef enum { SETENV = 0, diff --git a/src/firejail/main.c b/src/firejail/main.c index 922ba2edb..17e5a8140 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -982,7 +982,7 @@ static int check_postexec(const char *list) { //******************************************* // Main program //******************************************* -int main(int argc, char **argv) { +int main(int argc, char **argv, char **envp) { int i; int prog_index = -1; // index in argv where the program command starts int lockfd_network = -1; @@ -990,6 +990,7 @@ int main(int argc, char **argv) { int option_cgroup = 0; int custom_profile = 0; // custom profile loaded int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot) + char **ptr; // drop permissions by default and rise them when required EUID_INIT(); @@ -999,9 +1000,36 @@ int main(int argc, char **argv) { orig_umask = umask(022); // argument count should be larger than 0 - if (argc == 0) { + if (argc == 0 || !argv || strlen(argv[0]) == 0) { fprintf(stderr, "Error: argv[0] is NULL\n"); exit(1); + } else if (argc >= MAX_ARGS) { + fprintf(stderr, "Error: too many arguments\n"); + exit(1); + } + + // sanity check for arguments + for (i = 0; i < argc; i++) { + if (*argv[i] == 0) { + fprintf(stderr, "Error: too short arguments\n"); + exit(1); + } + if (strlen(argv[i]) >= MAX_ARG_LEN) { + fprintf(stderr, "Error: too long arguments\n"); + exit(1); + } + } + + // sanity check for environment variables + for (i = 0, ptr = envp; ptr && *ptr && i < MAX_ENVS; i++, ptr++) { + if (strlen(*ptr) >= MAX_ENV_LEN) { + fprintf(stderr, "Error: too long environment variables\n"); + exit(1); + } + } + if (i >= MAX_ENVS) { + fprintf(stderr, "Error: too many environment variables\n"); + exit(1); } // check if the user is allowed to use firejail -- cgit v1.2.3-54-g00ecf