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

[PINE-CERT-20040201] reference count overflow in shmat()



-------------------------------------------------------------------------------
Pine Digital Security Advisory
-------------------------------------------------------------------------------
Advisory ID       : PINE-CERT-20040201 (CAN-2004-0114)
Authors           : Joost Pol
Vendor Informed   : 2004-02-01
Issue date        : 2004-02-05
Application       : kernel / sysv shared memory
Platforms         : FreeBSD, NetBSD and OpenBSD
Availability      : http://www.pine.nl/press/pine-cert-20040201.txt
-------------------------------------------------------------------------------

Synopsis

        While gathering material for a security training Pine
        Digital Security encountered a reference count overflow
        condition which could lead to privilege escalation.

Versions

        Vulnerable versions include:

        FreeBSD >= 2.2.0, NetBSD >= 1.3 and OpenBSD >= 2.6

Impact

        Serious.

        Local users can elevate their privileges.

Description

        The shmat(2) function maps a shared memory segment, previously
        created with the shmget(2) function, into the address space of
        the calling process.

        This function is implemented in the sysv_shm.c file:

        -- sysv_shm.c lines 317-322 --


                vm_object_reference(shm_handle->shm_object);

                rv = vm_map_find(&p->p_vmspace->vm_map,
                                 shm_handle->shm_object,
                                 0, &attach_va, size,
                                 (flags & MAP_FIXED) ? 0 : 1,
                                 prot, prot, 0);

                if (rv != KERN_SUCCESS) return ENOMEM;

        -- end of code snippet --

        The shmat(2) function first increases the reference count on
        the underlying vm_object and then attempts to insert the
        vm_object into the process address space.

        The vulnerability occurs because the shmat(2) function forgets
        to decrease the reference count when the vm_map_find function
        returns failure.

        Since the caller of shmat(2) can specify the address at which
        the segment should be mapped it is possible to have vm_map_find
        return failure and thus end up with stale references.

Exploitability

        This vulnerability can exploited (reliably) by local users:

        One would first create a shared memory segment using the shmget(2)
        function and create two seperate mappings at different locations
        in the process address space using the shmat(2) function.

        After making around 2^32-2 (invalid) calls to the shmat(2)
        function the reference count of the underlying vm_object
        will wraparound to 1.

        After deleting one of our mappings using the shmdt(2) function
        the underlying vm_object will be freed and we will still have
        one (extranous) mapping hanging around.

        One would then invoke some magic trickery and execute a suid
        binary which will reuse the freed vm_object for its stack
        segment.

        At this point one could write directly into the stack segment
        of the suid binary (using the extranous mapping) and thus
        escalate ones privileges easily.

Disclaimer

        Pine Digital Security does not release exploits.

Patches

        The various CVS repositories should be updated.

References

        FreeBSD-SA-04:02.shmat.asc

        http://www.pine.nl/press/pine-cert-20040201.txt

        http://cve.mitre.org/cgi-bin/cvename.cgi?name=can-2004-0114

        file://usr/src/sys/kern/sysv_shm.c
        file://usr/src/sys/vm/vm_object.c
        file://usr/src/sys/vm/vm_map.c