File sudo-1.8.10p3-CVE-2014-9680.patch of Package sudo.14076
Index: sudo-1.8.10p3/plugins/sudoers/env.c
===================================================================
--- sudo-1.8.10p3.orig/plugins/sudoers/env.c
+++ sudo-1.8.10p3/plugins/sudoers/env.c
@@ -197,6 +197,7 @@ static const char *initial_checkenv_tabl
"LC_*",
"LINGUAS",
"TERM",
+ "TZ",
NULL
};
@@ -212,7 +213,6 @@ static const char *initial_keepenv_table
"PATH",
"PS1",
"PS2",
- "TZ",
"XAUTHORITY",
"XAUTHORIZATION",
NULL
@@ -576,6 +576,54 @@ matches_env_delete(const char *var)
}
/*
+ * Sanity-check the TZ environment variable.
+ * On many systems it is possible to set this to a pathname.
+ */
+static bool
+tz_is_sane(const char *tzval)
+{
+ const char *cp;
+ char lastch;
+ debug_decl(tz_is_sane, SUDO_DEBUG_ENV)
+
+ /* 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] != '/')
+ debug_return_bool(false);
+#else
+ /* Assume the worst. */
+ debug_return_bool(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))
+ debug_return_bool(false);
+ if (lastch == '/' && cp[0] == '.' && cp[1] == '.' &&
+ (cp[2] == '/' || cp[2] == '\0'))
+ debug_return_bool(false);
+ lastch = *cp;
+ }
+
+ /* Reject extra long TZ values (even if not a path). */
+ if ((size_t)(cp - tzval) >= PATH_MAX)
+ debug_return_bool(false);
+
+ debug_return_bool(true);
+}
+
+/*
* Apply the env_check list.
* Returns true if the variable is allowed, false if denied
* or -1 if no match.
@@ -599,7 +647,12 @@ matches_env_check(const char *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;
}
}
Index: sudo-1.8.10p3/pathnames.h.in
===================================================================
--- sudo-1.8.10p3.orig/pathnames.h.in
+++ sudo-1.8.10p3/pathnames.h.in
@@ -178,3 +178,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 */