Blame SOURCES/sudo-1.8.6p7-CVE-2014-9680.patch

72fdaf
diff -up sudo-1.8.6p7/aclocal.m4.CVE-2014-9680 sudo-1.8.6p7/aclocal.m4
72fdaf
--- sudo-1.8.6p7/aclocal.m4.CVE-2014-9680	2013-02-25 20:42:44.000000000 +0100
72fdaf
+++ sudo-1.8.6p7/aclocal.m4	2015-07-05 13:44:11.610596042 +0200
72fdaf
@@ -156,6 +156,25 @@ AC_DEFUN([SUDO_IO_LOGDIR], [
72fdaf
     AC_MSG_RESULT($iolog_dir)
72fdaf
 ])dnl
72fdaf
 
72fdaf
+dnl Detect time zone file directory, if any.
72fdaf
+dnl
72fdaf
+AC_DEFUN([SUDO_TZDIR], [AC_MSG_CHECKING(time zone data directory)
72fdaf
+tzdir="$with_tzdir"
72fdaf
+if test -z "$tzdir"; then
72fdaf
+    tzdir=no
72fdaf
+    for d in /usr/share /usr/share/lib /usr/lib /etc; do
72fdaf
+	if test -d "$d/zoneinfo"; then
72fdaf
+	    tzdir="$d/zoneinfo"
72fdaf
+	    break
72fdaf
+	fi
72fdaf
+    done
72fdaf
+fi
72fdaf
+AC_MSG_RESULT([$tzdir])
72fdaf
+if test "${tzdir}" != "no"; then
72fdaf
+    SUDO_DEFINE_UNQUOTED(_PATH_ZONEINFO, "$tzdir")
72fdaf
+fi
72fdaf
+])dnl
72fdaf
+
72fdaf
 dnl
72fdaf
 dnl check for working fnmatch(3)
72fdaf
 dnl
72fdaf
diff -up sudo-1.8.6p7/configure.in.CVE-2014-9680 sudo-1.8.6p7/configure.in
72fdaf
--- sudo-1.8.6p7/configure.in.CVE-2014-9680	2015-07-05 13:44:11.598596222 +0200
72fdaf
+++ sudo-1.8.6p7/configure.in	2015-07-05 13:44:11.610596042 +0200
72fdaf
@@ -776,6 +776,12 @@ AC_ARG_WITH(iologdir, [AS_HELP_STRING([-
72fdaf
 	    ;;
72fdaf
 esac])
72fdaf
 
72fdaf
+AC_ARG_WITH(tzdir, [AS_HELP_STRING([--with-tzdir=DIR], [path to the time zone data directory])],
72fdaf
+[case $with_tzdir in
72fdaf
+    yes)	AC_MSG_ERROR(["must give --with-tzdir an argument."])
72fdaf
+		;;
72fdaf
+esac])
72fdaf
+
72fdaf
 AC_ARG_WITH(sendmail, [AS_HELP_STRING([--with-sendmail], [set path to sendmail])
72fdaf
 AS_HELP_STRING([--without-sendmail], [do not send mail at all])],
72fdaf
 [case $with_sendmail in
72fdaf
@@ -3250,6 +3256,7 @@ fi
72fdaf
 SUDO_LOGFILE
72fdaf
 SUDO_TIMEDIR
72fdaf
 SUDO_IO_LOGDIR
72fdaf
+SUDO_TZDIR
72fdaf
 
72fdaf
 dnl
72fdaf
 dnl Turn warnings into errors.
72fdaf
diff -up sudo-1.8.6p7/doc/sudoers.cat.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.cat
72fdaf
--- sudo-1.8.6p7/doc/sudoers.cat.CVE-2014-9680	2015-07-05 13:44:11.586596402 +0200
72fdaf
+++ sudo-1.8.6p7/doc/sudoers.cat	2015-07-05 13:44:11.610596042 +0200
72fdaf
@@ -1421,20 +1421,36 @@ S?SU?UD?DO?OE?ER?RS?S O?OP?PT?TI?IO?ON?N
72fdaf
 
72fdaf
      L?Li?is?st?ts?s t?th?ha?at?t c?ca?an?n b?be?e u?us?se?ed?d i?in?n a?a b?bo?oo?ol?le?ea?an?n c?co?on?nt?te?ex?xt?t:
72fdaf
 
72fdaf
-     env_check         Environment variables to be removed from the user's
72fdaf
-                       environment if the variable's value contains `%' or `/'
72fdaf
+      env_check        Environment variables to be removed from the user's
72fdaf
+                       environment if unless they are considered ``safe''.
72fdaf
+                       For all variables except TZ, ``safe'' means that the
72fdaf
+                       variable's value does not contain any `%' or `/'
72fdaf
                        characters.  This can be used to guard against printf-
72fdaf
                        style format vulnerabilities in poorly-written
72fdaf
-                       programs.  The argument may be a double-quoted, space-
72fdaf
-                       separated list or a single value without double-quotes.
72fdaf
-                       The list can be replaced, added to, deleted from, or
72fdaf
-                       disabled by using the =, +=, -=, and ! operators
72fdaf
-                       respectively.  Regardless of whether the env_reset
72fdaf
-                       option is enabled or disabled, variables specified by
72fdaf
-                       env_check will be preserved in the environment if they
72fdaf
-                       pass the aforementioned check.  The default list of
72fdaf
-                       environment variables to check is displayed when s?su?ud?do?o
72fdaf
-                       is run by root with the -?-V?V option.
72fdaf
+                       programs.  The TZ variable is considerd unsafe if any
72fdaf
+                       of the following are true:
72fdaf
+
72fdaf
+                       +?+?o?o   It consists of a fully-qualified path name,
72fdaf
+                           optionally prefixed with a colon (`:'), that does
72fdaf
+                           not match the location of the _?z_?o_?n_?e_?i_?n_?f_?o directory.
72fdaf
+
72fdaf
+                       +?+?o?o   It contains a _?._?. path element.
72fdaf
+
72fdaf
+                       +?+?o?o   It contains white space or non-printable
72fdaf
+                           characters.
72fdaf
+
72fdaf
+                       +?+?o?o   It is longer than the value of PATH_MAX.
72fdaf
+
72fdaf
+                       The argument may be a double-quoted, space-separated
72fdaf
+                       list or a single value without double-quotes.  The list
72fdaf
+                       can be replaced, added to, deleted from, or disabled by
72fdaf
+                       using the =, +=, -=, and ! operators respectively.
72fdaf
+                       Regardless of whether the env_reset option is enabled
72fdaf
+                       or disabled, variables specified by env_check will be
72fdaf
+                       preserved in the environment if they pass the
72fdaf
+                       aforementioned check.  The default list of environment
72fdaf
+                       variables to check is displayed when s?su?ud?do?o is run by
72fdaf
+                       root with the -?-V?V option.
72fdaf
 
72fdaf
      env_delete        Environment variables to be removed from the user's
72fdaf
                        environment when the _?e_?n_?v_?__?r_?e_?s_?e_?t option is not in effect.
72fdaf
diff -up sudo-1.8.6p7/doc/sudoers.man.in.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.man.in
72fdaf
--- sudo-1.8.6p7/doc/sudoers.man.in.CVE-2014-9680	2015-07-05 13:44:11.586596402 +0200
72fdaf
+++ sudo-1.8.6p7/doc/sudoers.man.in	2015-07-05 13:44:11.611596027 +0200
72fdaf
@@ -3002,14 +3002,47 @@ The default value is
72fdaf
 \fBLists that can be used in a boolean context\fR:
72fdaf
 .TP 18n
72fdaf
 env_check
72fdaf
-Environment variables to be removed from the user's environment if
72fdaf
-the variable's value contains
72fdaf
-`%'
72fdaf
+ Environment variables to be removed from the user's environment if
72fdaf
+unless they are considered
72fdaf
+\(lqsafe\(rq.
72fdaf
+For all variables except
72fdaf
+\fRTZ\fR,
72fdaf
+\(lqsafe\(rq
72fdaf
+means that the variable's value does not contain any
72fdaf
+\(oq%\(cq
72fdaf
 or
72fdaf
-`/'
72fdaf
+\(oq/\(cq
72fdaf
 characters.
72fdaf
 This can be used to guard against printf-style format vulnerabilities
72fdaf
 in poorly-written programs.
72fdaf
+The
72fdaf
+\fRTZ\fR
72fdaf
+variable is considerd unsafe if any of the following are true:
72fdaf
+.PP
72fdaf
+.RS 18n
72fdaf
+.PD 0
72fdaf
+.TP 4n
72fdaf
+\fB\(bu\fR
72fdaf
+It consists of a fully-qualified path name,
72fdaf
+optionally prefixed with a colon
72fdaf
+(\(oq:\&\(cq),
72fdaf
+that does not match the location of the
72fdaf
+\fIzoneinfo\fR
72fdaf
+directory.
72fdaf
+.PD
72fdaf
+.TP 4n
72fdaf
+\fB\(bu\fR
72fdaf
+It contains a
72fdaf
+\fI..\fR
72fdaf
+path element.
72fdaf
+.TP 4n
72fdaf
+\fB\(bu\fR
72fdaf
+It contains white space or non-printable characters.
72fdaf
+.TP 4n
72fdaf
+\fB\(bu\fR
72fdaf
+It is longer than the value of
72fdaf
+\fRPATH_MAX\fR.
72fdaf
+.PP
72fdaf
 The argument may be a double-quoted, space-separated list or a
72fdaf
 single value without double-quotes.
72fdaf
 The list can be replaced, added to, deleted from, or disabled by using
72fdaf
@@ -3031,6 +3064,7 @@ is run by root with
72fdaf
 the
72fdaf
 \fB\-V\fR
72fdaf
 option.
72fdaf
+.RE
72fdaf
 .TP 18n
72fdaf
 env_delete
72fdaf
 Environment variables to be removed from the user's environment when the
72fdaf
diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.mdoc.in
72fdaf
--- sudo-1.8.6p7/doc/sudoers.mdoc.in.CVE-2014-9680	2015-07-05 13:44:11.586596402 +0200
72fdaf
+++ sudo-1.8.6p7/doc/sudoers.mdoc.in	2015-07-05 13:44:11.611596027 +0200
72fdaf
@@ -2791,13 +2791,40 @@ The default value is
72fdaf
 .Bl -tag -width 16n
72fdaf
 .It env_check
72fdaf
 Environment variables to be removed from the user's environment if
72fdaf
-the variable's value contains
72fdaf
+unless they are considered
72fdaf
+.Dq safe .
72fdaf
+For all variables except
72fdaf
+.Li TZ ,
72fdaf
+.Dq safe
72fdaf
+means that the variable's value does not contain any
72fdaf
 .Ql %
72fdaf
 or
72fdaf
 .Ql /
72fdaf
 characters.
72fdaf
 This can be used to guard against printf-style format vulnerabilities
72fdaf
 in poorly-written programs.
72fdaf
+The
72fdaf
+.Li TZ 
72fdaf
+variable is considerd unsafe if any of the following are true:
72fdaf
+.Bl -bullet
72fdaf
+.It
72fdaf
+It consists of a fully-qualified path name,
72fdaf
+optionally prefixed with a colon
72fdaf
+.Pq Ql :\& ,
72fdaf
+that does not match the location of the
72fdaf
+.Pa zoneinfo
72fdaf
+directory.
72fdaf
+.It
72fdaf
+It contains a
72fdaf
+.Pa ..
72fdaf
+path element.
72fdaf
+.It
72fdaf
+It contains white space or non-printable characters.
72fdaf
+.It
72fdaf
+It is longer than the value of
72fdaf
+.Li PATH_MAX .
72fdaf
+.El
72fdaf
+.Pp
72fdaf
 The argument may be a double-quoted, space-separated list or a
72fdaf
 single value without double-quotes.
72fdaf
 The list can be replaced, added to, deleted from, or disabled by using
72fdaf
diff -up sudo-1.8.6p7/INSTALL.CVE-2014-9680 sudo-1.8.6p7/INSTALL
72fdaf
--- sudo-1.8.6p7/INSTALL.CVE-2014-9680	2013-02-25 20:42:43.000000000 +0100
72fdaf
+++ sudo-1.8.6p7/INSTALL	2015-07-05 13:44:11.611596027 +0200
72fdaf
@@ -461,6 +461,16 @@ The following options are also configura
72fdaf
 	Override the default location of the sudo timestamp directory and
72fdaf
 	use "path" instead.
72fdaf
 
72fdaf
+  --with-tzdir=DIR
72fdaf
+        Set the directory to the system's time zone data files.  This 
72fdaf
+	is only used when sanitizing the TZ environment variable to
72fdaf
+	allow for fully-qualified paths in TZ.
72fdaf
+        By default, configure will look for an existing "zoneinfo"
72fdaf
+	directory in the following locations:
72fdaf
+	    /usr/share /usr/share/lib /usr/lib /etc
72fdaf
+	If no zoneinfo directory is found, the TZ variable may not
72fdaf
+	contain a fully-qualified path.
72fdaf
+
72fdaf
   --with-sendmail=PATH
72fdaf
 	Override configure's guess as to the location of sendmail.
72fdaf
 
72fdaf
diff -up sudo-1.8.6p7/pathnames.h.in.CVE-2014-9680 sudo-1.8.6p7/pathnames.h.in
72fdaf
--- sudo-1.8.6p7/pathnames.h.in.CVE-2014-9680	2012-09-18 15:56:28.000000000 +0200
72fdaf
+++ sudo-1.8.6p7/pathnames.h.in	2015-07-05 13:44:11.612596011 +0200
72fdaf
@@ -168,3 +168,7 @@
72fdaf
 #ifndef _PATH_NETSVC_CONF
72fdaf
 #undef	_PATH_NETSVC_CONF
72fdaf
 #endif /* _PATH_NETSVC_CONF */
72fdaf
+
72fdaf
+#ifndef _PATH_ZONEINFO
72fdaf
+# undef	_PATH_ZONEINFO
72fdaf
+#endif /* _PATH_ZONEINFO */
72fdaf
diff -up sudo-1.8.6p7/plugins/sudoers/env.c.CVE-2014-9680 sudo-1.8.6p7/plugins/sudoers/env.c
72fdaf
--- sudo-1.8.6p7/plugins/sudoers/env.c.CVE-2014-9680	2013-02-25 20:42:44.000000000 +0100
72fdaf
+++ sudo-1.8.6p7/plugins/sudoers/env.c	2015-07-05 13:44:11.612596011 +0200
72fdaf
@@ -198,6 +198,7 @@ static const char *initial_checkenv_tabl
72fdaf
     "LC_*",
72fdaf
     "LINGUAS",
72fdaf
     "TERM",
72fdaf
+    "TZ",
72fdaf
     NULL
72fdaf
 };
72fdaf
 
72fdaf
@@ -213,7 +214,6 @@ static const char *initial_keepenv_table
72fdaf
     "PATH",
72fdaf
     "PS1",
72fdaf
     "PS2",
72fdaf
-    "TZ",
72fdaf
     "XAUTHORITY",
72fdaf
     "XAUTHORIZATION",
72fdaf
     NULL
72fdaf
@@ -584,6 +584,54 @@ matches_env_delete(const char *var)
72fdaf
 }
72fdaf
 
72fdaf
 /*
72fdaf
+ * Sanity-check the TZ environment variable.
72fdaf
+ * On many systems it is possible to set this to a pathname.
72fdaf
+ */
72fdaf
+static bool
72fdaf
+tz_is_sane(const char *tzval)
72fdaf
+{
72fdaf
+    const char *cp;
72fdaf
+    char lastch;
72fdaf
+    debug_decl(tz_is_sane, SUDO_DEBUG_ENV)
72fdaf
+
72fdaf
+    /* tzcode treats a value beginning with a ':' as a path. */
72fdaf
+    if (tzval[0] == ':')
72fdaf
+	tzval++;
72fdaf
+
72fdaf
+    /* Reject fully-qualified TZ that doesn't being with the zoneinfo dir. */
72fdaf
+    if (tzval[0] == '/') {
72fdaf
+#ifdef _PATH_ZONEINFO
72fdaf
+	if (strncmp(tzval, _PATH_ZONEINFO, sizeof(_PATH_ZONEINFO) - 1) != 0 ||
72fdaf
+	    tzval[sizeof(_PATH_ZONEINFO) - 1] != '/')
72fdaf
+	    debug_return_bool(false);
72fdaf
+#else
72fdaf
+	/* Assume the worst. */
72fdaf
+	debug_return_bool(false);
72fdaf
+#endif
72fdaf
+    }
72fdaf
+
72fdaf
+    /*
72fdaf
+     * Make sure TZ only contains printable non-space characters
72fdaf
+     * and does not contain a '..' path element.
72fdaf
+     */
72fdaf
+    lastch = '/';
72fdaf
+    for (cp = tzval; *cp != '\0'; cp++) {
72fdaf
+	if (isspace((unsigned char)*cp) || !isprint((unsigned char)*cp))
72fdaf
+	    debug_return_bool(false);
72fdaf
+	if (lastch == '/' && cp[0] == '.' && cp[1] == '.' &&
72fdaf
+	    (cp[2] == '/' || cp[2] == '\0'))
72fdaf
+	    debug_return_bool(false);
72fdaf
+	lastch = *cp;
72fdaf
+    }
72fdaf
+
72fdaf
+    /* Reject extra long TZ values (even if not a path). */
72fdaf
+    if ((size_t)(cp - tzval) >= PATH_MAX)
72fdaf
+	debug_return_bool(false);
72fdaf
+
72fdaf
+    debug_return_bool(true);
72fdaf
+}
72fdaf
+
72fdaf
+/*
72fdaf
  * Apply the env_check list.
72fdaf
  * Returns true if the variable is allowed, false if denied
72fdaf
  * or -1 if no match.
72fdaf
@@ -607,8 +655,13 @@ matches_env_check(const char *var)
72fdaf
 	    iswild = false;
72fdaf
 	if (strncmp(cur->value, var, len) == 0 &&
72fdaf
 	    (iswild || var[len] == '=')) {
72fdaf
+	  if (strncmp(var, "TZ=", 3) == 0 ) {
72fdaf
+	    /* Sperial case for TZ */
72fdaf
+	    keepit = tz_is_sane(var + 3);
72fdaf
+	  } else {
72fdaf
 	    keepit = !strpbrk(var, "/%");
72fdaf
-	    break;
72fdaf
+	  }
72fdaf
+	  break;
72fdaf
 	}
72fdaf
     }
72fdaf
     debug_return_bool(keepit);