summaryrefslogtreecommitdiffstats
path: root/sys/net/if.c
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2019-04-10 09:51:35 +0000
committerdlg <dlg@openbsd.org>2019-04-10 09:51:35 +0000
commit51887993673bb2d139b5cb1afa518fa2c0b9d763 (patch)
treebdc9c6299c16f4f8c722c2a9b5669ebf90dfb891 /sys/net/if.c
parentadd SIOCGIFSFFPAGE, for getting sfp/qsfp module info from nics. (diff)
downloadwireguard-openbsd-51887993673bb2d139b5cb1afa518fa2c0b9d763.tar.xz
wireguard-openbsd-51887993673bb2d139b5cb1afa518fa2c0b9d763.zip
do custom checks for SIOCGIFSFFPAGE.
this should only be used by root, and it should not tak the NET_LOCK because a bunch of i2c reads can take a relatively long time during which packets would be blocked. while here make sure userland only requests pages from the eeprom and diag i2c addresses. ok deraadt@
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index dadafb649eb..3526e56f535 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.573 2019/03/01 04:47:32 dlg Exp $ */
+/* $OpenBSD: if.c,v 1.574 2019/04/10 09:51:35 dlg Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -144,6 +144,8 @@ int if_detached_ioctl(struct ifnet *, u_long, caddr_t);
int ifioctl_get(u_long, caddr_t);
int ifconf(caddr_t);
+static int
+ if_sffpage_check(const caddr_t);
int if_getgroup(caddr_t, struct ifnet *);
int if_getgroupmembers(caddr_t);
@@ -2143,6 +2145,19 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
NET_UNLOCK();
break;
+ case SIOCGIFSFFPAGE:
+ error = suser(p);
+ if (error != 0)
+ break;
+
+ error = if_sffpage_check(data);
+ if (error != 0)
+ break;
+
+ /* don't take NET_LOCK because i2c reads take a long time */
+ error = ((*ifp->if_ioctl)(ifp, cmd, data));
+ break;
+
case SIOCSETKALIVE:
case SIOCDIFPHYADDR:
case SIOCSLIFPHYADDR:
@@ -2304,6 +2319,22 @@ ifioctl_get(u_long cmd, caddr_t data)
return (error);
}
+static int
+if_sffpage_check(const caddr_t data)
+{
+ const struct if_sffpage *sff = (const struct if_sffpage *)data;
+
+ switch (sff->sff_addr) {
+ case IFSFF_ADDR_EEPROM:
+ case IFSFF_ADDR_DDM:
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
/*
* Return interface configuration
* of system. List may be used