git: b73612a34259 - main - blacklistd: Handle fds that are pointing to routing sockets
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 02 Nov 2023 18:53:00 UTC
The branch main has been updated by emaste:
URL: https://cgit.FreeBSD.org/src/commit/?id=b73612a34259a478c53eab408362d7bf879fefa6
commit b73612a34259a478c53eab408362d7bf879fefa6
Author: Jose Luis Duran <jlduran@gmail.com>
AuthorDate: 2022-10-12 16:14:44 +0000
Commit: Ed Maste <emaste@FreeBSD.org>
CommitDate: 2023-11-02 18:52:40 +0000
blacklistd: 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.
Obtained from: https://github.com/zoulasc/blocklist/commit/1b9475b2c8e0be2b9adc4d88e521ed488ac3c43c
---
contrib/blacklist/bin/conf.c | 113 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 95 insertions(+), 18 deletions(-)
diff --git a/contrib/blacklist/bin/conf.c b/contrib/blacklist/bin/conf.c
index 6eadf6b2ac8c..8f7e75a56be1 100644
--- a/contrib/blacklist/bin/conf.c
+++ b/contrib/blacklist/bin/conf.c
@@ -46,6 +46,7 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $");
#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 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $");
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
+#include <net/route.h>
#include <sys/socket.h>
#include "bl.h"
@@ -1000,32 +1002,72 @@ confset_match(const struct confset *cs, struct conf *c,
return i;
}
-const struct conf *
-conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss,
- struct conf *cr)
+#ifdef AF_ROUTE
+static int
+conf_route_perm(int fd) {
+#if defined(RTM_IFANNOUNCE) && defined(SA_SIZE)
+ /*
+ * 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 = SA_SIZE(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)
{
- int proto;
- socklen_t slen;
- struct sockaddr_storage lss;
- size_t i;
char buf[BUFSIZ];
+ int proto;
+ socklen_t slen = sizeof(proto);
- memset(cr, 0, sizeof(*cr));
- slen = sizeof(lss);
- memset(&lss, 0, slen);
- if (getsockname(fd, (void *)&lss, &slen) == -1) {
- (*lfun)(LOG_ERR, "getsockname failed (%m)");
- return NULL;
- }
-
- slen = sizeof(proto);
if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &proto, &slen) == -1) {
(*lfun)(LOG_ERR, "getsockopt failed (%m)");
- return NULL;
+ return -1;
}
if (debug) {
- sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (void *)&lss);
+ sockaddr_snprintf(buf, sizeof(buf), "%a:%p", lss);
(*lfun)(LOG_DEBUG, "listening socket: %s", buf);
}
@@ -1038,16 +1080,51 @@ conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss,
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)
+{
+ socklen_t slen;
+ struct sockaddr_storage lss;
+ size_t i;
+ char buf[BUFSIZ];
+
+ memset(cr, 0, sizeof(*cr));
+ slen = sizeof(lss);
+ memset(&lss, 0, slen);
+ if (getsockname(fd, (void *)&lss, &slen) == -1) {
+ (*lfun)(LOG_ERR, "getsockname failed (%m)");
return NULL;
}
switch (lss.ss_family) {
case AF_INET:
cr->c_port = ntohs(((struct sockaddr_in *)&lss)->sin_port);
+ if (conf_handle_inet(fd, &lss, cr) == -1)
+ return NULL;
break;
case AF_INET6:
cr->c_port = ntohs(((struct sockaddr_in6 *)&lss)->sin6_port);
+ if (conf_handle_inet(fd, &lss, cr) == -1)
+ return NULL;
break;
+#ifdef AF_ROUTE
+ case AF_ROUTE:
+ if (!conf_route_perm(fd)) {
+ (*lfun)(LOG_ERR,
+ "permission denied to routing socket (%m)");
+ return NULL;
+ }
+ cr->c_proto = FSTAR;
+ cr->c_port = FSTAR;
+ memcpy(&lss, rss, sizeof(lss));
+ break;
+#endif
default:
(*lfun)(LOG_ERR, "unsupported family %d", lss.ss_family);
return NULL;