diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2019-04-10 09:51:36 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2019-04-10 09:51:36 +0000 |
commit | 579c07513bb9e4718897ec05bd7bc43dff9b9d31 (patch) | |
tree | 22b261dd57576dc90221e6ac41d28c55d0c02a49 /sys/net/if.c | |
parent | f0a110c5b676c37665bdf854b2740352b4251fd7 (diff) |
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.c | 33 |
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 |