This patch will upgrade Sudo version 1.8.5 patchlevel 1 to Sudo version 1.8.5 patchlevel 2. To apply: $ cd sudo-1.8.5p1 $ patch -p1 < sudo-1.8.5p2.patch diff -urNa sudo-1.8.5p1/ChangeLog sudo-1.8.5p2/ChangeLog --- sudo-1.8.5p1/ChangeLog Thu May 17 15:54:58 2012 +++ sudo-1.8.5p2/ChangeLog Tue May 29 14:32:20 2012 @@ -1,3 +1,26 @@ +2012-05-29 Todd C. Miller + + * NEWS: + Update for sudo 1.8.5p2 + [d369d4d40a19] + +2012-05-27 Todd C. Miller + + * src/env_hooks.c, src/sudo.h, src/tgetpass.c: + Provide unhooked version of getenv() and use it when looking up + DISPLAY and SUDO_ASKPASS in the environment. + [04dbdccf4a14] + +2012-05-21 Todd C. Miller + + * plugins/sudoers/set_perms.c, plugins/sudoers/sudoers.c: + If sudoers_mode is group-readable but the actual sudoers file is + not, open the file as uid 0, not uid 1. This fixes a problem when + sudoers has a more restrictive mode than what sudo expects to find. + In older versions, sudo would silently chmod the file to add the + group-readable bit. + [c056b6003e6f] + 2012-05-17 Todd C. Miller * NEWS, configure, configure.in: diff -urNa sudo-1.8.5p1/NEWS sudo-1.8.5p2/NEWS --- sudo-1.8.5p1/NEWS Thu May 17 15:53:53 2012 +++ sudo-1.8.5p2/NEWS Tue May 29 14:29:04 2012 @@ -1,3 +1,12 @@ +What's new in Sudo 1.8.5p2? + + * Fixed use of the SUDO_ASKPASS environment variable which was + broken in Sudo 1.8.5. + + * Fixed a problem reading the sudoers file when the file mode is + more restrictive than the expected mode. For example, when the + expected sudoers file mode is 0440 but the actual mode is 0400. + What's new in Sudo 1.8.5p1? * Fixed a bug that prevented files in an include directory from diff -urNa sudo-1.8.5p1/configure sudo-1.8.5p2/configure --- sudo-1.8.5p1/configure Thu May 17 15:53:53 2012 +++ sudo-1.8.5p2/configure Tue May 29 14:32:55 2012 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for sudo 1.8.5p1. +# Generated by GNU Autoconf 2.68 for sudo 1.8.5p2. # # Report bugs to . # @@ -570,8 +570,8 @@ # Identity of this package. PACKAGE_NAME='sudo' PACKAGE_TARNAME='sudo' -PACKAGE_VERSION='1.8.5p1' -PACKAGE_STRING='sudo 1.8.5p1' +PACKAGE_VERSION='1.8.5p2' +PACKAGE_STRING='sudo 1.8.5p2' PACKAGE_BUGREPORT='http://www.sudo.ws/bugs/' PACKAGE_URL='' @@ -1447,7 +1447,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sudo 1.8.5p1 to adapt to many kinds of systems. +\`configure' configures sudo 1.8.5p2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1512,7 +1512,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sudo 1.8.5p1:";; + short | recursive ) echo "Configuration of sudo 1.8.5p2:";; esac cat <<\_ACEOF @@ -1730,7 +1730,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sudo configure 1.8.5p1 +sudo configure 1.8.5p2 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2434,7 +2434,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sudo $as_me 1.8.5p1, which was +It was created by sudo $as_me 1.8.5p2, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -20682,7 +20682,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sudo $as_me 1.8.5p1, which was +This file was extended by sudo $as_me 1.8.5p2, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20748,7 +20748,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sudo config.status 1.8.5p1 +sudo config.status 1.8.5p2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff -urNa sudo-1.8.5p1/configure.in sudo-1.8.5p2/configure.in --- sudo-1.8.5p1/configure.in Thu May 17 15:53:54 2012 +++ sudo-1.8.5p2/configure.in Tue May 29 14:32:41 2012 @@ -3,7 +3,7 @@ dnl dnl Copyright (c) 1994-1996,1998-2012 Todd C. Miller dnl -AC_INIT([sudo], [1.8.5p1], [http://www.sudo.ws/bugs/], [sudo]) +AC_INIT([sudo], [1.8.5p2], [http://www.sudo.ws/bugs/], [sudo]) AC_CONFIG_HEADER([config.h pathnames.h]) dnl dnl Note: this must come after AC_INIT diff -urNa sudo-1.8.5p1/plugins/sudoers/set_perms.c sudo-1.8.5p2/plugins/sudoers/set_perms.c --- sudo-1.8.5p1/plugins/sudoers/set_perms.c Tue May 15 12:22:03 2012 +++ sudo-1.8.5p2/plugins/sudoers/set_perms.c Tue May 29 14:11:35 2012 @@ -307,7 +307,7 @@ * we use a non-zero uid in order to avoid NFS lossage. * Using uid 1 is a bit bogus but should work on all OS's. */ - if (sudoers_uid == ROOT_UID && (sudoers_mode & 040)) + if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP)) state->euid = 1; else state->euid = sudoers_uid; @@ -617,7 +617,7 @@ * we use a non-zero uid in order to avoid NFS lossage. * Using uid 1 is a bit bogus but should work on all OS's. */ - if (sudoers_uid == ROOT_UID && (sudoers_mode & 040)) + if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP)) state->euid = 1; else state->euid = sudoers_uid; @@ -990,7 +990,7 @@ * we use a non-zero uid in order to avoid NFS lossage. * Using uid 1 is a bit bogus but should work on all OS's. */ - if (sudoers_uid == ROOT_UID && (sudoers_mode & 040)) + if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP)) state->euid = 1; else state->euid = sudoers_uid; @@ -1276,7 +1276,7 @@ * we use a non-zero uid in order to avoid NFS lossage. * Using uid 1 is a bit bogus but should work on all OS's. */ - if (sudoers_uid == ROOT_UID && (sudoers_mode & 040)) + if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP)) state->euid = 1; else state->euid = sudoers_uid; diff -urNa sudo-1.8.5p1/plugins/sudoers/sudoers.c sudo-1.8.5p2/plugins/sudoers/sudoers.c --- sudo-1.8.5p1/plugins/sudoers/sudoers.c Tue May 15 12:22:03 2012 +++ sudo-1.8.5p2/plugins/sudoers/sudoers.c Tue May 29 14:11:35 2012 @@ -975,13 +975,23 @@ switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) { case SUDO_PATH_SECURE: + /* + * If we are expecting sudoers to be group readable but + * it is not, we must open the file as root, not uid 1. + */ + if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP)) { + if ((sb.st_mode & S_IRGRP) == 0) { + restore_perms(); + set_perms(PERM_ROOT); + } + } + /* + * Open sudoers and make sure we can read it so we can present + * the user with a reasonable error message (unlike the lexer). + */ if ((fp = fopen(sudoers, "r")) == NULL) { log_error(USE_ERRNO, _("unable to open %s"), sudoers); } else { - /* - * Make sure we can actually read sudoers so we can present the - * user with a reasonable error message (unlike the lexer). - */ if (sb.st_size != 0 && fgetc(fp) == EOF) { log_error(USE_ERRNO, _("unable to read %s"), sudoers); diff -urNa sudo-1.8.5p1/src/env_hooks.c sudo-1.8.5p2/src/env_hooks.c --- sudo-1.8.5p1/src/env_hooks.c Tue May 15 12:22:03 2012 +++ sudo-1.8.5p2/src/env_hooks.c Tue May 29 14:10:51 2012 @@ -70,6 +70,19 @@ typedef char * (*sudo_fn_getenv_t)(const char *); char * +getenv_unhooked(const char *name) +{ +#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) + sudo_fn_getenv_t fn; + + fn = (sudo_fn_getenv_t)dlsym(RTLD_NEXT, "getenv"); + if (fn != NULL) + return fn(name); +#endif /* HAVE_DLOPEN && RTLD_NEXT */ + return rpl_getenv(name); +} + +char * getenv(const char *name) { char *val = NULL; @@ -79,16 +92,8 @@ return val; case SUDO_HOOK_RET_ERROR: return NULL; - default: { -#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) - sudo_fn_getenv_t fn; - - fn = (sudo_fn_getenv_t)dlsym(RTLD_NEXT, "getenv"); - if (fn != NULL) - return fn(name); -#endif /* HAVE_DLOPEN && RTLD_NEXT */ - return rpl_getenv(name); - } + default: + return getenv_unhooked(name); } } @@ -136,6 +141,19 @@ typedef int (*sudo_fn_putenv_t)(PUTENV_CONST char *); +static int +putenv_unhooked(PUTENV_CONST char *string) +{ +#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) + sudo_fn_putenv_t fn; + + fn = (sudo_fn_putenv_t)dlsym(RTLD_NEXT, "putenv"); + if (fn != NULL) + return fn(string); +#endif /* HAVE_DLOPEN && RTLD_NEXT */ + return rpl_putenv(string); +} + int putenv(PUTENV_CONST char *string) { @@ -144,16 +162,8 @@ return 0; case SUDO_HOOK_RET_ERROR: return -1; - default: { -#if defined(HAVE_DLOPEN) && defined(RTLD_NEXT) - sudo_fn_putenv_t fn; - - fn = (sudo_fn_putenv_t)dlsym(RTLD_NEXT, "putenv"); - if (fn != NULL) - return fn(string); -#endif /* HAVE_DLOPEN && RTLD_NEXT */ - return rpl_putenv(string); - } + default: + return putenv_unhooked(string); } } @@ -201,6 +211,19 @@ typedef int (*sudo_fn_setenv_t)(const char *, const char *, int); +static int +setenv_unhooked(const char *var, const char *val, int overwrite) +{ +#if defined(HAVE_SETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT) + sudo_fn_setenv_t fn; + + fn = (sudo_fn_setenv_t)dlsym(RTLD_NEXT, "setenv"); + if (fn != NULL) + return fn(var, val, overwrite); +#endif /* HAVE_SETENV && HAVE_DLOPEN && RTLD_NEXT */ + return rpl_setenv(var, val, overwrite); +} + int setenv(const char *var, const char *val, int overwrite) { @@ -209,24 +232,12 @@ return 0; case SUDO_HOOK_RET_ERROR: return -1; - default: { -#if defined(HAVE_SETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT) - sudo_fn_setenv_t fn; - - fn = (sudo_fn_setenv_t)dlsym(RTLD_NEXT, "setenv"); - if (fn != NULL) - return fn(var, val, overwrite); -#endif /* HAVE_SETENV && HAVE_DLOPEN && RTLD_NEXT */ - return rpl_setenv(var, val, overwrite); - } + default: + return setenv_unhooked(var, val, overwrite); } } -#ifdef UNSETENV_VOID -static void -#else -int -#endif +static int rpl_unsetenv(const char *var) { char **ep = environ; @@ -234,11 +245,7 @@ if (var == NULL || *var == '\0' || strchr(var, '=') != NULL) { errno = EINVAL; -#ifdef UNSETENV_VOID - return; -#else return -1; -#endif } len = strlen(var); @@ -253,9 +260,7 @@ ep++; } } -#ifndef UNSETENV_VOID return 0; -#endif } #ifdef UNSETENV_VOID @@ -264,47 +269,49 @@ typedef int (*sudo_fn_unsetenv_t)(const char *); #endif -#ifdef UNSETENV_VOID -void -unsetenv(const char *var) +static int +unsetenv_unhooked(const char *var) { - switch (process_hooks_unsetenv(var)) { - case SUDO_HOOK_RET_STOP: - return 0; - case SUDO_HOOK_RET_ERROR: - return -1; - default: { + int rval = 0; #if defined(HAVE_UNSETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT) - sudo_fn_unsetenv_t fn; + sudo_fn_unsetenv_t fn; - fn = (sudo_fn_unsetenv_t)dlsym(RTLD_NEXT, "unsetenv"); - if (fn != NULL) - fn(var); - else + fn = (sudo_fn_unsetenv_t)dlsym(RTLD_NEXT, "unsetenv"); + if (fn != NULL) { +# ifdef UNSETENV_VOID + fn(var); +# else + rval = fn(var); +# endif + } else #endif /* HAVE_UNSETENV && HAVE_DLOPEN && RTLD_NEXT */ - rpl_unsetenv(var); - } + { + rval = rpl_unsetenv(var); } + return rval; } + +#ifdef UNSETENV_VOID +void #else int +#endif unsetenv(const char *var) { + int rval; + switch (process_hooks_unsetenv(var)) { case SUDO_HOOK_RET_STOP: - return 0; + rval = 0; + break; case SUDO_HOOK_RET_ERROR: - return -1; - default: { -#if defined(HAVE_UNSETENV) && defined(HAVE_DLOPEN) && defined(RTLD_NEXT) - sudo_fn_unsetenv_t fn; - - fn = (sudo_fn_unsetenv_t)dlsym(RTLD_NEXT, "unsetenv"); - if (fn != NULL) - return fn(var); -#endif /* HAVE_UNSETENV && HAVE_DLOPEN && RTLD_NEXT */ - return rpl_unsetenv(var); - } + rval = -1; + break; + default: + rval = unsetenv_unhooked(var); + break; } +#ifndef UNSETENV_VOID + return rval; +#endif } -#endif /* UNSETENV_VOID */ diff -urNa sudo-1.8.5p1/src/sudo.h sudo-1.8.5p2/src/sudo.h --- sudo-1.8.5p1/src/sudo.h Tue May 15 12:22:03 2012 +++ sudo-1.8.5p2/src/sudo.h Tue May 29 14:10:51 2012 @@ -237,6 +237,9 @@ int process_hooks_putenv(char *string); int process_hooks_unsetenv(const char *name); +/* env_hooks.c */ +char *getenv_unhooked(const char *name); + /* interfaces.c */ int get_net_ifs(char **addrinfo); diff -urNa sudo-1.8.5p1/src/tgetpass.c sudo-1.8.5p2/src/tgetpass.c --- sudo-1.8.5p1/src/tgetpass.c Tue May 15 12:22:03 2012 +++ sudo-1.8.5p2/src/tgetpass.c Tue May 29 14:10:51 2012 @@ -78,7 +78,7 @@ (void) fflush(stdout); if (askpass == NULL) { - askpass = getenv("SUDO_ASKPASS"); + askpass = getenv_unhooked("SUDO_ASKPASS"); if (askpass == NULL || *askpass == '\0') askpass = sudo_conf_askpass_path(); } @@ -86,7 +86,7 @@ /* If no tty present and we need to disable echo, try askpass. */ if (!ISSET(flags, TGP_STDIN|TGP_ECHO|TGP_ASKPASS|TGP_NOECHO_TRY) && !tty_present()) { - if (askpass == NULL || getenv("DISPLAY") == NULL) { + if (askpass == NULL || getenv_unhooked("DISPLAY") == NULL) { warningx(_("no tty present and no askpass program specified")); debug_return_str(NULL); }