<<< Date Index >>>     <<< Thread Index >>>

[TKADV2007-001] Mac OS X TIOCSETD IOCTL Kernel Memory Corruption Vulnerability



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Advisory:               Mac OS X TIOCSETD IOCTL Kernel 
                        Memory Corruption Vulnerability
Advisory ID:            TKADV2007-001
Revision:               1.0              
Release Date:           2007/11/15 
Last Modified:          2007/11/15 
Date Reported:          2007/03/19
Author:                 Tobias Klein (tk at trapkit.de)
Affected Software:      Mac OS X xnu kernel <= version 
                        8.10.1 (xnu-792.22.5~1)
                        Mac OS X v10.4 through v10.4.10, 
                        Mac OS X Server v10.4 through v10.4.10
Remotely Exploitable:   No
Locally Exploitable:    Yes 
Vendor URL:             http://www.apple.com 
Vendor Status:          Vendor has released an updated version
CVE-ID:                 CVE-2007-4686         
Patch development time: 241 days

                    
======================
Vulnerability details: 
======================

The xnu kernel of Mac OS X contains a vulnerability in the code that 
handles TIOCSETD ioctl requests. Exploitation of this vulnerability 
can result in:

1) local execution of arbitrary code at the kernel level (complete system 
   compromise), or

2) local denial of service attacks (system crash due to a kernel panic)

The issue can be triggered by sending a specially crafted ioctl request.


======================
Technical description:
======================

Kernel source file: bsd/kern/tty.c 
(from http://www.opensource.apple.com/darwinsource/10.4.8.x86/xnu-792.13.8/)

 822 int
 823 ttioctl(register struct tty *tp,
 824         u_long cmd, caddr_t data, int flag,
 825         struct proc *p)
 826 {       

[...]

1085            bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1086            splx(s);
1087            break;
1088    }
1089    case TIOCSETD: {                /* set line discipline */
1090           register int t = *(int *)data;   <--- (1)
1091           dev_t device = tp->t_dev;
1092 
1093           if (t >= nlinesw)   <--- (2)
1094                   return (ENXIO);
1095           if (t != tp->t_line) {
1096                   s = spltty();
1097                   (*linesw[tp->t_line].l_close)(tp, flag);
1098                   error = (*linesw[t].l_open)(device, tp); <--- (3)
1099                   if (error) {
1100                         (void)(*linesw[tp->t_line].l_open)(device, tp);
1101                          splx(s);
1102                          return (error);
1103                   }
1104                   tp->t_line = t;
1105                   splx(s);
1106          }
1107          break;
1108    }

In line 1090 the user supplied "data" of the type caddr_t (char *) gets 
stored in the variable "t" of the type signed int (see (1)). Then in line 
1093 the value of "t" is compared with "nlinesw". As "data" is supplied 
by the user it is possible to provide a string value >= 0x80000000. If so, 
"t" gets a negative value due to the type conversion error (see (1)) and 
the check in line 1093 will always be passed (see (2)). In line 1098 the user 
supplied value "t" is used to reference and call "l_open". This leads to full 
control of the kernel execution flow.

Corresponding assembler code snippet:

__text:00356C08 loc_356C08:    
__text:00356C08    mov     eax, [ebp+arg_8]
__text:00356C0B    mov     ebx, [eax] <--- (1)
__text:00356C0D    mov     edx, [ebp+arg_0]                       
__text:00356C10    mov     edx, [edx+64h]                       
__text:00356C13    mov     [ebp+var_58], edx                         
__text:00356C16    cmp     ebx, ds:457880h <--- (2)
__text:00356C1C    jl      short loc_356C28
__text:00356C1E    mov     esi, 6                       
__text:00356C23    jmp     loc_356F70                                 
__text:00356C28 ; --------------------------------
__text:00356C28
__text:00356C28 loc_356C28:                        
__text:00356C28    mov     ecx, [ebp+arg_0]                         
__text:00356C2B    cmp     ebx, [ecx+60h]                             
__text:00356C2E    jz      loc_356633                                
__text:00356C34    call    _spltty                               
__text:00356C39    mov     edi, eax                       
__text:00356C3B    mov     esi, [ebp+arg_0]                         
__text:00356C3E    mov     eax, [esi+60h]                                 
__text:00356C41    shl     eax, 5                       
__text:00356C44    mov     edx, [ebp+arg_C]                 
__text:00356C47    mov     [esp+0B8h+var_B4], edx                 
__text:00356C4B    mov     [esp+0B8h+var_B8], esi                     
__text:00356C4E    call    ds:off_4578A4[eax]
__text:00356C54    mov     eax, ebx    <--- (3)
__text:00356C56    shl     eax, 5      <--- (4)
__text:00356C59    mov     [esp+0B8h+var_B4], esi
__text:00356C5D    mov     ecx, [ebp+var_58]
__text:00356C60    mov     [esp+0B8h+var_B8], ecx
__text:00356C63    call    ds:_linesw[eax]   <--- (5)

(1) The user supplied data is copied into EBX 
(2) EBX is compared with nlinesw 
(3) The user supplied data in EBX is copied into EAX
(4) Slightly modification of EAX
(5) The user supplied value in EAX is used as a reference in this call


=================
Proof of Concept:
=================

Due to the severity of this issue no proof of concept exploit code 
will be released.


========= 
Solution: 
=========

  Upgrade to Mac OS X (Server) v10.4.11 or apply the Security Update 2007-008.
  
  http://www.apple.com/support/downloads/
  

======== 
History: 
========

  2007/03/19 - Vendor notified
  2007/03/19 - Automated reply from vendor
  2007/03/26 - Vendor asks for more details
  2007/04/01 - Provided vendor with more details
  2007/04/04 - Status update from vendor
  2007/04/06 - Vendor confirms the vulnerability
  2007/05/11 - Status update request
  2007/06/22 - Status update from vendor 
  2007/11/14 - Update released by the vendor 
  2007/11/15 - Full technical details released to general 
               public


======== 
Credits: 
========

  Vulnerability found and advisory written by Tobias Klein.


=========== 
References: 
===========

  [1] http://docs.info.apple.com/article.html?artnum=307041
  [2] http://www.trapkit.de/advisories/TKADV2007-001.txt


======== 
Changes: 
========

  Revision 0.1 - Initial draft release to the vendor
  Revision 1.0 - Public release
  

===========
Disclaimer:
===========

The information within this advisory may change without notice. Use
of this information constitutes acceptance for use in an AS IS
condition. There are no warranties, implied or express, with regard
to this information. In no event shall the author be liable for any
direct or indirect damages whatsoever arising out of or in connection
with the use or spread of this information. Any use of this
information is at the user's own risk.


================== 
PGP Signature Key: 
==================

  http://www.trapkit.de/advisories/tk-advisories-signature-key.asc

  
Copyright 2007 Tobias Klein. All rights reserved.


-----BEGIN PGP SIGNATURE-----
Version: PGP 8.1

iQA/AwUBRzydRZF8YHACG4RBEQJHeQCePEAADwvFB/zfastphFcL+UAZkJ0An28f
TELICn1MGteOiFrhKudTyAtw
=+x0c
-----END PGP SIGNATURE-----