- Introduce a new SO_RERROR socket option to explicitly turn on

receive overflow errors re-instating the default behavior to
  silently ignore them as before 2018-03-19.
- Introduce a new kern.sooptions sysctl to control the default
  behavior of socket options. Setting this to 0x4000 (SO_RERROR),
  turns on receive overflow error reporting for all sockets.
- Change dhcpcd to turn on SO_RERROR on all its sockets.

As discussed in tech-net.
This commit is contained in:
christos 2018-11-04 16:30:28 +00:00
parent d760c69bf1
commit 2d24b2e817
9 changed files with 119 additions and 15 deletions

View File

@ -1604,6 +1604,11 @@ dhcp_openudp(struct interface *ifp)
n = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
goto eexit;
#ifdef SO_RERROR
n = 1;
if (setsockopt(s, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) == -1)
goto eexit;
#endif
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(BOOTPC);

View File

@ -3620,6 +3620,11 @@ dhcp6_listen(struct dhcpcd_ctx *ctx, struct ipv6_addr *ia)
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n)) == -1)
goto errexit;
#ifdef SO_RERROR
n = 1;
if (setsockopt(s, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) == -1)
goto errexit;
#endif
memset(&sa, 0, sizeof(sa));
sa.sin6_family = AF_INET6;
sa.sin6_port = htons(DHCP6_CLIENT_PORT);

View File

@ -161,6 +161,12 @@ if_opensockets_os(struct dhcpcd_ctx *ctx)
if (ctx->link_fd == -1)
return -1;
#ifdef SO_RERROR
int n = 1;
if (setsockopt(ctx->link_fd, SOL_SOCKET, SO_RERROR,
&n, sizeof(n)) == -1)
logerr(__func__);
#endif
#if defined(RO_MSGFILTER)
if (setsockopt(ctx->link_fd, PF_ROUTE, RO_MSGFILTER,
&msgfilter, sizeof(msgfilter)) == -1)

View File

@ -217,6 +217,13 @@ ipv6nd_open(struct dhcpcd_ctx *ctx)
&on, sizeof(on)) == -1)
goto eexit;
#ifdef SO_RERROR
on = 1;
if (setsockopt(ctx->nd_fd, SOL_SOCKET, SO_RERROR,
&on, sizeof(on)) == -1)
goto eexit;
#endif
ICMP6_FILTER_SETBLOCKALL(&filt);
ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filt);
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filt);

View File

@ -1,4 +1,4 @@
.\" $NetBSD: getsockopt.2,v 1.37 2018/07/31 22:28:26 sevan Exp $
.\" $NetBSD: getsockopt.2,v 1.38 2018/11/04 16:30:28 christos Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" @(#)getsockopt.2 8.4 (Berkeley) 5/2/95
.\"
.Dd July 31, 2018
.Dd November 3, 2018
.Dt GETSOCKOPT 2
.Os
.Sh NAME
@ -179,6 +179,7 @@ and set with
.It Dv SO_RCVTIMEO Ta "set timeout value for input"
.It Dv SO_TIMESTAMP Ta "enables reception of a timestamp with datagrams"
.It Dv SO_ACCEPTFILTER Ta "set accept filter on listening socket"
.It Dv SO_RERROR Ta "enables receive size error reporting"
.It Dv SO_NOSIGPIPE Ta
controls generation of
.Dv SIGPIPE
@ -213,6 +214,19 @@ indicates that outgoing messages should
bypass the standard routing facilities.
Instead, messages are directed to the appropriate network interface
according to the network portion of the destination address.
.Dv SO_RERROR
indicates that receive buffer overflows should be handled as errors.
Historically receive buffer overflows have been ignored and programs
could not tell if they missed messages or messages had been truncated
because of overflows.
Since programs historically do not expect to get receive overflow errors,
this behavior is not the default, but the default can be changed by
setting the
.Dv SO_RERROR
flag using
.Xr sysctl 1
and
.Dv kern.sooptions .
.Pp
.Dv SO_LINGER
controls the action taken when unsent messages

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sysctl.7,v 1.134 2018/10/30 19:41:21 kre Exp $
.\" $NetBSD: sysctl.7,v 1.135 2018/11/04 16:30:28 christos Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@ -29,7 +29,7 @@
.\"
.\" @(#)sysctl.3 8.4 (Berkeley) 5/9/95
.\"
.Dd October 30, 2018
.Dd November 3, 2018
.Dt SYSCTL 7
.Os
.Sh NAME
@ -359,6 +359,7 @@ privilege may change the value.
.It kern.sched node not applicable
.It kern.securelevel integer raise only
.It kern.somaxkva integer yes
.It kern.sooptions integer yes
.It kern.synchronized_io integer no
.It kern.timecounter node not applicable
.It kern.timex struct no
@ -1062,8 +1063,7 @@ Return the offset of real time clock from UTC in minutes.
.It Li kern.saved_ids ( Dv KERN_SAVED_IDS )
Returns 1 if saved set-group and saved set-user ID is available.
.It Li kern.sbmax ( Dv KERN_SBMAX )
Maximum socket buffer size.
.\" XXX units?
Maximum socket buffer size in bytes.
.It Li kern.securelevel ( Dv KERN_SECURELVL )
See
.Xr secmodel_securelevel 9 .
@ -1166,8 +1166,14 @@ See
.Xr sched 3 .
.El
.It Li kern.somaxkva ( Dv KERN_SOMAXKVA )
Maximum amount of kernel memory to be used for socket buffers.
.\" XXX units?
Maximum amount of kernel memory to be used for socket buffers in bytes.
.It Li kern.sooptions
Set the default socket option flags for
.Xr socket 2
creation.
See
.Xr setsockopt 2
for a list of supported flags.
.It Li kern.synchronized_io ( Dv KERN_SYNCHRONIZED_IO )
Returns 1 if the
.St -p1003.1b-93

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_socket.c,v 1.265 2018/09/03 16:29:35 riastradh Exp $ */
/* $NetBSD: uipc_socket.c,v 1.266 2018/11/04 16:30:29 christos Exp $ */
/*-
* Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.265 2018/09/03 16:29:35 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.266 2018/11/04 16:30:29 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@ -118,6 +118,7 @@ MALLOC_DEFINE(M_SONAME, "soname", "socket name");
extern const struct fileops socketops;
static int sooptions;
extern int somaxconn; /* patchable (XXX sysctl) */
int somaxconn = SOMAXCONN;
kmutex_t *softnet_lock;
@ -537,6 +538,7 @@ socreate(int dom, struct socket **aso, int type, int proto, struct lwp *l,
so->so_proto = prp;
so->so_send = sosend;
so->so_receive = soreceive;
so->so_options = sooptions;
#ifdef MBUFTRACE
so->so_rcv.sb_mowner = &prp->pr_domain->dom_mowner;
so->so_snd.sb_mowner = &prp->pr_domain->dom_mowner;
@ -1757,6 +1759,7 @@ sosetopt1(struct socket *so, const struct sockopt *sopt)
case SO_OOBINLINE:
case SO_TIMESTAMP:
case SO_NOSIGPIPE:
case SO_RERROR:
#ifdef SO_OTIMESTAMP
case SO_OTIMESTAMP:
#endif
@ -1958,6 +1961,7 @@ sogetopt1(struct socket *so, struct sockopt *sopt)
case SO_OOBINLINE:
case SO_TIMESTAMP:
case SO_NOSIGPIPE:
case SO_RERROR:
#ifdef SO_OTIMESTAMP
case SO_OTIMESTAMP:
#endif
@ -2522,6 +2526,31 @@ sysctl_kern_sbmax(SYSCTLFN_ARGS)
return (error);
}
/*
* sysctl helper routine for kern.sooptions. Ensures that only allowed
* options can be set.
*/
static int
sysctl_kern_sooptions(SYSCTLFN_ARGS)
{
int error, new_options;
struct sysctlnode node;
new_options = sooptions;
node = *rnode;
node.sysctl_data = &new_options;
error = sysctl_lookup(SYSCTLFN_CALL(&node));
if (error || newp == NULL)
return error;
if (new_options & ~SO_DEFOPTS)
return EINVAL;
sooptions = new_options;
return 0;
}
static void
sysctl_kern_socket_setup(void)
{
@ -2542,4 +2571,11 @@ sysctl_kern_socket_setup(void)
SYSCTL_DESCR("Maximum socket buffer size"),
sysctl_kern_sbmax, 0, NULL, 0,
CTL_KERN, KERN_SBMAX, CTL_EOL);
sysctl_createv(&socket_sysctllog, 0, NULL, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "sooptions",
SYSCTL_DESCR("Default socket options"),
sysctl_kern_sooptions, 0, NULL, 0,
CTL_KERN, CTL_CREATE, CTL_EOL);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: uipc_socket2.c,v 1.132 2018/09/03 16:29:35 riastradh Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.133 2018/11/04 16:30:29 christos 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.132 2018/09/03 16:29:35 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.133 2018/11/04 16:30:29 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@ -509,8 +509,10 @@ soroverflow(struct socket *so)
KASSERT(solocked(so));
so->so_rcv.sb_overflowed++;
so->so_rerror = ENOBUFS;
sorwakeup(so);
if (so->so_options & SO_RERROR) {
so->so_rerror = ENOBUFS;
sorwakeup(so);
}
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: socket.h,v 1.128 2018/09/16 20:40:20 mrg Exp $ */
/* $NetBSD: socket.h,v 1.129 2018/11/04 16:30:29 christos Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -132,7 +132,30 @@ typedef _BSD_SSIZE_T_ ssize_t;
#define SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */
#define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */
#define SO_TIMESTAMP 0x2000 /* timestamp received dgram traffic */
#define SO_RERROR 0x4000 /* Keep track of receive errors */
/* Allowed default option flags */
#define SO_DEFOPTS (SO_DEBUG|SO_REUSEADDR|SO_KEEPALIVE|SO_DONTROUTE| \
SO_BROADCAST|SO_USELOOPBACK|SO_LINGER|SO_OOBINLINE|SO_REUSEPORT| \
SO_NOSIGPIPE|SO_TIMESTAMP|SO_RERROR)
#define __SO_OPTION_BITS \
"\20" \
"\1SO_DEBUG" \
"\2SO_ACCEPTCONN" \
"\3SO_REUSEADDR" \
"\4SO_KEEPALIVE" \
"\5SO_DONTROUTE" \
"\6SO_BROADCAST" \
"\7SO_USELOOPBACK" \
"\10SO_LINGER" \
"\11SO_OOBINLINE" \
"\12SO_REUSEPORT" \
"\13SO_OTIMESTAMP" \
"\14SO_NOSIGPIPE" \
"\15SO_ACCEPTFILTER" \
"\16SO_TIMESTAMP" \
"\17SO_RERROR"
/*
* Additional options, not kept in so_options.