Panic from bad length parameter in bind (Possible DOS attack)
Maxim Konovalov
maxim at macomnet.ru
Sun Apr 4 03:53:09 PDT 2004
[ 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
More information about the freebsd-current
mailing list