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

[TKADV2009-001] Sun Solaris aio_suspend() Kernel Integer Overflow Vulnerability



Please find attached a detailed advisory of the vulnerability.

Alternatively, the advisory can also be found at:
http://www.trapkit.de/advisories/TKADV2009-001.txt
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Advisory:               Sun Solaris aio_suspend() Kernel Integer 
                        Overflow Vulnerability
Advisory ID:            TKADV2009-001
Revision:               1.0 
Release Date:           2009/01/08 
Last Modified:          2009/01/08
Date Reported:          2008/09/15
Author:                 Tobias Klein (tk at trapkit.de)
Affected Software:      Solaris  8 without patch 117350-59 (SPARC)
                        Solaris  9 without patch 138577-01 (SPARC)
                        Solaris 10 without patch 121394-02 (SPARC)
                        Solaris  8 without patch 117351-59 (x86)
                        Solaris  9 without patch 138578-01 (x86)
                        Solaris 10 without patch 121395-02 (x86)
                        OpenSolaris < build TBC (SPARC and x86)  
Remotely Exploitable:   No
Locally Exploitable:    Yes 
Vendor URL:             http://www.sun.com/ 
Vendor Status:          Vendor has released an updated version
Patch development time: 115 days


======================
Vulnerability Details: 
======================

The kernel of Solaris contains a vulnerability in the code that handles 
SYS_kaio syscall requests on systems in 32 bit mode. Exploitation of this 
vulnerability can result in local denial of service attacks (system crash 
due to a kernel panic). As all Solaris Zones (Containers) share the same 
kernel it is possible to crash the whole system (all Zones) even if the 
vulnerability is triggered in an unprivileged non-global zone.

This kernel vulnerability can be exploited by an unprivileged local user.


==================
Technical Details:
==================

The following source code references are based on the kernel source code 
available from http://www.opensolaris.org.

Source code file: /uts/common/os/aio.c

[..]
221 static int64_t
222 kaioc(
223        long  a0,
224        long  a1,
225        long  a2,
226        long  a3,
227        long  a4,
228        long  a5)
229 {
230        int  error;
231        long rval = 0;
232
233        switch ((int)a0 & ~AIO_POLL_BIT) {
...
266        case AIOSUSPEND:
267 [1]        error = aiosuspend((void *)a1, (int)a2, (timespec_t *)a3,
268                (int)a4, &rval, AIO_64);
269            break;
[..]

[1] The parameters "a1", "a2", "a3" and "a4" of the "aiosuspend()" function
    are user controlled.

Source code file: /uts/common/os/aio.c

[..]
897   static int
898   aiosuspend(
899          void   *aiocb,
900          int    nent,
901          struct timespec   *timout,
902          int    flag,
903          long   *rval,
904          int    run_mode)
905   {
...
925        aiop = curproc->p_aio;
926 [2]    if (aiop == NULL || nent <= 0)
927               return (EINVAL);
...
951        if (model == DATAMODEL_NATIVE)
952 [3]           ssize = (sizeof (aiocb_t *) * nent);
953      #ifdef _SYSCALL32_IMPL
954        else
955 [3]           ssize = (sizeof (caddr32_t) * nent);
956      #endif  /* _SYSCALL32_IMPL */
957 
958 [4]    cbplist = kmem_alloc(ssize, KM_NOSLEEP);
[..]

[2] As "nent" is controlled by the user this check can be passed if 
    "nent" > 0.
[3] The value of "ssize" is calculated using the user controlled value of 
    "nent". By supplying a value of 0x3fffffff for "nent" an integer 
    overflow will happen that results in "ssize" = 0x00000000. The 
    "kmem_alloc()" function is now called with a length value of 
    0x00000000 (see [4]). The "kmem_alloc()" function itself calls 
    "vmem_alloc()" with a "size" value of 0x00000000 which calls 
    "vmem_xalloc()" with the same "size" value.


Source code file: /lib/libumem/common/vmem.c

[..]
815 void *
816 vmem_xalloc(vmem_t *vmp, size_t size, size_t align, size_t phase,
817   size_t nocross, void *minaddr, void *maxaddr, int vmflag)
818 {
...
934 [6]  if (size == 0)
935         umem_panic("vmem_xalloc(): size == 0");
[..]

[6] If a "size" value of 0x00000000 is supplied to the "vmem_xalloc()" 
    function the kernel panics. This leads to a system crash (denial of 
    service).


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

This issue is addressed in the following patch releases from Sun:

SPARC Platform
    - Solaris 8 with patch 117350-59 or later
    - Solaris 9 with patch 138577-01 or later
    - Solaris 10 with patch 121394-02 or later
    - OpenSolaris build TBC

x86 Platform
    - Solaris 8 with patch 117351-59 or later
    - Solaris 9 with patch 138578-01 or later
    - Solaris 10 with patch 121395-02 or later
    - Opensolaris build TBC


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

  2008/09/15 - Vendor notified  
  2008/09/16 - Vendor confirms the vulnerability
  2009/01/08 - Public disclosure of vulnerability details by Sun 
  2009/01/08 - Release date of this security advisory


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

  Vulnerability found and advisory written by Tobias Klein.


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

  [1] http://sunsolve.sun.com/search/document.do?assetkey=1-66-247986-1
  [2] http://www.trapkit.de/advisories/TKADV2009-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 2009 Tobias Klein. All rights reserved.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG

iD8DBQFJaiEKkXxgcAIbhEERAi2vAKCz4kA50uoS0YZAR0XbfS2S2FbruACcCprB
FsiAvTxq5KXE6iNECznlbyA=
=P5+L
-----END PGP SIGNATURE-----