diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2015-02-10 12:59:02 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2015-02-10 12:59:02 +0000 |
commit | 8b91fc494fbb92372195cdbf61ed2ebfcab2d0db (patch) | |
tree | 18a015cc9b061a7d82bf39d520ea4960c1b19d3f | |
parent | 8d47a8a1cc7b9abeff742775d954906c76a2a164 (diff) |
Sanity check TZ environment variable; backport from sudo 1.8.12
-rw-r--r-- | usr.bin/sudo/INSTALL | 10 | ||||
-rw-r--r-- | usr.bin/sudo/aclocal.m4 | 20 | ||||
-rw-r--r-- | usr.bin/sudo/configure.in | 7 | ||||
-rw-r--r-- | usr.bin/sudo/env.c | 57 | ||||
-rw-r--r-- | usr.bin/sudo/pathnames.h | 4 | ||||
-rw-r--r-- | usr.bin/sudo/pathnames.h.in | 4 | ||||
-rw-r--r-- | usr.bin/sudo/sudoers.mdoc.in | 30 |
7 files changed, 128 insertions, 4 deletions
diff --git a/usr.bin/sudo/INSTALL b/usr.bin/sudo/INSTALL index b58852b9876..244fd3d647d 100644 --- a/usr.bin/sudo/INSTALL +++ b/usr.bin/sudo/INSTALL @@ -104,6 +104,16 @@ Directory and file names: --srcdir=DIR Find the sources in DIR [configure dir or ..] + --with-tzdir=DIR + Set the directory to the system's time zone data files. This + is only used when sanitizing the TZ environment variable to + allow for fully-qualified paths in TZ. + By default, configure will look for an existing "zoneinfo" + directory in the following locations: + /usr/share /usr/share/lib /usr/lib /etc + If no zoneinfo directory is found, the TZ variable may not + contain a fully-qualified path. + Special features/options: --with-CC=PATH Specifies path to C compiler you wish to use. diff --git a/usr.bin/sudo/aclocal.m4 b/usr.bin/sudo/aclocal.m4 index d8b55c0467b..c181d91567e 100644 --- a/usr.bin/sudo/aclocal.m4 +++ b/usr.bin/sudo/aclocal.m4 @@ -203,6 +203,26 @@ AC_DEFUN(SUDO_TYPE_INO_T, [SUDO_CHECK_TYPE(ino_t, unsigned int)]) dnl +dnl Detect time zone file directory, if any. +dnl +AC_DEFUN([SUDO_TZDIR], [AC_MSG_CHECKING(time zone data directory) +tzdir="$with_tzdir" +if test -z "$tzdir"; then + tzdir=no + for d in /usr/share /usr/share/lib /usr/lib /etc; do + if test -d "$d/zoneinfo"; then + tzdir="$d/zoneinfo" + break + fi + done +fi +AC_MSG_RESULT([$tzdir]) +if test "${tzdir}" != "no"; then + SUDO_DEFINE_UNQUOTED(_PATH_ZONEINFO, "$tzdir") +fi +])dnl + +dnl dnl check for working fnmatch(3) dnl AC_DEFUN(SUDO_FUNC_FNMATCH, diff --git a/usr.bin/sudo/configure.in b/usr.bin/sudo/configure.in index 5846de66985..d619a07678d 100644 --- a/usr.bin/sudo/configure.in +++ b/usr.bin/sudo/configure.in @@ -694,6 +694,12 @@ AC_ARG_WITH(timedir, [AS_HELP_STRING([--with-timedir], [path to the sudo timesta ;; esac]) +AC_ARG_WITH(tzdir, [AS_HELP_STRING([--with-tzdir=DIR], [path to the time zone data directory])], +[case $with_tzdir in + yes) AC_MSG_ERROR(["must give --with-tzdir an argument."]) + ;; +esac]) + AC_ARG_WITH(sendmail, [AS_HELP_STRING([--with-sendmail], [set path to sendmail]) AS_HELP_STRING([--without-sendmail], [do not send mail at all])], [case $with_sendmail in @@ -2560,6 +2566,7 @@ dnl Check for log file and timestamp locations dnl SUDO_LOGFILE SUDO_TIMEDIR +SUDO_TZDIR dnl dnl Use passwd (and secureware) auth modules? diff --git a/usr.bin/sudo/env.c b/usr.bin/sudo/env.c index ef2785d95bf..dc37afd5b24 100644 --- a/usr.bin/sudo/env.c +++ b/usr.bin/sudo/env.c @@ -186,6 +186,7 @@ static const char *initial_checkenv_table[] = { "LC_*", "LINGUAS", "TERM", + "TZ", NULL }; @@ -203,7 +204,6 @@ static const char *initial_keepenv_table[] = { "PATH", "PS1", "PS2", - "TZ", "XAUTHORITY", "XAUTHORIZATION", NULL @@ -513,6 +513,54 @@ matches_env_delete(var) } /* + * Sanity-check the TZ environment variable. + * On many systems it is possible to set this to a pathname. + */ +static int +tz_is_sane(tzval) + const char *tzval; +{ + const char *cp; + char lastch; + + /* tzcode treats a value beginning with a ':' as a path. */ + if (tzval[0] == ':') + tzval++; + + /* Reject fully-qualified TZ that doesn't being with the zoneinfo dir. */ + if (tzval[0] == '/') { +#ifdef _PATH_ZONEINFO + if (strncmp(tzval, _PATH_ZONEINFO, sizeof(_PATH_ZONEINFO) - 1) != 0 || + tzval[sizeof(_PATH_ZONEINFO) - 1] != '/') + return FALSE; +#else + /* Assume the worst. */ + return FALSE; +#endif + } + + /* + * Make sure TZ only contains printable non-space characters + * and does not contain a '..' path element. + */ + lastch = '/'; + for (cp = tzval; *cp != '\0'; cp++) { + if (isspace((unsigned char)*cp) || !isprint((unsigned char)*cp)) + return FALSE; + if (lastch == '/' && cp[0] == '.' && cp[1] == '.' && + (cp[2] == '/' || cp[2] == '\0')) + return FALSE; + lastch = *cp; + } + + /* Reject extra long TZ values (even if not a path). */ + if ((size_t)(cp - tzval) >= PATH_MAX) + return FALSE; + + return TRUE; +} + +/* * Apply the env_check list. * Returns TRUE if the variable is allowed, FALSE if denied * or -1 if no match. @@ -535,7 +583,12 @@ matches_env_check(var) iswild = FALSE; if (strncmp(cur->value, var, len) == 0 && (iswild || var[len] == '=')) { - keepit = !strpbrk(var, "/%"); + if (strncmp(var, "TZ=", 3) == 0) { + /* Special case for TZ */ + keepit = tz_is_sane(var + 3); + } else { + keepit = !strpbrk(var, "/%"); + } break; } } diff --git a/usr.bin/sudo/pathnames.h b/usr.bin/sudo/pathnames.h index 31baa082b49..bcb0cb65039 100644 --- a/usr.bin/sudo/pathnames.h +++ b/usr.bin/sudo/pathnames.h @@ -132,3 +132,7 @@ #ifndef _PATH_NETSVC_CONF /* #undef _PATH_NETSVC_CONF */ #endif /* _PATH_NETSVC_CONF */ + +#ifndef _PATH_ZONEINFO +#define _PATH_ZONEINFO "/usr/share/zoneinfo" +#endif /* _PATH_ZONEINFO */ diff --git a/usr.bin/sudo/pathnames.h.in b/usr.bin/sudo/pathnames.h.in index aec34eb69d3..8b6f3ca1aa1 100644 --- a/usr.bin/sudo/pathnames.h.in +++ b/usr.bin/sudo/pathnames.h.in @@ -129,3 +129,7 @@ #ifndef _PATH_NETSVC_CONF #undef _PATH_NETSVC_CONF #endif /* _PATH_NETSVC_CONF */ + +#ifndef _PATH_ZONEINFO +#undef _PATH_ZONEINFO +#endif /* _PATH_ZONEINFO */ diff --git a/usr.bin/sudo/sudoers.mdoc.in b/usr.bin/sudo/sudoers.mdoc.in index c21ac2f1da4..642611c0dcd 100644 --- a/usr.bin/sudo/sudoers.mdoc.in +++ b/usr.bin/sudo/sudoers.mdoc.in @@ -19,7 +19,7 @@ .\" Agency (DARPA) and Air Force Research Laboratory, Air Force .\" Materiel Command, USAF, under agreement number F39502-99-1-0512. .\" -.Dd $Mdocdate: February 15 2014 $ +.Dd $Mdocdate: February 10 2015 $ .Dt SUDOERS @mansectform@ .Os .Sh NAME @@ -2143,7 +2143,13 @@ The default value is .Sy Lists that can be used in a boolean context : .Bl -tag -width 16n .It env_check -Environment variables to be removed from the user's environment if +Environment variables to be removed from the user's environment +unless they are considered +.Dq safe . +For all variables except +Li TZ , +.Dq safe +means that the variable's value does not contain any the variable's value contains .Ql % or @@ -2151,6 +2157,26 @@ or characters. This can be used to guard against printf-style format vulnerabilities in poorly-written programs. +The +.Li TZ +variable is considerd unsafe if any of the following are true: +.Bl -bullet +.It +It consists of a fully-qualified path name that does not match +the location of the +.Pa zoneinfo +directory. +.It +It contains a +.Pa .. +path element. +.It +It contains white space or non-printable characters. +.It +It is longer than the value of +.Li PATH_MAX . +.El +.Pp The argument may be a double-quoted, space-separated list or a single value without double-quotes. The list can be replaced, added to, deleted from, or disabled by using |