aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Topi Miettinen <toiwoton@gmail.com>2020-04-05 11:08:44 +0300
committerLibravatar Topi Miettinen <toiwoton@gmail.com>2020-04-05 11:13:38 +0300
commit88258569cb5f455dd39447867e559bfba20d91c7 (patch)
tree49ea9631bb02bbd5b1f2dc5149a793f58e906ee3
parentprofile fixes (diff)
downloadfirejail-88258569cb5f455dd39447867e559bfba20d91c7.tar.gz
firejail-88258569cb5f455dd39447867e559bfba20d91c7.tar.zst
firejail-88258569cb5f455dd39447867e559bfba20d91c7.zip
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.
-rw-r--r--src/firejail/firejail.h3
-rw-r--r--src/firejail/main.c32
2 files changed, 33 insertions, 2 deletions
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;
350extern unsigned long long start_timestamp; 350extern unsigned long long start_timestamp;
351 351
352#define MAX_ARGS 128 // maximum number of command arguments (argc) 352#define MAX_ARGS 128 // maximum number of command arguments (argc)
353#define MAX_ARG_LEN (PATH_MAX + 32) // --foobar=PATH
353extern char *fullargv[MAX_ARGS]; 354extern char *fullargv[MAX_ARGS];
354extern int fullargc; 355extern int fullargc;
355 356
@@ -639,6 +640,8 @@ int check_namespace_virt(void);
639int check_kernel_procs(void); 640int check_kernel_procs(void);
640void run_no_sandbox(int argc, char **argv); 641void run_no_sandbox(int argc, char **argv);
641 642
643#define MAX_ENVS 100 // some sane maximum number of environment variables
644#define MAX_ENV_LEN (PATH_MAX + 32) // FOOBAR=SOME_PATH
642// env.c 645// env.c
643typedef enum { 646typedef enum {
644 SETENV = 0, 647 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) {
982//******************************************* 982//*******************************************
983// Main program 983// Main program
984//******************************************* 984//*******************************************
985int main(int argc, char **argv) { 985int main(int argc, char **argv, char **envp) {
986 int i; 986 int i;
987 int prog_index = -1; // index in argv where the program command starts 987 int prog_index = -1; // index in argv where the program command starts
988 int lockfd_network = -1; 988 int lockfd_network = -1;
@@ -990,6 +990,7 @@ int main(int argc, char **argv) {
990 int option_cgroup = 0; 990 int option_cgroup = 0;
991 int custom_profile = 0; // custom profile loaded 991 int custom_profile = 0; // custom profile loaded
992 int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot) 992 int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot)
993 char **ptr;
993 994
994 // drop permissions by default and rise them when required 995 // drop permissions by default and rise them when required
995 EUID_INIT(); 996 EUID_INIT();
@@ -999,9 +1000,36 @@ int main(int argc, char **argv) {
999 orig_umask = umask(022); 1000 orig_umask = umask(022);
1000 1001
1001 // argument count should be larger than 0 1002 // argument count should be larger than 0
1002 if (argc == 0) { 1003 if (argc == 0 || !argv || strlen(argv[0]) == 0) {
1003 fprintf(stderr, "Error: argv[0] is NULL\n"); 1004 fprintf(stderr, "Error: argv[0] is NULL\n");
1004 exit(1); 1005 exit(1);
1006 } else if (argc >= MAX_ARGS) {
1007 fprintf(stderr, "Error: too many arguments\n");
1008 exit(1);
1009 }
1010
1011 // sanity check for arguments
1012 for (i = 0; i < argc; i++) {
1013 if (*argv[i] == 0) {
1014 fprintf(stderr, "Error: too short arguments\n");
1015 exit(1);
1016 }
1017 if (strlen(argv[i]) >= MAX_ARG_LEN) {
1018 fprintf(stderr, "Error: too long arguments\n");
1019 exit(1);
1020 }
1021 }
1022
1023 // sanity check for environment variables
1024 for (i = 0, ptr = envp; ptr && *ptr && i < MAX_ENVS; i++, ptr++) {
1025 if (strlen(*ptr) >= MAX_ENV_LEN) {
1026 fprintf(stderr, "Error: too long environment variables\n");
1027 exit(1);
1028 }
1029 }
1030 if (i >= MAX_ENVS) {
1031 fprintf(stderr, "Error: too many environment variables\n");
1032 exit(1);
1005 } 1033 }
1006 1034
1007 // check if the user is allowed to use firejail 1035 // check if the user is allowed to use firejail