Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/sys Add IP_BINDANY, IPV6_BINDANY which can be used to bi...



details:   https://anonhg.NetBSD.org/src/rev/bd2802c0ad6c
branches:  trunk
changeset: 938443:bd2802c0ad6c
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Sep 08 14:12:57 2020 +0000

description:
Add IP_BINDANY, IPV6_BINDANY which can be used to bind to any address in
order to implement transparent proxies.

diffstat:

 share/man/man4/ip.4                 |  21 +++++++++++++++++++--
 share/man/man4/ip6.4                |  19 +++++++++++++++++--
 sys/netinet/in.h                    |   4 ++--
 sys/netinet/in_pcb.c                |  17 +++++++++++------
 sys/netinet/in_pcb.h                |   6 ++++--
 sys/netinet/ip_output.c             |  34 +++++++++++++++++++++++++---------
 sys/netinet/raw_ip.c                |   5 +++--
 sys/netinet6/in6.h                  |   3 ++-
 sys/netinet6/in6_pcb.c              |  10 ++++++----
 sys/netinet6/in6_pcb.h              |  34 +++++++++++++++++-----------------
 sys/netinet6/ip6_output.c           |  20 ++++++++++++++++++--
 sys/secmodel/suser/secmodel_suser.c |   5 +++--
 sys/sys/kauth.h                     |   3 ++-
 13 files changed, 129 insertions(+), 52 deletions(-)

diffs (truncated from 539 to 300 lines):

diff -r e6f3766be5ea -r bd2802c0ad6c share/man/man4/ip.4
--- a/share/man/man4/ip.4       Tue Sep 08 13:28:51 2020 +0000
+++ b/share/man/man4/ip.4       Tue Sep 08 14:12:57 2020 +0000
@@ -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 @@
 .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
diff -r e6f3766be5ea -r bd2802c0ad6c share/man/man4/ip6.4
--- a/share/man/man4/ip6.4      Tue Sep 08 13:28:51 2020 +0000
+++ b/share/man/man4/ip6.4      Tue Sep 08 14:12:57 2020 +0000
@@ -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
 .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
diff -r e6f3766be5ea -r bd2802c0ad6c sys/netinet/in.h
--- a/sys/netinet/in.h  Tue Sep 08 13:28:51 2020 +0000
+++ b/sys/netinet/in.h  Tue Sep 08 14:12:57 2020 +0000
@@ -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 @@
 #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 */
 
 /*
diff -r e6f3766be5ea -r bd2802c0ad6c sys/netinet/in_pcb.c
--- a/sys/netinet/in_pcb.c      Tue Sep 08 13:28:51 2020 +0000
+++ b/sys/netinet/in_pcb.c      Tue Sep 08 14:12:57 2020 +0000
@@ -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 @@
 }
 
 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 @@
                        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 @@
 {
        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 @@
                }
                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 @@
                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;
        }
 
diff -r e6f3766be5ea -r bd2802c0ad6c sys/netinet/in_pcb.h
--- a/sys/netinet/in_pcb.h      Tue Sep 08 13:28:51 2020 +0000
+++ b/sys/netinet/in_pcb.h      Tue Sep 08 14:12:57 2020 +0000
@@ -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 @@
                                         */
 #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 @@
 
 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 *);
diff -r e6f3766be5ea -r bd2802c0ad6c sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c   Tue Sep 08 13:28:51 2020 +0000
+++ b/sys/netinet/ip_output.c   Tue Sep 08 14:12:57 2020 +0000
@@ -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 @@
                case IP_RECVIF:
                case IP_RECVPKTINFO:
                case IP_RECVTTL:
+               case IP_BINDANY:
                        error = sockopt_getint(sopt, &optval);
                        if (error)
                                break;
@@ -1168,6 +1169,16 @@
                        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 @@
                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 @@
                        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 @@
 }
 
 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 @@
        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 @@
                        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 @@
                        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;
diff -r e6f3766be5ea -r bd2802c0ad6c sys/netinet/raw_ip.c
--- a/sys/netinet/raw_ip.c      Tue Sep 08 13:28:51 2020 +0000
+++ b/sys/netinet/raw_ip.c      Tue Sep 08 14:12:57 2020 +0000



Home | Main Index | Thread Index | Old Index