Re: Panic from bad length parameter in bind (Possible DOS attack)

From: Maxim Konovalov <maxim_at_macomnet.ru>
Date: Sun, 4 Apr 2004 14:53:05 +0400 (MSD)
[ 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
_at__at_ -245,8 +245,10 _at__at_
 	 * 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;
_at__at_ -276,8 +278,10 _at__at_
 	 * 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;
_at__at_ -371,8 +375,10 _at__at_
 	 * 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;
_at__at_ -405,8 +411,10 _at__at_
 	 * 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
Received on Sun Apr 04 2004 - 01:53:09 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:49 UTC