changeset 5246:52a4070231c6 draft

privsep: Filter ioctls to a known list. In-case the master process is broken into.
author Roy Marples <roy@marples.name>
date Wed, 20 May 2020 18:14:38 +0100
parents 05b76a4875e0
children 30906bee600b
files src/privsep-bsd.c src/privsep-root.c
diffstat 2 files changed, 68 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/privsep-bsd.c	Wed May 20 17:37:21 2020 +0100
+++ b/src/privsep-bsd.c	Wed May 20 18:14:38 2020 +0100
@@ -28,6 +28,12 @@
 
 #include <sys/ioctl.h>
 
+/* Need these for filtering the ioctls */
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
@@ -41,6 +47,38 @@
 {
 	int s, err;
 
+	/* Only allow these ioctls */
+	switch(req) {
+#ifdef SIOCIFAFATTACH
+	case SIOCIFAFATTACH:	/* FALLTHROUGH */
+#endif
+#ifdef SIOCSIFXFLAGS
+	case SIOCSIFXFLAGS:	/* FALLTHROUGH */
+#endif
+#ifdef SIOCSIFINFO_FLAGS
+	case SIOCSIFINFO_FLAGS:	/* FALLTHROUGH */
+#endif
+#ifdef SIOCSRTRFLUSH_IN6
+	case SIOCSRTRFLUSH_IN6:	/* FALLTHROUGH */
+	case SIOCSPFXFLUSH_IN6: /* FALLTHROUGH */
+#endif
+#if defined(SIOCALIFADDR) && defined(IFLR_ACTIVE)
+	case SIOCALIFADDR:	/* FALLTHROUGH */
+	case SIOCDLIFADDR:	/* FALLTHROUGH */
+#else
+	case SIOCSIFLLADDR:	/* FALLTHROUGH */
+#endif
+#ifdef SIOCSIFINFO_IN6
+	case SIOCSIFINFO_IN6:	/* FALLTHROUGH */
+#endif
+	case SIOCAIFADDR_IN6:	/* FALLTHROUGH */
+	case SIOCDIFADDR_IN6:	/* FALLTHROUGH */
+		break;
+	default:
+		errno = EPERM;
+		return -1;
+	}
+
 	s = socket(domain, SOCK_DGRAM, 0);
 	if (s == -1)
 		return -1;
@@ -73,6 +111,15 @@
 	struct ifreq ifr = { .ifr_flags = 0 };
 	ssize_t err;
 
+	switch(req) {
+	case SIOCG80211NWID:	/* FALLTHROUGH */
+	case SIOCGETVLAN:
+		break;
+	default:
+		errno =	EPERM;
+		return -1;
+	}
+
 	if (len < IFNAMSIZ) {
 		errno = EINVAL;
 		return -1;
--- a/src/privsep-root.c	Wed May 20 17:37:21 2020 +0100
+++ b/src/privsep-root.c	Wed May 20 18:14:38 2020 +0100
@@ -215,6 +215,27 @@
 {
 	int s, err;
 
+	/* Only allow these ioctls */
+	switch(req) {
+#ifdef SIOCAIFADDR
+	case SIOCAIFADDR:	/* FALLTHROUGH */
+	case SIOCDIFADDR:	/* FALLTHROUGH */
+#endif
+#ifdef SIOCSIFHWADDR
+	case SIOCSIFHWADDR:	/* FALLTHROUGH */
+#endif
+#ifdef SIOCGIFPRIORITY
+	case SIOCGIFPRIORITY:	/* FALLTHROUGH */
+#endif
+	case SIOCSIFFLAGS:	/* FALLTHROUGH */
+	case SIOCGIFMTU:	/* FALLTHROUGH */
+	case SIOCSIFMTU:
+		break;
+	default:
+		errno = EPERM;
+		return -1;
+	}
+
 	s = socket(PF_INET, SOCK_DGRAM, 0);
 	if (s != -1)
 #ifdef IOCTL_REQUEST_TYPE