Arbitrary file access via TZ environment variable

Release Date:

February 9, 2015

Summary:

Prior to sudo 1.8.12, the TZ environment variable was passed through unchecked. Most libc tzset() implementations support passing an absolute pathname in the time zone to point to an arbitrary, user-controlled file. This may be used to exploit bugs in the C library's TZ parser or open files the user would not otherwise have access to. Arbitrary file access via TZ could also be used in a denial of service attack by reading from a file or fifo that will block.

Beginning with sudo 1.8.12, TZ is only passed through by default if it is considered safe. The TZ variable is now considered unsafe if any of the following are true:

  • It consists of a fully-qualified path name, optionally prefixed with a colon (:), that does not match the location of the zoneinfo directory.

  • It contains a .. path element.

  • It contains white space or non-printable characters.

  • It is longer than the value of PATH_MAX.

Sudo versions affected:

Sudo versions prior to 1.8.12 are affected.

CVE ID:

This vulnerability has been assigned CVE-2014-9680 in the Common Vulnerabilities and Exposures database.

Details:

Unix systems support a user-specified time zone value stored in the TZ environment variable. On many systems, the value of TZ is ignored for set user ID processes (such as sudo) if it does not pass certain sanity checks. However, while the value may be ignored, it is not actually removed from the environment. As such, a program run via sudo will inherit the (possibly malicious) value of TZ.

A user with sudo access may take advantage of this to exploit bugs in the C library functions which parse the TZ environment variable. The TZ handling in most C libraries (including GNU libc and the tzcode used by BSD and others) supports reading arbitrary files.

By setting TZ to a fully-qualified path name, a command run via sudo may be used to read (but not disclose the contents of) files that the user would not otherwise be able to open. This is generally benign for regular files, but it may be possible to change the behavior of the system by reading from device special files. For instance, it may be possible to hijack the output from a terminal device file, consume kernel log messages or cause a tape drive to change position. It may also be possible to cause a command run by sudo to hang if TZ is set to the value of a named pipe or a device special file that blocks on read.

Impact:

A user with sudo access may be able to exploit parsing bugs in the time zone parsing functions of the system's C library functions. The user may also be able to read arbitrary files, potentially causing changes in system behavior when reading certain device special files or simply causing the program run via sudo to block.

Fix:

The bug is fixed in sudo 1.8.12 and 1.7.10p9.

Credit:

Jakub Wilk began a discussion about abusing the TZ environment variable on the oss-security mailing list.

Stephane Chazelas also reported the problem and supplied some concrete examples of how it could be abused.

See Also:

http://www.openwall.com/lists/oss-security/2014/10/15/24

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=772707