Date: Mon, 11 Oct 2010 21:38:31 +0000 (UTC) From: Matthew D Fleming <mdf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r213704 - head/sys/dev/mps Message-ID: <201010112138.o9BLcVIZ028265@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mdf Date: Mon Oct 11 21:38:31 2010 New Revision: 213704 URL: http://svn.freebsd.org/changeset/base/213704 Log: Fix a memory leak and locking inconsistency in mps(4) ioctl handling. Check copyin(9) for error and sanity check the length before copyin. Reviewed by: ken Modified: head/sys/dev/mps/mps_user.c Modified: head/sys/dev/mps/mps_user.c ============================================================================== --- head/sys/dev/mps/mps_user.c Mon Oct 11 21:34:35 2010 (r213703) +++ head/sys/dev/mps/mps_user.c Mon Oct 11 21:38:31 2010 (r213704) @@ -343,7 +343,7 @@ mps_user_command(struct mps_softc *sc, s MPI2_REQUEST_HEADER *hdr; MPI2_DEFAULT_REPLY *rpl; MPI2_SGE_IO_UNION *sgl; - void *buf; + void *buf = NULL; struct mps_command *cm; int err = 0; int sz; @@ -363,7 +363,13 @@ mps_user_command(struct mps_softc *sc, s mps_dprint(sc, MPS_INFO, "mps_user_command: req %p %d rpl %p %d\n", cmd->req, cmd->req_len, cmd->rpl, cmd->rpl_len ); - copyin(cmd->req, hdr, cmd->req_len); + if (cmd->req_len > (int)sc->facts->IOCRequestFrameSize * 4) { + err = EINVAL; + goto RetFreeUnlocked; + } + err = copyin(cmd->req, hdr, cmd->req_len); + if (err != 0) + goto RetFreeUnlocked; mps_dprint(sc, MPS_INFO, "mps_user_command: Function %02X " "MsgFlags %02X\n", hdr->Function, hdr->MsgFlags ); @@ -372,7 +378,7 @@ mps_user_command(struct mps_softc *sc, s if (err != 0) { mps_printf(sc, "mps_user_command: unsupported function 0x%X\n", hdr->Function ); - goto RetFree; + goto RetFreeUnlocked; } if (cmd->len > 0) { @@ -380,7 +386,6 @@ mps_user_command(struct mps_softc *sc, s cm->cm_data = buf; cm->cm_length = cmd->len; } else { - buf = NULL; cm->cm_data = NULL; cm->cm_length = 0; } @@ -412,20 +417,27 @@ mps_user_command(struct mps_softc *sc, s mps_unlock(sc); copyout(rpl, cmd->rpl, sz); - if (buf != NULL) { + if (buf != NULL) copyout(buf, cmd->buf, cmd->len); - free(buf, M_MPSUSER); - } mps_lock(sc); mps_dprint(sc, MPS_INFO, "mps_user_command: reply size %d\n", sz ); -RetFree: mps_free_command(sc, cm); - Ret: mps_unlock(sc); - return err; + if (buf != NULL) + free(buf, M_MPSUSER); + return (err); + +RetFreeUnlocked: + mps_lock(sc); + mps_free_command(sc, cm); + mps_unlock(sc); + + if (buf != NULL) + free(buf, M_MPSUSER); + return (err); } static int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010112138.o9BLcVIZ028265>