Date: Sun, 4 Apr 2004 14:53:05 +0400 (MSD) From: Maxim Konovalov <maxim@macomnet.ru> To: Ryan Sommers <ryans@gamersimpact.com> Cc: current@freebsd.org Subject: Re: Panic from bad length parameter in bind (Possible DOS attack) Message-ID: <20040404144858.H26420@mp3files.int.ru> In-Reply-To: <49165.65.103.5.228.1081027268.squirrel@www2.neuroflux.com> References: <49165.65.103.5.228.1081027268.squirrel@www2.neuroflux.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[ CC'ed truckman, an author of rev. 1.92 tcp_usrreq.c ] On Sat, 3 Apr 2004, 14:21-0700, Ryan Sommers wrote: > Whenever I supply a length of 4 as the final bind parameter I get the > following panic. Looks like bind returns fine, however, when the program > exits it stumbles over some mutex associated with the descriptor. The > mutex passed to mtx_destroy() has MTX_RECURSED set. I attempted to find > where the call to bind was clobbering the mutex but couldn't. I attached > the simple program to exploit this. I was able to do it as a regular user. > > panic: Assertion (m->mtx_lock & (MTX_RECURSED|MTX_CONTESTED)) == 0 failed > at /usr/src/sys/kern/kern_mutex.c:848 > panic messages: > --- > panic: Assertion (m->mtx_lock & (MTX_RECURSED|MTX_CONTESTED)) == 0 failed > at /usr/src/sys/kern/kern_mutex.c:8485B > at line 848 in file /usr/src/sys/kern/kern_mutex.c > Debugger("panic") [...] Try this: Index: tcp_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.95 diff -u -r1.95 tcp_usrreq.c --- tcp_usrreq.c 16 Feb 2004 22:21:16 -0000 1.95 +++ tcp_usrreq.c 4 Apr 2004 10:41:14 -0000 @@ -245,8 +245,10 @@ * to them. */ sinp = (struct sockaddr_in *)nam; - if (nam->sa_len != sizeof (*sinp)) - return (EINVAL); + if (nam->sa_len != sizeof (*sinp)) { + error = EINVAL; + goto out; + } if (sinp->sin_family == AF_INET && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) { error = EAFNOSUPPORT; @@ -276,8 +278,10 @@ * to them. */ sin6p = (struct sockaddr_in6 *)nam; - if (nam->sa_len != sizeof (*sin6p)) - return (EINVAL); + if (nam->sa_len != sizeof (*sin6p)) { + error = EINVAL; + goto out; + } if (sin6p->sin6_family == AF_INET6 && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) { error = EAFNOSUPPORT; @@ -371,8 +375,10 @@ * Must disallow TCP ``connections'' to multicast addresses. */ sinp = (struct sockaddr_in *)nam; - if (nam->sa_len != sizeof (*sinp)) - return (EINVAL); + if (nam->sa_len != sizeof (*sinp)) { + error = EINVAL; + goto out; + } if (sinp->sin_family == AF_INET && IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) { error = EAFNOSUPPORT; @@ -405,8 +411,10 @@ * Must disallow TCP ``connections'' to multicast addresses. */ sin6p = (struct sockaddr_in6 *)nam; - if (nam->sa_len != sizeof (*sin6p)) - return (EINVAL); + if (nam->sa_len != sizeof (*sin6p)) { + error = EINVAL; + goto out; + } if (sin6p->sin6_family == AF_INET6 && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) { error = EAFNOSUPPORT; %%% -- Maxim Konovalov
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040404144858.H26420>