]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/commit
MFC 338408: Don't directly dereference a user pointer in the VPD ioctl.
authorjhb <jhb@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Tue, 30 Oct 2018 21:31:32 +0000 (21:31 +0000)
committerjhb <jhb@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Tue, 30 Oct 2018 21:31:32 +0000 (21:31 +0000)
commitd221757e1e74da3b4e1792cf744191aa227c1ce7
tree00789a1da672316d75afee8675b47ea583238511
parent82cd85fd0dbdb5f33e71405d5e3e0fa844a6c659
MFC 338408: Don't directly dereference a user pointer in the VPD ioctl.

The PCIOCLISTVPD ioctl on /dev/pci is used to fetch a list of VPD
key-value pairs for a specific PCI function.  It is used by
'pciconf -l -V'.  The list is stored in a userland-supplied buffer as
an array of variable-length structures where the key and data length
are stored in a fixed-size header followed by the variable-length
value as a byte array.  To facilitate walking this array in userland,
<sys/pciio.h> provides a PVE_NEXT() helper macro to return a pointer
to the next array element by reading the the length out of the current
header and using it to compute the address of the next header.

To simplify the implementation, the ioctl handler was also using
PVE_NEXT() when on the user address of the user buffer to compute the
user address of the next array element.  However, the PVE_NEXT() macro
when used with a user address was reading the value's length by
indirecting the user pointer.  The value was ready after the current
record had been copied out to the user buffer, so it appeared to work
on architectures where user addresses are directly dereferencable from
the kernel (all but powerpc and i386 after the 4:4 split).  The recent
enablement of SMAP on amd64 caught this violation however.  To fix,
add a variant of PVE_NEXT() for use in the ioctl handler that takes an
explicit value length.

git-svn-id: svn://svn.freebsd.org/base/stable/10@339932 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
sys/dev/pci/pci_user.c