Fix ISP_FC_LIP and ISP_RESCAN on big-endian 64-bit systems.

For _IO() ioctls, addr is a pointer to uap->data which is a caddr_t.
When the caddr_t stores an int, dereferencing addr as an (int *) results
in truncation on little-endian 64-bit systems and corruption (owing to
extracting top bits) on big-endian 64-bit systems. In practice the
value of chan was probably always zero on systems of the latter type as
all such FreeBSD platforms use a register-based calling convention.

Reviewed by:	mav
Obtained from:	CheriBSD
MFC after:	1 week
Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D14673
This commit is contained in:
Brooks Davis 2018-03-13 19:56:10 +00:00
parent cd1fd29c26
commit 8037cdcd9a

View File

@ -444,7 +444,7 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
case ISP_RESCAN:
if (IS_FC(isp)) {
chan = *(int *)addr;
chan = *(intptr_t *)addr;
if (chan < 0 || chan >= isp->isp_nchan) {
retval = -ENXIO;
break;
@ -461,7 +461,7 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
case ISP_FC_LIP:
if (IS_FC(isp)) {
chan = *(int *)addr;
chan = *(intptr_t *)addr;
if (chan < 0 || chan >= isp->isp_nchan) {
retval = -ENXIO;
break;