Module Name:    src
Committed By:   roy
Date:           Mon Mar 19 16:26:26 UTC 2018

Modified Files:
        src/lib/libc/sys: recv.2
        src/sys/kern: uipc_socket2.c uipc_usrreq.c
        src/sys/net: raw_usrreq.c
        src/sys/netinet: udp_usrreq.c
        src/sys/netinet6: udp6_usrreq.c
        src/sys/netipsec: keysock.c
        src/sys/sys: socketvar.h

Log Message:
socket: report receive buffer overflows

Add soroverflow() which increments the overflow counter, sets so_error
to ENOBUFS and wakes the receive socket up.
Replace all code that manually increments this counter with soroverflow().
Add soroverflow() to raw_input().

This allows userland to detect route(4) overflows so it can re-sync
with the current state.


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/lib/libc/sys/recv.2
cvs rdiff -u -r1.127 -r1.128 src/sys/kern/uipc_socket2.c
cvs rdiff -u -r1.183 -r1.184 src/sys/kern/uipc_usrreq.c
cvs rdiff -u -r1.58 -r1.59 src/sys/net/raw_usrreq.c
cvs rdiff -u -r1.245 -r1.246 src/sys/netinet/udp_usrreq.c
cvs rdiff -u -r1.137 -r1.138 src/sys/netinet6/udp6_usrreq.c
cvs rdiff -u -r1.62 -r1.63 src/sys/netipsec/keysock.c
cvs rdiff -u -r1.150 -r1.151 src/sys/sys/socketvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/sys/recv.2
diff -u src/lib/libc/sys/recv.2:1.37 src/lib/libc/sys/recv.2:1.38
--- src/lib/libc/sys/recv.2:1.37	Sun Jun 11 17:34:54 2017
+++ src/lib/libc/sys/recv.2	Mon Mar 19 16:26:26 2018
@@ -1,4 +1,4 @@
-.\"	$NetBSD: recv.2,v 1.37 2017/06/11 17:34:54 abhinav Exp $
+.\"	$NetBSD: recv.2,v 1.38 2018/03/19 16:26:26 roy Exp $
 .\"
 .\" Copyright (c) 1983, 1990, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)recv.2	8.3 (Berkeley) 2/21/94
 .\"
-.Dd June 22, 2012
+.Dd March 19, 2018
 .Dt RECV 2
 .Os
 .Sh NAME
@@ -319,6 +319,8 @@ any data were available.
 .It Bq Er EINVAL
 The total length of the I/O is more than can be expressed by the ssize_t
 return value.
+.It Bq Er ENOBUFS
+A message was not delivered because it would have overflowed the buffer.
 .It Bq Er ENOTCONN
 The socket is associated with a connection-oriented protocol
 and has not been connected (see

Index: src/sys/kern/uipc_socket2.c
diff -u src/sys/kern/uipc_socket2.c:1.127 src/sys/kern/uipc_socket2.c:1.128
--- src/sys/kern/uipc_socket2.c:1.127	Sun Mar 18 15:32:48 2018
+++ src/sys/kern/uipc_socket2.c	Mon Mar 19 16:26:26 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_socket2.c,v 1.127 2018/03/18 15:32:48 christos Exp $	*/
+/*	$NetBSD: uipc_socket2.c,v 1.128 2018/03/19 16:26:26 roy Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.127 2018/03/18 15:32:48 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.128 2018/03/19 16:26:26 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_mbuftrace.h"
@@ -495,6 +495,20 @@ socantrcvmore(struct socket *so)
 }
 
 /*
+ * soroverflow(): indicates that data was attempted to be sent
+ * but the receiving buffer overflowed.
+ */
+void
+soroverflow(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	so->so_rcv.sb_overflowed++;
+	so->so_error = ENOBUFS;
+	sorwakeup(so);
+}
+
+/*
  * Wait for data to arrive at/drain from a socket buffer.
  */
 int

Index: src/sys/kern/uipc_usrreq.c
diff -u src/sys/kern/uipc_usrreq.c:1.183 src/sys/kern/uipc_usrreq.c:1.184
--- src/sys/kern/uipc_usrreq.c:1.183	Sat Feb 17 20:19:36 2018
+++ src/sys/kern/uipc_usrreq.c	Mon Mar 19 16:26:26 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_usrreq.c,v 1.183 2018/02/17 20:19:36 christos Exp $	*/
+/*	$NetBSD: uipc_usrreq.c,v 1.184 2018/03/19 16:26:26 roy Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.183 2018/02/17 20:19:36 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.184 2018/03/19 16:26:26 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -342,10 +342,10 @@ unp_output(struct mbuf *m, struct mbuf *
 #endif
 	if (sbappendaddr(&so2->so_rcv, (const struct sockaddr *)sun, m,
 	    control) == 0) {
-		so2->so_rcv.sb_overflowed++;
 		unp_dispose(control);
 		m_freem(control);
 		m_freem(m);
+		soroverflow(so2);
 		return (ENOBUFS);
 	} else {
 		sorwakeup(so2);

Index: src/sys/net/raw_usrreq.c
diff -u src/sys/net/raw_usrreq.c:1.58 src/sys/net/raw_usrreq.c:1.59
--- src/sys/net/raw_usrreq.c:1.58	Mon Sep 25 01:57:54 2017
+++ src/sys/net/raw_usrreq.c	Mon Mar 19 16:26:25 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_usrreq.c,v 1.58 2017/09/25 01:57:54 ozaki-r Exp $	*/
+/*	$NetBSD: raw_usrreq.c,v 1.59 2018/03/19 16:26:25 roy Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.58 2017/09/25 01:57:54 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.59 2018/03/19 16:26:25 roy Exp $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -106,21 +106,26 @@ raw_input(struct mbuf *m0, ...)
 			continue;
 		if (last != NULL) {
 			struct mbuf *n;
-			if ((n = m_copy(m, 0, M_COPYALL)) == NULL)
-				;
-			else if (sbappendaddr(&last->so_rcv, src, n, NULL) == 0)
-				/* should notify about lost packet */
-				m_freem(n);
-			else {
+
+			if ((n = m_copy(m, 0, M_COPYALL)) == NULL ||
+			    sbappendaddr(&last->so_rcv, src, n, NULL) == 0)
+			{
+				if (n != NULL)
+					m_freem(n);
+				soroverflow(last);
+			} else
 				sorwakeup(last);
-			}
 		}
 		last = rp->rcb_socket;
 	}
-	if (last == NULL || sbappendaddr(&last->so_rcv, src, m, NULL) == 0)
-		m_freem(m);
-	else {
-		sorwakeup(last);
+	if (last != NULL) {
+		if (sbappendaddr(&last->so_rcv, src, m, NULL) == 0) {
+			m_free(m);
+			soroverflow(last);
+		} else
+			sorwakeup(last);
+	} else {
+		m_free(m);
 	}
 }
 

Index: src/sys/netinet/udp_usrreq.c
diff -u src/sys/netinet/udp_usrreq.c:1.245 src/sys/netinet/udp_usrreq.c:1.246
--- src/sys/netinet/udp_usrreq.c:1.245	Wed Feb 28 11:23:24 2018
+++ src/sys/netinet/udp_usrreq.c	Mon Mar 19 16:26:25 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: udp_usrreq.c,v 1.245 2018/02/28 11:23:24 maxv Exp $	*/
+/*	$NetBSD: udp_usrreq.c,v 1.246 2018/03/19 16:26:25 roy Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.245 2018/02/28 11:23:24 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.246 2018/03/19 16:26:25 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -498,8 +498,8 @@ udp4_sendup(struct mbuf *m, int off /* o
 			m_freem(n);
 			if (opts)
 				m_freem(opts);
-			so->so_rcv.sb_overflowed++;
 			UDP_STATINC(UDP_STAT_FULLSOCK);
+			soroverflow(so);
 		} else
 			sorwakeup(so);
 	}

Index: src/sys/netinet6/udp6_usrreq.c
diff -u src/sys/netinet6/udp6_usrreq.c:1.137 src/sys/netinet6/udp6_usrreq.c:1.138
--- src/sys/netinet6/udp6_usrreq.c:1.137	Wed Feb 28 11:23:24 2018
+++ src/sys/netinet6/udp6_usrreq.c	Mon Mar 19 16:26:25 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: udp6_usrreq.c,v 1.137 2018/02/28 11:23:24 maxv Exp $ */
+/* $NetBSD: udp6_usrreq.c,v 1.138 2018/03/19 16:26:25 roy Exp $ */
 /* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */
 /* $KAME: udp6_output.c,v 1.43 2001/10/15 09:19:52 itojun Exp $ */
 
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.137 2018/02/28 11:23:24 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.138 2018/03/19 16:26:25 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -372,8 +372,8 @@ udp6_sendup(struct mbuf *m, int off /* o
 			m_freem(n);
 			if (opts)
 				m_freem(opts);
-			so->so_rcv.sb_overflowed++;
 			UDP6_STATINC(UDP6_STAT_FULLSOCK);
+			soroverflow(so);
 		} else
 			sorwakeup(so);
 	}

Index: src/sys/netipsec/keysock.c
diff -u src/sys/netipsec/keysock.c:1.62 src/sys/netipsec/keysock.c:1.63
--- src/sys/netipsec/keysock.c:1.62	Thu Sep 28 17:21:42 2017
+++ src/sys/netipsec/keysock.c	Mon Mar 19 16:26:26 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: keysock.c,v 1.62 2017/09/28 17:21:42 christos Exp $	*/
+/*	$NetBSD: keysock.c,v 1.63 2018/03/19 16:26:26 roy Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.62 2017/09/28 17:21:42 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.63 2018/03/19 16:26:26 roy Exp $");
 
 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
 
@@ -207,11 +207,12 @@ key_sendup0(
 		    __func__);
 		PFKEY_STATINC(PFKEY_STAT_IN_NOMEM);
 		m_freem(m);
+		soroverflow(rp->rcb_socket);
 		error = ENOBUFS;
-		rp->rcb_socket->so_rcv.sb_overflowed++;
-	} else
+	} else {
+		sorwakeup(rp->rcb_socket);
 		error = 0;
-	sorwakeup(rp->rcb_socket);
+	}
 	return error;
 }
 

Index: src/sys/sys/socketvar.h
diff -u src/sys/sys/socketvar.h:1.150 src/sys/sys/socketvar.h:1.151
--- src/sys/sys/socketvar.h:1.150	Sun Mar 18 15:42:37 2018
+++ src/sys/sys/socketvar.h	Mon Mar 19 16:26:26 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: socketvar.h,v 1.150 2018/03/18 15:42:37 christos Exp $	*/
+/*	$NetBSD: socketvar.h,v 1.151 2018/03/19 16:26:26 roy Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -301,6 +301,7 @@ int	sofamily(const struct socket *);
 int	sobind(struct socket *, struct sockaddr *, struct lwp *);
 void	socantrcvmore(struct socket *);
 void	socantsendmore(struct socket *);
+void	soroverflow(struct socket *);
 int	soclose(struct socket *);
 int	soconnect(struct socket *, struct sockaddr *, struct lwp *);
 int	soconnect2(struct socket *, struct socket *);

Reply via email to