[Zero Day] Memory Leak and Buffer Overflow Vulnerability in GNU C Library Dynamic Loader

Qualys Vulnerability and Malware Research Labs has uncovered vulnerabilities in the Linux operating system specifically in glibc’s ld.so shared object. CVE-2017-1000408 is a Memory Leak vulnerability and CVE-2017-1000409 is a Buffer overflow vulnerability which is not exploitable if /proc/sys/fs/protected_hardlinks is enabled on the machine. The targets are  not vulnerable to either of these vulnerabilities if it is patched for stack-clash vulnerability CVE-2017-1000366. Due these limitations, the impact of the these vulnerabilities is low. Upon successful exploitation an attacker can achieve root privileges from an unauthorized account.

Vulnerability Details
Memory Leak – CVE-2017-1000408
The function _dl_init_paths() in ld.so uses malloc() to allocate space for an array of pointers to struct object of type r_search_path_elem. To calculate the size it uses the statement sizeof(system_dirs)/sizeof(system_dirs[0]). Here the code assumes that the system_dirs is an array of strings but it is an array of characters, where each directory path is separated by ‘\0’. For eg. If system_dirs contains the string /lib/\0/usr/lib/\0/usr/sbin

rtld_search_dirs.dirs[0] = (struct r_search_path_elem *)
 malloc ((sizeof (system_dirs) / sizeof (system_dirs[0]))
 * round_size * sizeof (struct r_search_path_elem));

the size calculation above translates to malloc ((sizeof (system_dirs)=27 / sizeof (system_dirs[0])=1) so instead of 3 it allocates 27, because the sizeof(system_dirs[0]) always evaluates to 1 as system_dirs[0] is a character whose size is 1 byte. So the code snippet always over allocates the space. This additional memory is never accessed or freed.

Buffer Overflow – CVE-2017-1000409
_dl_init_paths() allocates space for env_path_list.dirs which is an array of pointers to struct objects of type r_search_path_elem. The size of the array is determined by variable nllp which is calculated using llp which is string of colon-separated directories. Once the nllp is determined, malloc() is called to allocate array of length nllp + 1. fillin_rpath() is called to populate the array.

if (llp != NULL && *llp != '\0')
 {
 size_t nllp;
 const char *cp = llp;
 char *llp_tmp;

nllp = 1;
 while (*cp)
 {
 if (*cp == ':' || *cp == ';')
 ++nllp;
 ++cp;
 }

env_path_list.dirs = (struct r_search_path_elem **)
 malloc ((nllp + 1) * sizeof (struct r_search_path_elem *));
.
.
.
(void) fillin_rpath (llp_tmp, env_path_list.dirs, ":;",
 __libc_enable_secure, "LD_LIBRARY_PATH",
 NULL, l);

The issue occurs when fillin_rpath() uses llp_tmp to fill the array, if llp_tmp contains more colon-separated values than llp then the env_path_list.dirs is overflowed beyond the required nllp + 1 entries therefore causing buffer overflow. Rpath token expansion accepts certain token strings one of which is $ORIGIN, it can inject extra colons into llp_tmp. To exploit this vulnerability the attacker must be able to hard-link a SUID binary into a directory whose pathname contains colons. Please refer the Qualys Security Advisory for more detailed information on exploiting CVE-2017-1000409.

As mentioned in the earlier sections to exploit either of these vulnerabilities the target must not be patched for CVE-2017-1000366.

Mitigation
We request our clients to scan their network with QID 370680 to detect vulnerable machines and apply the latest patches as released by the respective vendors.

Please continue to follow Qualys Threat Protection for more coverage on this issue.

References
Memory Leak (CVE-2017-1000408) and Buffer Overflow (CVE-2017-1000409) in GNU C Library Dynamic Loader (ld.so)
Stack-Clash Vulnerability

2 thoughts on “[Zero Day] Memory Leak and Buffer Overflow Vulnerability in GNU C Library Dynamic Loader”

Leave a Reply

Your email address will not be published. Required fields are marked *