sockets: on accept(2) don't copy all of so_options to new socket

As uncovered by e3ba0d6add we are copying lots of irrelevant options
from the listener to an accepted socket, even those that aren't relevant
to a non-listener, e.g. SO_REUSE*, SO_ACCEPTFILTER.  Stop doing that
and provide a fixed opt-in list for options to be inherited.  Ideally
we shall not inherit anything at all.  For compatibility inherit a set
of options that are meaningful for a non-listening socket of a protocol
that can listen(2).

Differential Revision:	https://reviews.freebsd.org/D41412
Fixes:			e3ba0d6add
This commit is contained in:
Gleb Smirnoff 2023-08-14 12:56:07 -07:00
parent e3637e2f5b
commit d29b95ecc0

View File

@ -750,7 +750,19 @@ solisten_clone(struct socket *head)
}
so->so_listen = head;
so->so_type = head->so_type;
so->so_options = head->so_options & ~SO_ACCEPTCONN;
/*
* POSIX is ambiguous on what options an accept(2)ed socket should
* inherit from the listener. Words "create a new socket" may be
* interpreted as not inheriting anything. Best programming practice
* for application developers is to not rely on such inheritance.
* FreeBSD had historically inherited all so_options excluding
* SO_ACCEPTCONN, which virtually means all SOL_SOCKET level options,
* including those completely irrelevant to a new born socket. For
* compatibility with older versions we will inherit a list of
* meaningful options.
*/
so->so_options = head->so_options & (SO_KEEPALIVE | SO_DONTROUTE |
SO_LINGER | SO_OOBINLINE | SO_NOSIGPIPE);
so->so_linger = head->so_linger;
so->so_state = head->so_state;
so->so_fibnum = head->so_fibnum;