[Bug 209661] amd64_set_ioperm overflow

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Fri May 20 13:44:56 UTC 2016


            Bug ID: 209661
           Summary: amd64_set_ioperm overflow
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs at FreeBSD.org
          Reporter: cturt at hardenedbsd.org
                CC: freebsd-amd64 at FreeBSD.org
                CC: freebsd-amd64 at FreeBSD.org

The privileged `sysarch` handler, `amd64_set_ioperm`, performs an incorrect
bound check on user arguments supplied to it.

The `uap->start + uap->length > ...` check can be bypassed if the two user
controlled values overflow when added together.

For example, `uap->start = 0xffffffff` and `uap->len = 1` will overflow to 0
when added together, which will bypass the check.

Later on, there is a signed array index with a loop starting from `uap->start`.
If `uap->start` is negative, this would index `iomap` negatively.


amd64_set_ioperm(td, uap)
        struct thread *td;
        struct i386_ioperm_args *uap;
        int i, error;
        char *iomap;
        struct amd64tss *tssp;
        struct system_segment_descriptor *tss_sd;
        struct pcb *pcb;

        if ((error = priv_check(td, PRIV_IO)) != 0)
                return (error);
        if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
                return (error);
        if (uap->start + uap->length > IOPAGES * PAGE_SIZE * NBBY)
                return (EINVAL);


        for (i = uap->start; i < uap->start + uap->length; i++) {
                if (uap->enable)
                        iomap[i >> 3] &= ~(1 << (i & 7));
                        iomap[i >> 3] |= (1 << (i & 7));
        return (error);

You are receiving this mail because:
You are on the CC list for the bug.

More information about the freebsd-amd64 mailing list