[Midnightbsd-cvs] src [7940] trunk/sys/dev/mfi/mfi.c: Fix panics triggered by older mfiutil binaries run on the new mfi(4) driver.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Wed Sep 14 17:42:08 EDT 2016


Revision: 7940
          http://svnweb.midnightbsd.org/src/?rev=7940
Author:   laffer1
Date:     2016-09-14 17:42:08 -0400 (Wed, 14 Sep 2016)
Log Message:
-----------
Fix panics triggered by older mfiutil binaries run on the new mfi(4) driver.
The new driver changed the size of the mfi_dcmd_frame structure in such a
way that a MFI_IOC_PASSTHRU ioctl from an old amd64 binary is treated as an
MFI_IOC_PASSTHRU32 ioctl in the new driver.  As a result, the user pointer
is treated as the buffer length.  mfi_user_command() doesn't have a bounds
check on the buffer length, so it passes a really big value to malloc()
which panics when it tries to exhaust the kmem_map.  Fix this two ways:
- Only honor MFI_IOC_PASSTHRU32 if the binary has the SV_ILP32 flag set,
  otherwise treat it as an unknown ioctl.
- Add a bounds check on the buffer length passed by the user.  For now
  it fails any user attempts to use a buffer larger than 1MB.

While here, fix a few other nits:
- Remove an unnecessary check for a NULL return from malloc(M_WAITOK).
- Use the ENOTTY errno for invalid ioctl commands instead of ENOENT.

Modified Paths:
--------------
    trunk/sys/dev/mfi/mfi.c

Modified: trunk/sys/dev/mfi/mfi.c
===================================================================
--- trunk/sys/dev/mfi/mfi.c	2016-09-14 21:39:27 UTC (rev 7939)
+++ trunk/sys/dev/mfi/mfi.c	2016-09-14 21:42:08 UTC (rev 7940)
@@ -73,6 +73,7 @@
 #include <sys/uio.h>
 #include <sys/proc.h>
 #include <sys/signalvar.h>
+#include <sys/sysent.h>
 #include <sys/taskqueue.h>
 
 #include <machine/bus.h>
@@ -2932,10 +2933,9 @@
 
 
 	if (ioc->buf_size > 0) {
+		if (ioc->buf_size > 1024 * 1024)
+			return (ENOMEM);
 		ioc_buf = malloc(ioc->buf_size, M_MFIBUF, M_WAITOK);
-		if (ioc_buf == NULL) {
-			return (ENOMEM);
-		}
 		error = copyin(ioc->buf, ioc_buf, ioc->buf_size);
 		if (error) {
 			device_printf(sc->mfi_dev, "failed to copyin\n");
@@ -3344,6 +3344,10 @@
 		}
 #ifdef COMPAT_FREEBSD32
 	case MFIIO_PASSTHRU32:
+		if (!SV_CURPROC_FLAG(SV_ILP32)) {
+			error = ENOTTY;
+			break;
+		}
 		iop_swab.ioc_frame	= iop32->ioc_frame;
 		iop_swab.buf_size	= iop32->buf_size;
 		iop_swab.buf		= PTRIN(iop32->buf);
@@ -3359,7 +3363,7 @@
 		break;
 	default:
 		device_printf(sc->mfi_dev, "IOCTL 0x%lx not handled\n", cmd);
-		error = ENOENT;
+		error = ENOTTY;
 		break;
 	}
 



More information about the Midnightbsd-cvs mailing list