Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jan 2016 15:45:10 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 206680] kbd race attacks
Message-ID:  <bug-206680-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D206680

            Bug ID: 206680
           Summary: kbd race attacks
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: cturt@hardenedbsd.org

Whilst analysing my previous bug about the missing `splx` call in one of the
code paths for `genkbd_commonioctl`
(https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D206678), I decided to =
look
at the declaration for the macro itself, in `sys/sys/systm.h`:

/* Stubs for obsolete functions that used to be for interrupt management */
static __inline intrmask_t      splbio(void)            { return 0; }
static __inline intrmask_t      splcam(void)            { return 0; }
static __inline intrmask_t      splclock(void)          { return 0; }
static __inline intrmask_t      splhigh(void)           { return 0; }
static __inline intrmask_t      splimp(void)            { return 0; }
static __inline intrmask_t      splnet(void)            { return 0; }
static __inline intrmask_t      spltty(void)            { return 0; }
static __inline void            splx(intrmask_t ipl __unused)   { return; }

Since these functions have been removed, but kbd has not been updated to
account for this, it means that none of the kbd code is thread safe.

For example, `kbd_realloc_array` contains a lovely, possible race attack:

        s =3D spltty();
        newsize =3D ((keyboards + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA;
        new_kbd =3D malloc(sizeof(*new_kbd)*newsize, M_DEVBUF, M_NOWAIT|M_Z=
ERO);
        if (new_kbd =3D=3D NULL) {
                splx(s);
                return (ENOMEM);
        }
        new_kbdsw =3D malloc(sizeof(*new_kbdsw)*newsize, M_DEVBUF,
                            M_NOWAIT|M_ZERO);
        if (new_kbdsw =3D=3D NULL) {
                free(new_kbd, M_DEVBUF);
                splx(s);
                return (ENOMEM);
        }
        bcopy(keyboard, new_kbd, sizeof(*keyboard)*keyboards);
        bcopy(kbdsw, new_kbdsw, sizeof(*kbdsw)*keyboards);
        if (keyboards > 1) {
                free(keyboard, M_DEVBUF);
                free(kbdsw, M_DEVBUF);
        }
        keyboard =3D new_kbd;
        kbdsw =3D new_kbdsw;
        keyboards =3D newsize;
        splx(s);

This code would have been safe because of the `spltty`, and `splx` locks, b=
ut
since these functions no longer do anything, we have a very brief window wh=
ere
the buffers have been freed, but have not been set to the new allocations. =
If
the thread were to be preempted at this point, and another thread attempted=
 to
use the buffers, a use after free would occur.

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-206680-8>