Module Name: src Committed By: christos Date: Tue Sep 8 14:12:57 UTC 2020
Modified Files: src/share/man/man4: ip.4 ip6.4 src/sys/netinet: in.h in_pcb.c in_pcb.h ip_output.c raw_ip.c src/sys/netinet6: in6.h in6_pcb.c in6_pcb.h ip6_output.c src/sys/secmodel/suser: secmodel_suser.c src/sys/sys: kauth.h Log Message: Add IP_BINDANY, IPV6_BINDANY which can be used to bind to any address in order to implement transparent proxies. To generate a diff of this commit: cvs rdiff -u -r1.44 -r1.45 src/share/man/man4/ip.4 cvs rdiff -u -r1.31 -r1.32 src/share/man/man4/ip6.4 cvs rdiff -u -r1.110 -r1.111 src/sys/netinet/in.h cvs rdiff -u -r1.184 -r1.185 src/sys/netinet/in_pcb.c cvs rdiff -u -r1.68 -r1.69 src/sys/netinet/in_pcb.h cvs rdiff -u -r1.319 -r1.320 src/sys/netinet/ip_output.c cvs rdiff -u -r1.179 -r1.180 src/sys/netinet/raw_ip.c cvs rdiff -u -r1.99 -r1.100 src/sys/netinet6/in6.h cvs rdiff -u -r1.166 -r1.167 src/sys/netinet6/in6_pcb.c cvs rdiff -u -r1.51 -r1.52 src/sys/netinet6/in6_pcb.h cvs rdiff -u -r1.225 -r1.226 src/sys/netinet6/ip6_output.c cvs rdiff -u -r1.54 -r1.55 src/sys/secmodel/suser/secmodel_suser.c cvs rdiff -u -r1.85 -r1.86 src/sys/sys/kauth.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/ip.4 diff -u src/share/man/man4/ip.4:1.44 src/share/man/man4/ip.4:1.45 --- src/share/man/man4/ip.4:1.44 Fri Aug 28 12:07:49 2020 +++ src/share/man/man4/ip.4 Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -.\" $NetBSD: ip.4,v 1.44 2020/08/28 16:07:49 fcambus Exp $ +.\" $NetBSD: ip.4,v 1.45 2020/09/08 14:12:57 christos Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" @(#)ip.4 8.2 (Berkeley) 11/30/93 .\" -.Dd December 31, 2017 +.Dd September 8, 2020 .Dt IP 4 .Os .Sh NAME @@ -227,6 +227,23 @@ cmsg_type = IP_RECVIF .Ed .Pp If the +.Dv IP_BINDANY +option is enabled on a +.Dv SOCK_STREAM , +.Dv SOCK_DGRAM +or a +.Dv SOCK_RAW +socket, one can +.Xr bind 2 +to any address, even one not bound to any available network interface in the +system. +This functionality (in conjunction with special firewall rules) can be used for +implementing a transparent proxy. +The +.Dv KAUTH_REQ_NETWORK_BIND_ANYADDR +privilege is needed to set this option. +.Pp +If the .Dv IP_RECVTTL option is enabled on a .Dv SOCK_DGRAM Index: src/share/man/man4/ip6.4 diff -u src/share/man/man4/ip6.4:1.31 src/share/man/man4/ip6.4:1.32 --- src/share/man/man4/ip6.4:1.31 Mon Jul 3 17:30:58 2017 +++ src/share/man/man4/ip6.4 Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -.\" $NetBSD: ip6.4,v 1.31 2017/07/03 21:30:58 wiz Exp $ +.\" $NetBSD: ip6.4,v 1.32 2020/09/08 14:12:57 christos Exp $ .\" $KAME: ip6.4,v 1.23 2005/01/11 05:56:25 itojun Exp $ .\" $OpenBSD: ip6.4,v 1.21 2005/01/06 03:50:46 itojun Exp $ .\" @@ -28,7 +28,7 @@ .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. -.Dd June 25, 2012 +.Dd September 8, 2020 .Dt IP6 4 .Os .Sh NAME @@ -430,6 +430,21 @@ Get or set the ESP encapsulation level. Get or set the .Xr ipcomp 4 level. +.Dv IPV6_BINDANY +option is enabled on a +.Dv SOCK_STREAM , +.Dv SOCK_DGRAM +or a +.Dv SOCK_RAW +socket, one can +.Xr bind 2 +to any address, even one not bound to any available network interface in the +system. +This functionality (in conjunction with special firewall rules) can be used for +implementing a transparent proxy. +The +.Dv KAUTH_REQ_NETWORK_BIND_ANYADDR +privilege is needed to set this option. .El .Pp The Index: src/sys/netinet/in.h diff -u src/sys/netinet/in.h:1.110 src/sys/netinet/in.h:1.111 --- src/sys/netinet/in.h:1.110 Thu Aug 20 17:21:32 2020 +++ src/sys/netinet/in.h Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: in.h,v 1.110 2020/08/20 21:21:32 riastradh Exp $ */ +/* $NetBSD: in.h,v 1.111 2020/09/08 14:12:57 christos Exp $ */ /* * Copyright (c) 1982, 1986, 1990, 1993 @@ -293,7 +293,7 @@ struct ip_opts { #define IP_MINTTL 24 /* minimum TTL for packet or drop */ #define IP_PKTINFO 25 /* struct; set default src if/addr */ #define IP_RECVPKTINFO 26 /* int; receive dst if/addr w/dgram */ - +#define IP_BINDANY 27 /* bool: allow bind to any address */ #define IP_SENDSRCADDR IP_RECVDSTADDR /* FreeBSD compatibility */ /* Index: src/sys/netinet/in_pcb.c diff -u src/sys/netinet/in_pcb.c:1.184 src/sys/netinet/in_pcb.c:1.185 --- src/sys/netinet/in_pcb.c:1.184 Thu Aug 20 17:21:32 2020 +++ src/sys/netinet/in_pcb.c Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: in_pcb.c,v 1.184 2020/08/20 21:21:32 riastradh Exp $ */ +/* $NetBSD: in_pcb.c,v 1.185 2020/09/08 14:12:57 christos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -93,7 +93,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.184 2020/08/20 21:21:32 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.185 2020/09/08 14:12:57 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -274,7 +274,8 @@ in_pcbsetport(struct sockaddr_in *sin, s } int -in_pcbbindableaddr(struct sockaddr_in *sin, kauth_cred_t cred) +in_pcbbindableaddr(const struct inpcb *inp, struct sockaddr_in *sin, + kauth_cred_t cred) { int error = EADDRNOTAVAIL; struct ifaddr *ifa = NULL; @@ -295,6 +296,10 @@ in_pcbbindableaddr(struct sockaddr_in *s ifa = ifa_ifwithaddr(sintosa(sin)); if (ifa != NULL) ia = ifatoia(ifa); + else if ((inp->inp_flags & INP_BINDANY) != 0) { + error = 0; + goto error; + } } if (ia == NULL) goto error; @@ -312,7 +317,7 @@ in_pcbbind_addr(struct inpcb *inp, struc { int error; - error = in_pcbbindableaddr(sin, cred); + error = in_pcbbindableaddr(inp, sin, cred); if (error == 0) inp->inp_laddr = sin->sin_addr; return error; @@ -546,7 +551,7 @@ in_pcbconnect(void *v, struct sockaddr_i } s = pserialize_read_enter(); _ia = in_get_ia(IA_SIN(ia)->sin_addr); - if (_ia == NULL) { + if (_ia == NULL && (inp->inp_flags & INP_BINDANY) == 0) { pserialize_read_exit(s); ia4_release(ia, &psref); curlwp_bindx(bound); @@ -587,7 +592,7 @@ in_pcbconnect(void *v, struct sockaddr_i lsin.sin_addr = inp->inp_laddr; lsin.sin_port = 0; - if ((error = in_pcbbind_port(inp, &lsin, l->l_cred)) != 0) + if ((error = in_pcbbind_port(inp, &lsin, l->l_cred)) != 0) return error; } Index: src/sys/netinet/in_pcb.h diff -u src/sys/netinet/in_pcb.h:1.68 src/sys/netinet/in_pcb.h:1.69 --- src/sys/netinet/in_pcb.h:1.68 Fri Aug 28 03:01:57 2020 +++ src/sys/netinet/in_pcb.h Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: in_pcb.h,v 1.68 2020/08/28 07:01:57 riastradh Exp $ */ +/* $NetBSD: in_pcb.h,v 1.69 2020/09/08 14:12:57 christos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -131,6 +131,7 @@ struct inpcb { */ #define INP_RECVTTL 0x0800 /* receive incoming IP TTL */ #define INP_RECVPKTINFO 0x1000 /* receive IP dst if/addr */ +#define INP_BINDANY 0x2000 /* allow bind to any address */ #define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR|\ INP_RECVIF|INP_RECVTTL|INP_RECVPKTINFO) @@ -153,7 +154,8 @@ struct vestigial_inpcb; void in_losing(struct inpcb *); int in_pcballoc(struct socket *, void *); -int in_pcbbindableaddr(struct sockaddr_in *, kauth_cred_t); +int in_pcbbindableaddr(const struct inpcb *, struct sockaddr_in *, + kauth_cred_t); int in_pcbbind(void *, struct sockaddr_in *, struct lwp *); int in_pcbconnect(void *, struct sockaddr_in *, struct lwp *); void in_pcbdetach(void *); Index: src/sys/netinet/ip_output.c diff -u src/sys/netinet/ip_output.c:1.319 src/sys/netinet/ip_output.c:1.320 --- src/sys/netinet/ip_output.c:1.319 Fri Aug 28 13:01:48 2020 +++ src/sys/netinet/ip_output.c Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_output.c,v 1.319 2020/08/28 17:01:48 christos Exp $ */ +/* $NetBSD: ip_output.c,v 1.320 2020/09/08 14:12:57 christos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.319 2020/08/28 17:01:48 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.320 2020/09/08 14:12:57 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1120,6 +1120,7 @@ ip_ctloutput(int op, struct socket *so, case IP_RECVIF: case IP_RECVPKTINFO: case IP_RECVTTL: + case IP_BINDANY: error = sockopt_getint(sopt, &optval); if (error) break; @@ -1168,6 +1169,16 @@ ip_ctloutput(int op, struct socket *so, case IP_RECVTTL: OPTSET(INP_RECVTTL); break; + + case IP_BINDANY: + error = kauth_authorize_network( + kauth_cred_get(), KAUTH_NETWORK_BIND, + KAUTH_REQ_NETWORK_BIND_ANYADDR, so, + NULL, NULL); + if (error == 0) { + OPTSET(INP_BINDANY); + } + break; } break; case IP_PKTINFO: @@ -1294,6 +1305,7 @@ ip_ctloutput(int op, struct socket *so, case IP_RECVPKTINFO: case IP_RECVTTL: case IP_ERRORMTU: + case IP_BINDANY: switch (sopt->sopt_name) { case IP_TOS: optval = ip->ip_tos; @@ -1336,6 +1348,10 @@ ip_ctloutput(int op, struct socket *so, case IP_RECVTTL: optval = OPTBIT(INP_RECVTTL); break; + + case IP_BINDANY: + optval = OPTBIT(INP_BINDANY); + break; } error = sockopt_setint(sopt, optval); break; @@ -1416,8 +1432,8 @@ ip_ctloutput(int op, struct socket *so, } static int -ip_pktinfo_prepare(const struct in_pktinfo *pktinfo, struct ip_pktopts *pktopts, - int *flags, kauth_cred_t cred) +ip_pktinfo_prepare(const struct inpcb *inp, const struct in_pktinfo *pktinfo, + struct ip_pktopts *pktopts, int *flags, kauth_cred_t cred) { struct ip_moptions *imo; int error = 0; @@ -1426,7 +1442,7 @@ ip_pktinfo_prepare(const struct in_pktin if (!in_nullhost(pktinfo->ipi_addr)) { pktopts->ippo_laddr.sin_addr = pktinfo->ipi_addr; /* EADDRNOTAVAIL? */ - error = in_pcbbindableaddr(&pktopts->ippo_laddr, cred); + error = in_pcbbindableaddr(inp, &pktopts->ippo_laddr, cred); if (error != 0) return error; addrset = true; @@ -1519,8 +1535,8 @@ ip_setpktopts(struct mbuf *control, stru if (cm->cmsg_len != CMSG_LEN(sizeof(pktinfo))) return EINVAL; memcpy(&pktinfo, CMSG_DATA(cm), sizeof(pktinfo)); - error = ip_pktinfo_prepare(&pktinfo, pktopts, flags, - cred); + error = ip_pktinfo_prepare(inp, &pktinfo, pktopts, + flags, cred); if (error) return error; break; @@ -1530,8 +1546,8 @@ ip_setpktopts(struct mbuf *control, stru pktinfo.ipi_ifindex = 0; pktinfo.ipi_addr = ((struct in_pktinfo *)CMSG_DATA(cm))->ipi_addr; - error = ip_pktinfo_prepare(&pktinfo, pktopts, flags, - cred); + error = ip_pktinfo_prepare(inp, &pktinfo, pktopts, + flags, cred); if (error) return error; break; Index: src/sys/netinet/raw_ip.c diff -u src/sys/netinet/raw_ip.c:1.179 src/sys/netinet/raw_ip.c:1.180 --- src/sys/netinet/raw_ip.c:1.179 Sun Feb 24 02:20:33 2019 +++ src/sys/netinet/raw_ip.c Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_ip.c,v 1.179 2019/02/24 07:20:33 maxv Exp $ */ +/* $NetBSD: raw_ip.c,v 1.180 2020/09/08 14:12:57 christos Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.179 2019/02/24 07:20:33 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.180 2020/09/08 14:12:57 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -594,6 +594,7 @@ rip_bind(struct socket *so, struct socka } ss = pserialize_read_enter(); if ((ifa = ifa_ifwithaddr(sintosa(addr))) == NULL && + (inp->inp_flags & INP_BINDANY) == 0 && !in_nullhost(addr->sin_addr)) { pserialize_read_exit(ss); Index: src/sys/netinet6/in6.h diff -u src/sys/netinet6/in6.h:1.99 src/sys/netinet6/in6.h:1.100 --- src/sys/netinet6/in6.h:1.99 Fri Jun 12 07:04:45 2020 +++ src/sys/netinet6/in6.h Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: in6.h,v 1.99 2020/06/12 11:04:45 roy Exp $ */ +/* $NetBSD: in6.h,v 1.100 2020/09/08 14:12:57 christos Exp $ */ /* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ /* @@ -441,6 +441,7 @@ extern const struct in6_addr in6addr_lin #define IPV6_DONTFRAG 62 /* bool; disable IPv6 fragmentation */ #define IPV6_PREFER_TEMPADDR 63 /* int; prefer temporary address as * the sorce address */ +#define IPV6_BINDANY 64 /* bool: allow bind to any address */ /* to define items, should talk with KAME guys first, for *BSD compatibility */ #define IPV6_RTHDR_LOOSE 0 /* this hop need not be a neighbor. XXX old spec */ Index: src/sys/netinet6/in6_pcb.c diff -u src/sys/netinet6/in6_pcb.c:1.166 src/sys/netinet6/in6_pcb.c:1.167 --- src/sys/netinet6/in6_pcb.c:1.166 Tue May 14 22:59:18 2019 +++ src/sys/netinet6/in6_pcb.c Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_pcb.c,v 1.166 2019/05/15 02:59:18 ozaki-r Exp $ */ +/* $NetBSD: in6_pcb.c,v 1.167 2020/09/08 14:12:57 christos Exp $ */ /* $KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.166 2019/05/15 02:59:18 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.167 2020/09/08 14:12:57 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -235,7 +235,8 @@ in6_pcbbind_addr(struct in6pcb *in6p, st if (!IN_MULTICAST(sin.sin_addr.s_addr)) { struct ifaddr *ifa; ifa = ifa_ifwithaddr((struct sockaddr *)&sin); - if (ifa == NULL) { + if (ifa == NULL && + (in6p->in6p_flags & IN6P_BINDANY) == 0) { error = EADDRNOTAVAIL; goto out; } @@ -248,7 +249,8 @@ in6_pcbbind_addr(struct in6pcb *in6p, st if ((in6p->in6p_flags & IN6P_FAITH) == 0) { ifa = ifa_ifwithaddr(sin6tosa(sin6)); - if (ifa == NULL) { + if (ifa == NULL && + (in6p->in6p_flags & IN6P_BINDANY) == 0) { error = EADDRNOTAVAIL; goto out; } Index: src/sys/netinet6/in6_pcb.h diff -u src/sys/netinet6/in6_pcb.h:1.51 src/sys/netinet6/in6_pcb.h:1.52 --- src/sys/netinet6/in6_pcb.h:1.51 Thu Aug 20 17:21:32 2020 +++ src/sys/netinet6/in6_pcb.h Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_pcb.h,v 1.51 2020/08/20 21:21:32 riastradh Exp $ */ +/* $NetBSD: in6_pcb.h,v 1.52 2020/09/08 14:12:57 christos Exp $ */ /* $KAME: in6_pcb.h,v 1.45 2001/02/09 05:59:46 itojun Exp $ */ /* @@ -123,22 +123,22 @@ struct in6pcb { * We define KAME's original flags in higher 16 bits as much as possible * for compatibility with *bsd*s. */ -#define IN6P_RECVOPTS 0x001000 /* receive incoming IP6 options */ -#define IN6P_RECVRETOPTS 0x002000 /* receive IP6 options for reply */ -#define IN6P_RECVDSTADDR 0x004000 /* receive IP6 dst address */ -#define IN6P_IPV6_V6ONLY 0x008000 /* restrict AF_INET6 socket for v6 */ -#define IN6P_PKTINFO 0x010000 /* receive IP6 dst and I/F */ -#define IN6P_HOPLIMIT 0x020000 /* receive hoplimit */ -#define IN6P_HOPOPTS 0x040000 /* receive hop-by-hop options */ -#define IN6P_DSTOPTS 0x080000 /* receive dst options after rthdr */ -#define IN6P_RTHDR 0x100000 /* receive routing header */ -#define IN6P_RTHDRDSTOPTS 0x200000 /* receive dstoptions before rthdr */ -#define IN6P_TCLASS 0x400000 /* traffic class */ - -#define IN6P_HIGHPORT 0x1000000 /* user wants "high" port binding */ -#define IN6P_LOWPORT 0x2000000 /* user wants "low" port binding */ -#define IN6P_ANONPORT 0x4000000 /* port chosen for user */ -#define IN6P_FAITH 0x8000000 /* accept FAITH'ed connections */ +#define IN6P_RECVOPTS 0x00001000 /* receive incoming IP6 options */ +#define IN6P_RECVRETOPTS 0x00002000 /* receive IP6 options for reply */ +#define IN6P_RECVDSTADDR 0x00004000 /* receive IP6 dst address */ +#define IN6P_IPV6_V6ONLY 0x00008000 /* restrict AF_INET6 socket for v6 */ +#define IN6P_PKTINFO 0x00010000 /* receive IP6 dst and I/F */ +#define IN6P_HOPLIMIT 0x00020000 /* receive hoplimit */ +#define IN6P_HOPOPTS 0x00040000 /* receive hop-by-hop options */ +#define IN6P_DSTOPTS 0x00080000 /* receive dst options after rthdr */ +#define IN6P_RTHDR 0x00100000 /* receive routing header */ +#define IN6P_RTHDRDSTOPTS 0x00200000 /* receive dstoptions before rthdr */ +#define IN6P_TCLASS 0x00400000 /* traffic class */ +#define IN6P_BINDANY 0x00800000 /* allow bind to any address */ +#define IN6P_HIGHPORT 0x01000000 /* user wants "high" port binding */ +#define IN6P_LOWPORT 0x02000000 /* user wants "low" port binding */ +#define IN6P_ANONPORT 0x04000000 /* port chosen for user */ +#define IN6P_FAITH 0x08000000 /* accept FAITH'ed connections */ /* XXX should move to an UDP control block */ #define IN6P_ESPINUDP INP_ESPINUDP /* ESP over UDP for NAT-T */ Index: src/sys/netinet6/ip6_output.c diff -u src/sys/netinet6/ip6_output.c:1.225 src/sys/netinet6/ip6_output.c:1.226 --- src/sys/netinet6/ip6_output.c:1.225 Fri Aug 28 02:32:24 2020 +++ src/sys/netinet6/ip6_output.c Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_output.c,v 1.225 2020/08/28 06:32:24 ozaki-r Exp $ */ +/* $NetBSD: ip6_output.c,v 1.226 2020/09/08 14:12:57 christos Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.225 2020/08/28 06:32:24 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.226 2020/09/08 14:12:57 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1377,6 +1377,7 @@ ip6_ctloutput(int op, struct socket *so, case IPV6_RECVPATHMTU: case IPV6_RECVTCLASS: case IPV6_V6ONLY: + case IPV6_BINDANY: error = sockopt_getint(sopt, &optval); if (error) break; @@ -1529,6 +1530,7 @@ else \ OPTSET(IN6P_IPV6_V6ONLY); #endif break; + case IPV6_RECVTCLASS: #ifdef RFC2292 /* cannot mix with RFC2292 XXX */ @@ -1540,6 +1542,15 @@ else \ OPTSET(IN6P_TCLASS); break; + case IPV6_BINDANY: + error = kauth_authorize_network( + kauth_cred_get(), KAUTH_NETWORK_BIND, + KAUTH_REQ_NETWORK_BIND_ANYADDR, so, NULL, + NULL); + if (error) + break; + OPTSET(IN6P_BINDANY); + break; } break; @@ -1756,6 +1767,7 @@ else \ case IPV6_V6ONLY: case IPV6_PORTRANGE: case IPV6_RECVTCLASS: + case IPV6_BINDANY: switch (optname) { case IPV6_RECVHOPOPTS: @@ -1814,7 +1826,11 @@ else \ optval = OPTBIT(IN6P_TCLASS); break; + case IPV6_BINDANY: + optval = OPTBIT(IN6P_BINDANY); + break; } + if (error) break; error = sockopt_setint(sopt, optval); Index: src/sys/secmodel/suser/secmodel_suser.c diff -u src/sys/secmodel/suser/secmodel_suser.c:1.54 src/sys/secmodel/suser/secmodel_suser.c:1.55 --- src/sys/secmodel/suser/secmodel_suser.c:1.54 Sat May 16 15:12:38 2020 +++ src/sys/secmodel/suser/secmodel_suser.c Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: secmodel_suser.c,v 1.54 2020/05/16 19:12:38 alnsn Exp $ */ +/* $NetBSD: secmodel_suser.c,v 1.55 2020/09/08 14:12:57 christos Exp $ */ /*- * Copyright (c) 2006 Elad Efrat <e...@netbsd.org> * All rights reserved. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.54 2020/05/16 19:12:38 alnsn Exp $"); +__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.55 2020/09/08 14:12:57 christos Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -599,6 +599,7 @@ secmodel_suser_network_cb(kauth_cred_t c switch (req) { case KAUTH_REQ_NETWORK_BIND_PORT: case KAUTH_REQ_NETWORK_BIND_PRIVPORT: + case KAUTH_REQ_NETWORK_BIND_ANYADDR: if (isroot) result = KAUTH_RESULT_ALLOW; break; Index: src/sys/sys/kauth.h diff -u src/sys/sys/kauth.h:1.85 src/sys/sys/kauth.h:1.86 --- src/sys/sys/kauth.h:1.85 Sat May 16 14:31:53 2020 +++ src/sys/sys/kauth.h Tue Sep 8 10:12:57 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: kauth.h,v 1.85 2020/05/16 18:31:53 christos Exp $ */ +/* $NetBSD: kauth.h,v 1.86 2020/09/08 14:12:57 christos Exp $ */ /*- * Copyright (c) 2005, 2006 Elad Efrat <e...@netbsd.org> @@ -311,6 +311,7 @@ enum kauth_network_req { KAUTH_REQ_NETWORK_SMB_VC_ACCESS, KAUTH_REQ_NETWORK_SMB_VC_CREATE, KAUTH_REQ_NETWORK_INTERFACE_FIRMWARE, + KAUTH_REQ_NETWORK_BIND_ANYADDR }; /*