Mac OS X Libc Buffer Overflow

CVE-2015-7038

Posted by Brian on March 6, 2017

In early 2013 I was developing a small utility to walk an Xsan volume and dump all the folder permissions to a text file for analysis and later restoration. While testing against a large Xsan volume I noticed that permissions for certain folders were not listed as expected.

The problem occurred when calling the acl_to_text() function with an ACL that had a large number of entries. This function is part of the Libc package, for which Apple makes the Mac OS X source available through their Apple Open Source website.

To dig deeper into the issue, I examined the acl_to_text() function as defined in the posix1e/acl_translate.c file for Mac OS X 10.8.3, which was the current OS version at the time.

The function allocates a buffer of 1024 bytes in size and then proceeds to write data to the buffer by means of the raosnprintf() function, which reallocates the data buffer with one of a larger size as needed.

The last few lines of code in the function add a line feed and terminating zero but raosnprintf() is not used to write the data:

buf[(*len_p)++] = '\n';
buf[(*len_p)] = 0;

This opens the door for data to be written outside of the buffer when it is full, thus causing the problems I originally discovered while developing my utility.

Reporting The Issue

On March 18, 2013 I reported my findings to Apple through Bug Reporter as Problem ID 13444026. Here are the steps I provided for reproducing the problem:

1) In Terminal, create a test file and configure ACL as administrator:

sudo -s
touch /tmp/acl_test_file
chmod -N /tmp/acl_test_file
chmod +a# 0 "user:_spotlight allow read,write,append,readattr,readextattr,writeextattr,readsecurity" /tmp/acl_test_file
chmod +a# 0 "user:_spotlight allow read,write,append,readattr,readextattr,writeextattr,readsecurity" /tmp/acl_test_file
chmod +a# 0 "user:_spotlight allow read,write,append,readattr,readextattr,writeextattr,readsecurity" /tmp/acl_test_file
chmod +a# 0 "user:_spotlight allow read,write,append,readattr,readextattr,writeextattr,readsecurity" /tmp/acl_test_file
chmod +a# 0 "user:_spotlight allow read,write,append,readattr,readextattr,writeextattr,readsecurity" /tmp/acl_test_file
chmod +a# 0 "user:_spotlight allow read,write,append,readattr,readextattr,writeextattr,readsecurity" /tmp/acl_test_file
chmod +a# 0 "user:_spotlight allow read,write,append,readattr,readextattr,writeextattr,readsecurity" /tmp/acl_test_file
chmod +a# 0 "user:_spotlight allow read,write,append,readattr,readextattr,writeextattr,readsecurity" /tmp/acl_test_file
exit

The ACL applied to the test file is designed to cause the acl_to_text() function fill the 1024-byte buffer and trigger the buffer overflow.

2) In Terminal, compile and run test program (Xcode and command-line tools required):

cd /tmp/
cat << EOF > dumpacls.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/acl.h>

int main(int argc, const char * argv[])
{
    int i = 1;
    while (i < argc) {
        printf("%s\n",argv[i]);
        acl_t acl = acl_get_file(argv[i], ACL_TYPE_EXTENDED);
        if (acl) {
            char *text = acl_to_text(acl, NULL);
            if (text) {
                printf("%s",text);
                acl_free(text);
            }
            acl_free(acl);
        }
        i++;
    }
    return 0;
}
EOF
clang -o dumpacls dumpacls.c
DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib ./dumpacls /tmp/acl_test_file

The expected results of the test program was the text representation of ACL that was applied to the file, but the actual result was a Segmentation fault: 11 error thanks to the buffer overflow and and the libgmalloc debugging library.

A look through historical versions of the posix1e/acl_translate.c file on the Apple Open Source website revealed that the bug originated with the 10.4 version of the file when the acl_to_text() function was added. So this bug has been around since Mac OS X 10.4 was released on April 29, 2005.

Issue Resolved

On December 9, 2015 Apple release Mac OS X 10.11.2, which replaced the two lines of code with a single line that uses the raosnprintf() function, as can be seen in the updated source in the posix1e/acl_translate.c file:

if(!raosnprintf(&buf, &bufsize, len_p, "\n")) goto err_nomem;

The test program I provided in the bug report now properly displays the text representation of ACL that was applied to the file and no longer crashes because of a buffer overflow.

Apple recently updated the documentation for the OS X El Capitan 10.11.2 update to show that this issue was addressed and assigned CVE-2015-7038. They also credited myself and Narayan Subramanian for reporting the vulnerability.

Text of notification

The issue was also addressed with security updates iOS 9.2, tvOS 9.1, and watchOS 2.1.

While it did take some time for Apple to fix the bug, the experience emphasized to me the need to always report bugs that are found and not to be afraid to dig in and find what is the root cause of the problem. You just might discover a security vulnerability and reporting it will help to further secure the computer systems we use every day. 😊