Date: Wed, 14 Mar 2018 09:57:58 +0000 (UTC) From: Tijl Coosemans <tijl@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r330926 - in stable/11/sys/cam: . scsi Message-ID: <201803140957.w2E9vwxO038725@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tijl Date: Wed Mar 14 09:57:58 2018 New Revision: 330926 URL: https://svnweb.freebsd.org/changeset/base/330926 Log: MFC r314624: Reject userland CCBs that have CAM_UNLOCKED set. CAM_UNLOCKED is internal flag and cannot correctly be set by userland. Return EINVAL from CAMIOCOMMAND and CAMIOQUEUE if it is set. Also fix leaks in some of the error paths for CAMIOQUEUE. PR: 215356 Modified: stable/11/sys/cam/cam_xpt.c stable/11/sys/cam/scsi/scsi_pass.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/cam/cam_xpt.c ============================================================================== --- stable/11/sys/cam/cam_xpt.c Wed Mar 14 09:20:03 2018 (r330925) +++ stable/11/sys/cam/cam_xpt.c Wed Mar 14 09:57:58 2018 (r330926) @@ -414,6 +414,9 @@ xptdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, inccb = (union ccb *)addr; + if (inccb->ccb_h.flags & CAM_UNLOCKED) + return (EINVAL); + bus = xpt_find_bus(inccb->ccb_h.path_id); if (bus == NULL) return (EINVAL); Modified: stable/11/sys/cam/scsi/scsi_pass.c ============================================================================== --- stable/11/sys/cam/scsi/scsi_pass.c Wed Mar 14 09:20:03 2018 (r330925) +++ stable/11/sys/cam/scsi/scsi_pass.c Wed Mar 14 09:57:58 2018 (r330926) @@ -1798,6 +1798,11 @@ passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr inccb = (union ccb *)addr; + if (inccb->ccb_h.flags & CAM_UNLOCKED) { + error = EINVAL; + break; + } + /* * Some CCB types, like scan bus and scan lun can only go * through the transport layer device. @@ -1891,20 +1896,23 @@ passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr xpt_print(periph->path, "Copy of user CCB %p to " "kernel address %p failed with error %d\n", *user_ccb, ccb, error); - uma_zfree(softc->pass_zone, io_req); - cam_periph_lock(periph); - break; + goto camioqueue_error; } + if (ccb->ccb_h.flags & CAM_UNLOCKED) { + error = EINVAL; + goto camioqueue_error; + } + if (ccb->ccb_h.flags & CAM_CDB_POINTER) { if (ccb->csio.cdb_len > IOCDBLEN) { error = EINVAL; - break; + goto camioqueue_error; } error = copyin(ccb->csio.cdb_io.cdb_ptr, ccb->csio.cdb_io.cdb_bytes, ccb->csio.cdb_len); - if (error) - break; + if (error != 0) + goto camioqueue_error; ccb->ccb_h.flags &= ~CAM_CDB_POINTER; } @@ -1916,10 +1924,8 @@ passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr xpt_print(periph->path, "CCB function code %#x is " "restricted to the XPT device\n", ccb->ccb_h.func_code); - uma_zfree(softc->pass_zone, io_req); - cam_periph_lock(periph); error = ENODEV; - break; + goto camioqueue_error; } /* @@ -1966,11 +1972,8 @@ passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr || (fc == XPT_DEV_ADVINFO) || (fc == XPT_NVME_ADMIN) || (fc == XPT_NVME_IO)) { error = passmemsetup(periph, io_req); - if (error != 0) { - uma_zfree(softc->pass_zone, io_req); - cam_periph_lock(periph); - break; - } + if (error != 0) + goto camioqueue_error; } else io_req->mapinfo.num_bufs_used = 0; @@ -2014,6 +2017,11 @@ passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr TAILQ_REMOVE(&softc->active_queue, io_req, links); TAILQ_INSERT_TAIL(&softc->done_queue, io_req, links); } + break; + +camioqueue_error: + uma_zfree(softc->pass_zone, io_req); + cam_periph_lock(periph); break; } case CAMIOGET:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803140957.w2E9vwxO038725>