CESA-2006-003 - rev 1
[See all my vulnerabilities at
http://scary.beasts.org/security]
OpenBSD / NetBSD systrace kernel integer overflow
Programs affected: OpenBSD 3.9, NetBSD 3.
Severity: Local privilege escalation.
systrace is a technology which allows supervision and allow / deny of syscalls
made by a supervised process. There is an integer overflow condition in the
kernel component of systrace which can be triggered by specifiying large
integer values in a systrace ioctl(). The integer overflow condition allows
the sidestep of a sanity check, and subsequent out-of-bounds write of a NULL
byte to a fairly arbitrary kernel address. Reading of chunks of kernel memory
may also be possible.
Possible fruitful attacks here include:
- Writing NULL bytes over your own UID, to get UID 0.
- Writing NULL bytes over wherever securelevel is stored.
The actual code flaw can be observed in the systrace_preprepl function:
for (i = 0, len = 0; i < repl->strr_nrepl; i++) {
len += repl->strr_offlen[i];
if (repl->strr_offlen[i] == 0)
continue;
if (repl->strr_offlen[i] + repl->strr_off[i] > len)
return (EINVAL);
}
/* Make sure that the length adds up */
if (repl->strr_len != len)
return (EINVAL);
/* Check against a maximum length */
if (repl->strr_len > 2048)
return (EINVAL);
Here, strr_offlen[i] + strr_off[i] can overflow, leading to the attacker's
choice of very large strr_offlen or strr_off. The "len" variable is also
subject to integer overflow, making the strr_len <= 2048 requirement easy
to satisfy. Subsequently, in systrace_replace, the attacker-supplied huge
value is used:
if (repl->strr_flags[i] & SYSTR_NOLINKS) {
ret = systrace_fname(strp, kdata, repl->strr_offlen[i]);
And looking at systrace_fname:
int
systrace_fname(struct str_process *strp, caddr_t kdata, size_t len)
{
if (strp->nfname >= SYSTR_MAXFNAME || len < 1)
return EINVAL;
strp->fname[strp->nfname] = kdata;
strp->fname[strp->nfname][len - 1] = '\0';
strp->nfname++;
return 0;
}
"len" is fairly arbitrarily attacker-controlled, leading to the ability to
write NULLs anywhere in kernel space.
Also, in systrace_replace, there's the use of this attacker-controlled
length to copy out to userspace, probably resulting in ability to steal
contents of kernel memory:
if (copyout(kdata, udata, repl->strr_offlen[i])) {
ret = EINVAL;
goto out;
}
Credits
- Google - this flaw was discovered in Google's time. I'm with Google's
Security Team, and we're always recruiting talented security individuals.
Mail me.
- Damien Miller - for great proof of concept work looking into how serious
the flaw actually is.
CESA-2006-003 - rev 1
Chris Evans
scarybeasts@gmail.com