Source-Changes-HG archive

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

[src/trunk]: src/external/bsd/blacklist/bin Handle fds that are pointing to r...



details:   https://anonhg.NetBSD.org/src/rev/dec814e1148c
branches:  trunk
changeset: 970100:dec814e1148c
user:      christos <christos%NetBSD.org@localhost>
date:      Thu Mar 12 19:35:11 2020 +0000

description:
Handle fds that are pointing to routing sockets. If the fd has access to
make changes via the routing socket, grant full permission to make filter
changes.

diffstat:

 external/bsd/blacklist/bin/conf.c |  183 +++++++++++++++++++++++++++----------
 1 files changed, 131 insertions(+), 52 deletions(-)

diffs (truncated from 347 to 300 lines):

diff -r e2c4ff47c976 -r dec814e1148c external/bsd/blacklist/bin/conf.c
--- a/external/bsd/blacklist/bin/conf.c Thu Mar 12 18:08:54 2020 +0000
+++ b/external/bsd/blacklist/bin/conf.c Thu Mar 12 19:35:11 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: conf.c,v 1.28 2020/03/12 11:31:23 roy Exp $    */
+/*     $NetBSD: conf.c,v 1.29 2020/03/12 19:35:11 christos Exp $       */
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: conf.c,v 1.28 2020/03/12 11:31:23 roy Exp $");
+__RCSID("$NetBSD: conf.c,v 1.29 2020/03/12 19:35:11 christos Exp $");
 
 #include <stdio.h>
 #ifdef HAVE_LIBUTIL_H
@@ -46,6 +46,7 @@
 #include <ctype.h>
 #include <inttypes.h>
 #include <netdb.h>
+#include <unistd.h>
 #include <pwd.h>
 #include <syslog.h>
 #include <errno.h>
@@ -55,6 +56,7 @@
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <net/if.h>
+#include <net/route.h>
 #include <sys/socket.h>
 
 #include "bl.h"
@@ -90,7 +92,7 @@
 }
 
 static int
-getnum(const char *f, size_t l, bool local, void *rp, const char *name,
+conf_getnum(const char *f, size_t l, bool local, void *rp, const char *name,
     const char *p)
 {
        int e;
@@ -127,13 +129,14 @@
 }
 
 static int
-getnfail(const char *f, size_t l, bool local, struct conf *c, const char *p)
+conf_getnfail(const char *f, size_t l, bool local, struct conf *c,
+    const char *p)
 {
-       return getnum(f, l, local, &c->c_nfail, "nfail", p);
+       return conf_getnum(f, l, local, &c->c_nfail, "nfail", p);
 }
 
 static int
-getsecs(const char *f, size_t l, bool local, struct conf *c, const char *p)
+conf_getsecs(const char *f, size_t l, bool local, struct conf *c, const char *p)
 {
        int e;
        char *ep;
@@ -193,7 +196,7 @@
 }
 
 static int
-getport(const char *f, size_t l, bool local, void *r, const char *p)
+conf_getport(const char *f, size_t l, bool local, void *r, const char *p)
 {
        struct servent *sv;
 
@@ -207,11 +210,11 @@
                return 0;
        }
 
-       return getnum(f, l, local, r, "service", p);
+       return conf_getnum(f, l, local, r, "service", p);
 }
 
 static int
-getmask(const char *f, size_t l, bool local, const char **p, int *mask)
+conf_getmask(const char *f, size_t l, bool local, const char **p, int *mask)
 {
        char *d;
        const char *s = *p;
@@ -226,11 +229,12 @@
        }
 
        *d++ = '\0';
-       return getnum(f, l, local, mask, "mask", d);
+       return conf_getnum(f, l, local, mask, "mask", d);
 }
 
 static int
-gethostport(const char *f, size_t l, bool local, struct conf *c, const char *p)
+conf_gethostport(const char *f, size_t l, bool local, struct conf *c,
+    const char *p)
 {
        char *d;        // XXX: Ok to write to string.
        in_port_t *port = NULL;
@@ -249,7 +253,7 @@
        } else
                pstr = p;
 
-       if (getmask(f, l, local, &pstr, &c->c_lmask) == -1)
+       if (conf_getmask(f, l, local, &pstr, &c->c_lmask) == -1)
                goto out;
 
        if (d) {
@@ -300,7 +304,7 @@
                }
        }
 
-       if (getport(f, l, local, &c->c_port, pstr) == -1)
+       if (conf_getport(f, l, local, &c->c_port, pstr) == -1)
                return -1;
 
        if (port && c->c_port != FSTAR && c->c_port != FEQUAL)
@@ -320,7 +324,7 @@
 }
 
 static int
-getproto(const char *f, size_t l, bool local __unused, struct conf *c,
+conf_getproto(const char *f, size_t l, bool local __unused, struct conf *c,
     const char *p)
 {
        if (strcmp(p, "stream") == 0) {
@@ -331,22 +335,22 @@
                c->c_proto = IPPROTO_UDP;
                return 0;
        }
-       return getnum(f, l, local, &c->c_proto, "protocol", p);
+       return conf_getnum(f, l, local, &c->c_proto, "protocol", p);
 }
 
 static int
-getfamily(const char *f, size_t l, bool local __unused, struct conf *c,
+conf_getfamily(const char *f, size_t l, bool local __unused, struct conf *c,
     const char *p)
 {
        if (strncmp(p, "tcp", 3) == 0 || strncmp(p, "udp", 3) == 0) {
                c->c_family = p[3] == '6' ? AF_INET6 : AF_INET;
                return 0;
        }
-       return getnum(f, l, local, &c->c_family, "family", p);
+       return conf_getnum(f, l, local, &c->c_family, "family", p);
 }
 
 static int
-getuid(const char *f, size_t l, bool local __unused, struct conf *c,
+conf_getuid(const char *f, size_t l, bool local __unused, struct conf *c,
     const char *p)
 {
        struct passwd *pw;
@@ -356,15 +360,15 @@
                return 0;
        }
 
-       return getnum(f, l, local, &c->c_uid, "user", p);
+       return conf_getnum(f, l, local, &c->c_uid, "user", p);
 }
 
 
 static int
-getname(const char *f, size_t l, bool local, struct conf *c,
+conf_getname(const char *f, size_t l, bool local, struct conf *c,
     const char *p)
 {
-       if (getmask(f, l, local, &p, &c->c_rmask) == -1)
+       if (conf_getmask(f, l, local, &p, &c->c_rmask) == -1)
                return -1;
 
        if (strcmp(p, "*") == 0) {
@@ -407,19 +411,19 @@
                p++;
 
        memset(c, 0, sizeof(*c));
-       e = getvalue(f, l, local, c, &p, gethostport);
+       e = getvalue(f, l, local, c, &p, conf_gethostport);
        if (e) return -1;
-       e = getvalue(f, l, local, c, &p, getproto);
+       e = getvalue(f, l, local, c, &p, conf_getproto);
        if (e) return -1;
-       e = getvalue(f, l, local, c, &p, getfamily);
+       e = getvalue(f, l, local, c, &p, conf_getfamily);
        if (e) return -1;
-       e = getvalue(f, l, local, c, &p, getuid);
+       e = getvalue(f, l, local, c, &p, conf_getuid);
        if (e) return -1;
-       e = getvalue(f, l, local, c, &p, getname);
+       e = getvalue(f, l, local, c, &p, conf_getname);
        if (e) return -1;
-       e = getvalue(f, l, local, c, &p, getnfail);
+       e = getvalue(f, l, local, c, &p, conf_getnfail);
        if (e) return -1;
-       e = getvalue(f, l, local, c, &p, getsecs);
+       e = getvalue(f, l, local, c, &p, conf_getsecs);
        if (e) return -1;
 
        return 0;
@@ -998,11 +1002,93 @@
        return i;
 }
 
+#ifdef AF_ROUTE
+static int
+conf_route_perm(int fd) {
+#if defined(RTM_IFANNOUNCE) && defined(RT_ROUNDUP)
+       /*
+        * Send a routing message that is not supported to check for access
+        * We expect EOPNOTSUPP for having access, since we are sending a
+        * request the system does not understand and EACCES if we don't have
+        * access.
+        */
+       static struct sockaddr_in sin = {
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+               .sin_len = sizeof(sin),
+#endif
+               .sin_family = AF_INET,
+       };
+       char buf[4096];
+       struct rt_msghdr *rtm = (void *)buf;
+       char *cp = (char *)(rtm + 1);
+       size_t l;
+
+#define NEXTADDR(s) \
+       l = RT_ROUNDUP(sizeof(*s)); memmove(cp, s, l); cp += l;
+       memset(buf, 0, sizeof(buf));
+       rtm->rtm_type = RTM_IFANNOUNCE;
+       rtm->rtm_flags = 0;
+       rtm->rtm_addrs = RTA_DST|RTA_GATEWAY;
+       rtm->rtm_version = RTM_VERSION;
+       rtm->rtm_seq = 666;
+       NEXTADDR(&sin);
+       NEXTADDR(&sin);
+       rtm->rtm_msglen = (u_short)((char *)cp - (char *)rtm);
+       if (write(fd, rtm, rtm->rtm_msglen) != -1) {
+               (*lfun)(LOG_ERR, "Writing to routing socket succeeded!");
+               return 0;
+       }
+       switch (errno) {
+       case EACCES:
+               return 0;
+       case EOPNOTSUPP:
+               return 1;
+       default:
+               (*lfun)(LOG_ERR,
+                   "Unexpected error writing to routing socket (%m)");
+               return 0;
+       }
+#else
+       return 0;
+#endif
+}
+#endif
+
+static int
+conf_handle_inet(int fd, const void *lss, struct conf *cr)
+{
+       char buf[BUFSIZ];
+       int proto;
+       socklen_t slen = sizeof(proto);
+
+       if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &proto, &slen) == -1) {
+               (*lfun)(LOG_ERR, "getsockopt failed (%m)");
+               return -1;
+       }
+
+       if (debug) {
+               sockaddr_snprintf(buf, sizeof(buf), "%a:%p", lss);
+               (*lfun)(LOG_DEBUG, "listening socket: %s", buf);
+       }
+
+       switch (proto) {
+       case SOCK_STREAM:
+               cr->c_proto = IPPROTO_TCP;
+               break;
+       case SOCK_DGRAM:
+               cr->c_proto = IPPROTO_UDP;
+               break;
+       default:
+               (*lfun)(LOG_ERR, "unsupported protocol %d", proto);
+               return -1;
+       }
+       return 0;
+}
+
 const struct conf *
 conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss,
     struct conf *cr)
 {
-       int proto;
        socklen_t slen;
        struct sockaddr_storage lss;
        size_t i;
@@ -1016,36 +1102,29 @@
                return NULL;
        }
 
-       slen = sizeof(proto);
-       if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &proto, &slen) == -1) {



Home | Main Index | Thread Index | Old Index