Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 May 2016 09:10:58 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 209545] Heap overflows in an driver
Message-ID:  <bug-209545-8@https.bugs.freebsd.org/bugzilla/>

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

            Bug ID: 209545
           Summary: Heap overflows in an driver
           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

The `an` driver doesn't perform bound checks on the lengths used by the
`AIROFLSHGCHR` and `AIROFLSHPCHR` commands implemented through
`SIOCGPRIVATE_0`, which leads to heap overflows from the `copyin` calls,
accessible by a privileged user only.

sys/dev/an/if_an.c:

static int
an_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
        ...

        switch (command) {
        ...
        case SIOCGPRIVATE_0:            /* used by Cisco client utility */
                if ((error =3D priv_check(td, PRIV_DRIVER)))
                        goto out;
                error =3D copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl));
                if (error)
                        goto out;
                mode =3D l_ioctl.command;

                AN_LOCK(sc);
                if (mode >=3D AIROGCAP && mode <=3D AIROGSTATSD32) {
                        error =3D readrids(ifp, &l_ioctl);
                } else if (mode >=3D AIROPCAP && mode <=3D AIROPLEAPUSR) {
                        error =3D writerids(ifp, &l_ioctl);
                } else if (mode >=3D AIROFLSHRST && mode <=3D AIRORESTART) {
                        error =3D flashcard(ifp, &l_ioctl);
                } else {
                        error =3D-1;
                }
                AN_UNLOCK(sc);
                if (!error) {
                        /* copy out the updated command info */
                        error =3D copyout(&l_ioctl, ifr->ifr_data,
sizeof(l_ioctl));
                }
                break;
        ...
out:

        return(error !=3D 0);
}=20=20=20=20=20=20=20

static int
flashcard(struct ifnet *ifp, struct aironet_ioctl *l_ioctl)
{
        int             z =3D 0, status;
        struct an_softc *sc;

        sc =3D ifp->if_softc;
        if (sc->mpi350) {
                if_printf(ifp, "flashing not supported on MPI 350 yet\n");
                return(-1);
        }
        status =3D l_ioctl->command;

        switch (l_ioctl->command) {
        ...
        case AIROFLSHGCHR:      /* Get char from aux */
                AN_UNLOCK(sc);
                status =3D copyin(l_ioctl->data, &sc->areq, l_ioctl->len);
                AN_LOCK(sc);
                if (status)
                        return status;
                z =3D *(int *)&sc->areq;
                if ((status =3D flashgchar(ifp, z, 8000)) =3D=3D 1)
                        return 0;
                else
                        return -1;
        case AIROFLSHPCHR:      /* Send char to card. */
                AN_UNLOCK(sc);
                status =3D copyin(l_ioctl->data, &sc->areq, l_ioctl->len);
                AN_LOCK(sc);
                if (status)
                        return status;
                z =3D *(int *)&sc->areq;
                if ((status =3D flashpchar(ifp, z, 8000)) =3D=3D -1)
                        return -EIO;
                else
                        return 0;
                break;
        ...

        return -EINVAL;
}

I propose that the following bound checks are added to this command:

        case AIROFLSHGCHR:      /* Get char from aux */
+               if (l_ioctl->len > sizeof(sc->areq)) {
+                       return -EINVAL;
+               }
...
        case AIROFLSHPCHR:      /* Send char to card. */
+               if (l_ioctl->len > sizeof(sc->areq)) {
+                       return -EINVAL;
+               }

--=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-209545-8>