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.

MFC after:	1 week
Found by:	jau@iki.fi
PR:		223767
Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2017-11-29 09:40:11 +00:00
parent 2404b5d277
commit fa3f256682
4 changed files with 22 additions and 6 deletions

View File

@ -1,7 +1,7 @@
.\" $FreeBSD$
.\" Based on PR#2411
.\"
.Dd April 10, 2015
.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

View File

@ -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

View File

@ -737,9 +737,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;

View File

@ -676,9 +676,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;