From 6a5f0fc1d4afb92d9f2b70ad8f47b054caa6555b Mon Sep 17 00:00:00 2001 From: hselasky Date: Fri, 8 Dec 2017 15:30:59 +0000 Subject: [PATCH] MFC r326362: Disallow TUN and TAP character device IOCTLs to modify the network device type to any value. This can cause page faults and panics due to accessing uninitialized fields in the "struct ifnet" which are specific to the network device type. Found by: jau@iki.fi PR: 223767 Sponsored by: Mellanox Technologies git-svn-id: svn://svn.freebsd.org/base/stable/9@326693 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- share/man/man4/tap.4 | 11 +++++++++-- share/man/man4/tun.4 | 11 +++++++++-- sys/net/if_tap.c | 3 ++- sys/net/if_tun.c | 3 ++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/share/man/man4/tap.4 b/share/man/man4/tap.4 index 229de6028..89defdaae 100644 --- a/share/man/man4/tap.4 +++ b/share/man/man4/tap.4 @@ -1,7 +1,7 @@ .\" $FreeBSD$ .\" Based on PR#2411 .\" -.Dd November 30, 2014 +.Dd November 29, 2017 .Dt TAP 4 .Os .Sh NAME @@ -171,7 +171,14 @@ calls are supported .In net/if_tap.h ) : .Bl -tag -width VMIO_SIOCSETMACADDR .It Dv TAPSIFINFO -Set network interface information (line speed, MTU and type). +Set network interface information (line speed and MTU). +The type must be the same as returned by +.Dv TAPGIFINFO +or set to +.Dv IFT_ETHER +else the +.Xr ioctl 2 +call will fail. The argument should be a pointer to a .Va struct tapinfo . .It Dv TAPGIFINFO diff --git a/share/man/man4/tun.4 b/share/man/man4/tun.4 index 0b88b7213..4e58eb825 100644 --- a/share/man/man4/tun.4 +++ b/share/man/man4/tun.4 @@ -2,7 +2,7 @@ .\" $FreeBSD$ .\" Based on PR#2411 .\" -.Dd November 30, 2014 +.Dd November 29, 2017 .Dt TUN 4 .Os .Sh NAME @@ -208,8 +208,15 @@ this stores the internal debugging variable's value into it. .It Dv TUNSIFINFO The argument should be a pointer to an .Vt struct tuninfo -and allows setting the MTU, the type, and the baudrate of the tunnel +and allows setting the MTU and the baudrate of the tunnel device. +The type must be the same as returned by +.Dv TUNGIFINFO +or set to +.Dv IFT_PPP +else the +.Xr ioctl 2 +call will fail. The .Vt struct tuninfo is declared in diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c index 3d1a30979..8adaf665e 100644 --- a/sys/net/if_tap.c +++ b/sys/net/if_tap.c @@ -731,9 +731,10 @@ tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td switch (cmd) { case TAPSIFINFO: tapp = (struct tapinfo *)data; + if (ifp->if_type != tapp->type) + return (EPROTOTYPE); mtx_lock(&tp->tap_mtx); ifp->if_mtu = tapp->mtu; - ifp->if_type = tapp->type; ifp->if_baudrate = tapp->baudrate; mtx_unlock(&tp->tap_mtx); break; diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 16ea96806..8d6151ff2 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -685,9 +685,10 @@ tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, if (error) return (error); } + if (TUN2IFP(tp)->if_type != tunp->type) + return (EPROTOTYPE); mtx_lock(&tp->tun_mtx); TUN2IFP(tp)->if_mtu = tunp->mtu; - TUN2IFP(tp)->if_type = tunp->type; TUN2IFP(tp)->if_baudrate = tunp->baudrate; mtx_unlock(&tp->tun_mtx); break; -- 2.42.0