diff options
| author | Roy Marples <roy@marples.name> | 2020-05-20 18:14:38 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2020-05-20 18:14:38 +0100 |
| commit | 57b2db8ffc9e88d303e2c140e07be79aa45a35ce (patch) | |
| tree | d54c187e7337494e883a7ceb3381933dd0039a42 | |
| parent | ce1f59bef3420015ae06ff8f7c04c8f56c320c90 (diff) | |
| download | dhcpcd-57b2db8ffc9e88d303e2c140e07be79aa45a35ce.tar.xz | |
privsep: Filter ioctls to a known list.
In-case the master process is broken into.
| -rw-r--r-- | src/privsep-bsd.c | 47 | ||||
| -rw-r--r-- | src/privsep-root.c | 21 |
2 files changed, 68 insertions, 0 deletions
diff --git a/src/privsep-bsd.c b/src/privsep-bsd.c index d714eee4..e73984e4 100644 --- a/src/privsep-bsd.c +++ b/src/privsep-bsd.c @@ -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 @@ ps_root_doioctldom(int domain, unsigned long req, void *data, size_t len) { 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 @@ ps_root_doindirectioctl(unsigned long req, void *data, size_t len) 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; diff --git a/src/privsep-root.c b/src/privsep-root.c index f511a43f..8232a532 100644 --- a/src/privsep-root.c +++ b/src/privsep-root.c @@ -215,6 +215,27 @@ ps_root_doioctl(unsigned long req, void *data, size_t len) { 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 |
