From owner-svn-src-head@FreeBSD.ORG Tue Jul 3 16:12:58 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 77D3D1065672; Tue, 3 Jul 2012 16:12:58 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4BD358FC17; Tue, 3 Jul 2012 16:12:58 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q63GCwgX055474; Tue, 3 Jul 2012 16:12:58 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q63GCwKv055472; Tue, 3 Jul 2012 16:12:58 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201207031612.q63GCwKv055472@svn.freebsd.org> From: John Baldwin Date: Tue, 3 Jul 2012 16:12:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r238077 - head/sys/dev/mfi X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Jul 2012 16:12:58 -0000 Author: jhb Date: Tue Jul 3 16:12:57 2012 New Revision: 238077 URL: http://svn.freebsd.org/changeset/base/238077 Log: 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. MFC after: 3 days Modified: head/sys/dev/mfi/mfi.c Modified: head/sys/dev/mfi/mfi.c ============================================================================== --- head/sys/dev/mfi/mfi.c Tue Jul 3 15:54:20 2012 (r238076) +++ head/sys/dev/mfi/mfi.c Tue Jul 3 16:12:57 2012 (r238077) @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -2832,10 +2833,9 @@ mfi_user_command(struct mfi_softc *sc, s if (ioc->buf_size > 0) { - ioc_buf = malloc(ioc->buf_size, M_MFIBUF, M_WAITOK); - if (ioc_buf == NULL) { + if (ioc->buf_size > 1024 * 1024) return (ENOMEM); - } + ioc_buf = malloc(ioc->buf_size, M_MFIBUF, M_WAITOK); error = copyin(ioc->buf, ioc_buf, ioc->buf_size); if (error) { device_printf(sc->mfi_dev, "failed to copyin\n"); @@ -3244,6 +3244,10 @@ out: } #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); @@ -3259,7 +3263,7 @@ out: break; default: device_printf(sc->mfi_dev, "IOCTL 0x%lx not handled\n", cmd); - error = ENOENT; + error = ENOTTY; break; }