From 051a2110a4e45d0082fb53b867bc1090022eceb0 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 16 Dec 2004 18:33:49 +0000 Subject: [PATCH] Add closefrom sudoers option to start closing at a point other than 3. Add closefrom_override sudoers option and -C sudo flag to allow the user to specify a different closefrom starting point. --- def_data.c | 24 ++++++++++++++++-------- def_data.h | 24 ++++++++++++++---------- def_data.in | 18 ++++++++++++------ defaults.c | 1 + logging.c | 3 ++- sudo.c | 27 +++++++++++++++++++++++++-- sudo.pod | 14 ++++++++++++-- sudoers.pod | 14 ++++++++++++++ 8 files changed, 96 insertions(+), 29 deletions(-) diff --git a/def_data.c b/def_data.c index 19d734eee..99e4fbc0d 100644 --- a/def_data.c +++ b/def_data.c @@ -243,6 +243,22 @@ struct sudo_defs_types sudo_defs_table[] = { "noexec_file", T_STR|T_PATH, "File containing dummy exec functions: %s", NULL, + }, { + "ignore_local_sudoers", T_FLAG, + "If LDAP directory is up, do we ignore local sudoers file", + NULL, + }, { + "monitor", T_FLAG, + "Monitor children of cmnd and apply sudoers restrictions to them", + NULL, + }, { + "closefrom", T_INT, + "File descriptors >= %d will be closed before executing a command", + NULL, + }, { + "closefrom_override", T_FLAG, + "If set, users may override the value of `closefrom' with the -O option", + NULL, }, { "env_check", T_LIST|T_BOOL, "Environment variables to check for sanity:", @@ -255,14 +271,6 @@ struct sudo_defs_types sudo_defs_table[] = { "env_keep", T_LIST|T_BOOL, "Environment variables to preserve:", NULL, - }, { - "ignore_local_sudoers", T_FLAG, - "If LDAP directory is up, do we ignore local sudoers file", - NULL, - }, { - "monitor", T_FLAG, - "Monitor children of cmnd and apply sudoers restrictions to them", - NULL, }, { NULL, 0, NULL } diff --git a/def_data.h b/def_data.h index 50a7ce8fc..e3ae94330 100644 --- a/def_data.h +++ b/def_data.h @@ -108,16 +108,20 @@ #define I_NOEXEC 53 #define def_noexec_file (sudo_defs_table[54].sd_un.str) #define I_NOEXEC_FILE 54 -#define def_env_check (sudo_defs_table[55].sd_un.list) -#define I_ENV_CHECK 55 -#define def_env_delete (sudo_defs_table[56].sd_un.list) -#define I_ENV_DELETE 56 -#define def_env_keep (sudo_defs_table[57].sd_un.list) -#define I_ENV_KEEP 57 -#define def_ignore_local_sudoers (sudo_defs_table[58].sd_un.flag) -#define I_IGNORE_LOCAL_SUDOERS 58 -#define def_monitor (sudo_defs_table[59].sd_un.flag) -#define I_MONITOR 59 +#define def_ignore_local_sudoers (sudo_defs_table[55].sd_un.flag) +#define I_IGNORE_LOCAL_SUDOERS 55 +#define def_monitor (sudo_defs_table[56].sd_un.flag) +#define I_MONITOR 56 +#define def_closefrom (sudo_defs_table[57].sd_un.ival) +#define I_CLOSEFROM 57 +#define def_closefrom_override (sudo_defs_table[58].sd_un.flag) +#define I_CLOSEFROM_OVERRIDE 58 +#define def_env_check (sudo_defs_table[59].sd_un.list) +#define I_ENV_CHECK 59 +#define def_env_delete (sudo_defs_table[60].sd_un.list) +#define I_ENV_DELETE 60 +#define def_env_keep (sudo_defs_table[61].sd_un.list) +#define I_ENV_KEEP 61 enum def_tupple { never, diff --git a/def_data.in b/def_data.in index b055febe2..7806ba662 100644 --- a/def_data.in +++ b/def_data.in @@ -179,6 +179,18 @@ noexec noexec_file T_STR|T_PATH "File containing dummy exec functions: %s" +ignore_local_sudoers + T_FLAG + "If LDAP directory is up, do we ignore local sudoers file" +monitor + T_FLAG + "Monitor children of cmnd and apply sudoers restrictions to them" +closefrom + T_INT + "File descriptors >= %d will be closed before executing a command" +closefrom_override + T_FLAG + "If set, users may override the value of `closefrom' with the -O option" env_check T_LIST|T_BOOL "Environment variables to check for sanity:" @@ -188,9 +200,3 @@ env_delete env_keep T_LIST|T_BOOL "Environment variables to preserve:" -ignore_local_sudoers - T_FLAG - "If LDAP directory is up, do we ignore local sudoers file" -monitor - T_FLAG - "Monitor children of cmnd and apply sudoers restrictions to them" diff --git a/defaults.c b/defaults.c index c9bff384b..1b50c52fb 100644 --- a/defaults.c +++ b/defaults.c @@ -428,6 +428,7 @@ init_defaults() def_env_editor = TRUE; #endif def_set_logname = TRUE; + def_closefrom = STDERR_FILENO + 1; /* Syslog options need special care since they both strings and ints */ #if (LOGGING & SLOG_SYSLOG) diff --git a/logging.c b/logging.c index e28f65d21..c2db37045 100644 --- a/logging.c +++ b/logging.c @@ -490,9 +490,10 @@ send_mail(line) } argv[i] = NULL; - /* Close password and group files so we don't leak fds. */ + /* Close password, group and other fds so we don't leak. */ sudo_endpwent(); sudo_endgrent(); + closefrom(STDERR_FILENO + 1); /* * Depending on the config, either run the mailer as root diff --git a/sudo.c b/sudo.c index 631626891..353cc851d 100644 --- a/sudo.c +++ b/sudo.c @@ -116,6 +116,7 @@ extern char **zero_env __P((char **)); int Argc, NewArgc; char **Argv, **NewArgv; char *prev_user; +static int user_closefrom = -1; struct sudo_user sudo_user; struct passwd *auth_pw, *list_pw; struct interface *interfaces; @@ -189,7 +190,7 @@ main(argc, argv, envp) (void) sigaction(SIGCHLD, &sa, &saved_sa_chld); /* - * Turn off core dumps and close open files. + * Turn off core dumps and make sure fds 0-2 are open. */ initial_setup(); sudo_setpwent(); @@ -280,6 +281,14 @@ main(argc, argv, envp) exit(1); } + /* Check for -C overriding def_closefrom. */ + if (user_closefrom >= 0 && user_closefrom != def_closefrom) { + if (!def_closefrom_override) + errorx(1, "you are not permitted to use the -O option"); + else + def_closefrom = user_closefrom; + } + cmnd_status = set_cmnd(sudo_mode); #ifdef HAVE_LDAP @@ -426,6 +435,8 @@ main(argc, argv, envp) (void) sigaction(SIGTSTP, &saved_sa_tstp, NULL); (void) sigaction(SIGCHLD, &saved_sa_chld, NULL); + closefrom(def_closefrom + 1); + #ifndef PROFILING if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0) exit(0); @@ -753,6 +764,16 @@ parse_args(argc, argv) NewArgv++; break; #endif + case 'C': + if (NewArgv[1] == NULL) + usage(1); + if ((user_closefrom = atoi(NewArgv[1])) < 3) { + warningx("the argument to -O must be at least 3"); + usage(1); + } + NewArgc--; + NewArgv++; + break; case 'b': SET(rval, MODE_BACKGROUND); break; @@ -993,9 +1014,10 @@ initial_setup() (void) dup2(devnull, STDOUT_FILENO); if (miss[STDERR_FILENO]) (void) dup2(devnull, STDERR_FILENO); + if (devnull > STDERR_FILENO) + close(devnull); } } - closefrom(STDERR_FILENO + 1); } #ifdef HAVE_LOGIN_CAP_H @@ -1151,6 +1173,7 @@ usage(exit_val) #ifdef HAVE_BSD_AUTH_H " [-a auth_type]", #endif + " [-C fd]", #ifdef HAVE_LOGIN_CAP_H " [-c class|-]", #endif diff --git a/sudo.pod b/sudo.pod index 576dcc4de..8759f3385 100644 --- a/sudo.pod +++ b/sudo.pod @@ -31,8 +31,8 @@ B B<-K> | B<-L> | B<-V> | B<-h> | B<-k> | B<-v> B S<[B<-U> I]> S<[B<-u> I|I<#uid>]> B<-l> [I] -B [B<-HPSb>] S<[B<-a> I]> S<[B<-c> I|I<->]> -S<[B<-p> I]> S<[B<-u> I|I<#uid>]> +B [B<-HPSb>] S<[B<-a> I]> S<[B<-C> I]> +S<[B<-c> I|I<->]> S<[B<-p> I]> S<[B<-u> I|I<#uid>]> S<{B<-e> file [...] | B<-i> | B<-s> | I}> B [B<-S>] S<[B<-a> I]> @@ -92,6 +92,16 @@ B accepts the following command line options: =over 4 +=item -C fd + +Normally, B will close all open file descriptors other than +standard input, standard output and standard error. The B<-C> +(I) option allows the user to specify a starting point +above the standard error (file descriptor three). Values less than +three are not permitted. This option is only available if the +administrator has enabled the I option in +L. + =item -H The B<-H> (I) option sets the C environment variable diff --git a/sudoers.pod b/sudoers.pod index 030c9cd77..7724edfdf 100644 --- a/sudoers.pod +++ b/sudoers.pod @@ -477,6 +477,12 @@ Since this options tells B how to behave when no specific LDAP entries have been matched, this sudoOption is only meaningful for the cn=defaults section. This flag is I by default. +=item closefrom_override + +If set, the user may use B's B<-O> option which +overrides the default starting point at which B begins +closing open file descriptors. This flag is I by default. + =back B: @@ -520,6 +526,14 @@ The default is C<@password_timeout@>, set this to C<0> for no password timeout. Umask to use when running the command. Negate this option or set it to 0777 to preserve the user's umask. The default is C<@sudo_umask@>. +=item closefrom + +Before it executes a command, B will close all open file +descriptors other than standard input, standard output and standard +error (ie: file descriptors 0-2). The I option can be used +to specify a different file descriptor at which to start closing. +The default is 3. + =back B: -- 2.40.0