Wednesday, December 01, 2010

NetBSD Denial^WLocal root ?

Dear,

Here are some information about the vulnerability released by NetBSD.org 3 days ago.

The issue is due to the use of an uninitialized structure « allocated » on the kernel stack. It seems to affect all NetBSD stable releases since 5.0.2.

Vulnerability resides in the udp6_output() kernel function which can be triggered from userland by a single sendmsg() call on a basic UDP6 socket. Here is the buggy code:

int udp6_output(..., struct mbuf *addr6, struct mbuf *control, ...)
{
(...)
struct ip6_pktopts *optp, opt; [0]
(... nothing is done on opt ...)
if (addr6) {
if (addr6->m_len != sizeof(*sin6)) {
error = EINVAL;
goto release; [1]
}
sin6 = mtod(addr6, struct sockaddr_in6 *);
if (sin6->sin6_family != AF_INET6) {
error = EAFNOSUPPORT;
goto release; [2]
}
(...)
}
(...)
if (control) {
if ((error = ip6_setpktopts(control, &opt, in6p->in6p_outputopts, priv, IPPROTO_UDP)) != 0) [3]
goto release;
optp = &opt;
}
(...)
release:
m_freem(m);
releaseopt:
if (control) {
ip6_clearpktopts(&opt, -1); [4]
m_freem(control);
}
}

At [0] we have an opt ip6_pktopts structure declarated on the kernel stack. This structure is initialized/filled in [3] by ip6_setpktopts() and cleared in the releaseopt label [4] by a call to ip6_clearpktopts(). Unfortunately this label can be achieved before initialization at [1] or [2] if udp6_output() is called with a bad addr6 (msg_name field of the msghdr struct) for example. If it is the case, ip6_clearpktopts() will try to free uninitialized pointers and/or to remove routes from linked lists. Here is the most interesting parts of ip6_clearpktopts().

void ip6_clearpktopts(struct ip6_pktopts *pktopt, int optname)
{
if (optname == -1 || optname == IPV6_PKTINFO) {
if (pktopt->ip6po_pktinfo)
free(pktopt->ip6po_pktinfo, M_IP6OPT);
(...)
if (optname == -1 || optname == IPV6_RTHDR) {
if (pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
free(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT);
rtcache_free(&pktopt->ip6po_route);
}
(...)
}


Exploitation of this security issue can result in a kernel panic by using this simple proof of concept. I am currently trying to gain root priv. through this vulnerability by using some evil mmap()s at fixed address to trick the rtcache_free() to write a NULL at an user controlled address but it's not yet reliable. More information about this soon. ;-)

PS: I have just received this book and it really rocks. \o/

PS2: Phrack #67 rocks too, I loved the quotes on the glibc code in the « A Eulogy for Format Strings paper ». Grep for alloca() in glibc and enjoy. \o/

2 Comments:

Blogger tito said...

Your link from amazon is dead :)

2:44 PM  
Blogger clem1 said...

@tito: fixed, thanks. Hope you are well man. :-)

4:59 AM  

Post a Comment

<< Home