[Bug 209661] amd64_set_ioperm overflow
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Fri May 20 13:44:56 UTC 2016
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=209661
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.
sys/amd64/amd64/sys_machdep:
int
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));
else
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