Author: jimharris
Date: Wed Jun 26 23:32:45 2013
New Revision: 252272
URL: http://svnweb.freebsd.org/changeset/base/252272

Log:
  Fail any passthrough command whose transfer size exceeds the controller's
  max transfer size.  This guards against rogue commands coming in from
  userspace.
  
  Also add KASSERTS for the virtual address and unmapped bio cases, if the
  transfer size exceeds the controller's max transfer size.
  
  Sponsored by: Intel
  MFC after:    3 days

Modified:
  head/sys/dev/nvme/nvme_ctrlr.c
  head/sys/dev/nvme/nvme_qpair.c

Modified: head/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr.c      Wed Jun 26 23:27:17 2013        
(r252271)
+++ head/sys/dev/nvme/nvme_ctrlr.c      Wed Jun 26 23:32:45 2013        
(r252272)
@@ -895,7 +895,13 @@ nvme_ctrlr_passthrough_cmd(struct nvme_c
        struct buf              *buf = NULL;
        int                     ret = 0;
 
-       if (pt->len > 0)
+       if (pt->len > 0) {
+               if (pt->len > ctrlr->max_xfer_size) {
+                       nvme_printf(ctrlr, "pt->len (%d) "
+                           "exceeds max_xfer_size (%d)\n", pt->len,
+                           ctrlr->max_xfer_size);
+                       return EIO;
+               }
                if (is_user_buffer) {
                        /*
                         * Ensure the user buffer is wired for the duration of
@@ -920,7 +926,7 @@ nvme_ctrlr_passthrough_cmd(struct nvme_c
                } else
                        req = nvme_allocate_request_vaddr(pt->buf, pt->len,
                            nvme_pt_done, pt);
-       else
+       } else
                req = nvme_allocate_request_null(nvme_pt_done, pt);
 
        req->cmd.opc    = pt->cmd.opc;

Modified: head/sys/dev/nvme/nvme_qpair.c
==============================================================================
--- head/sys/dev/nvme/nvme_qpair.c      Wed Jun 26 23:27:17 2013        
(r252271)
+++ head/sys/dev/nvme/nvme_qpair.c      Wed Jun 26 23:32:45 2013        
(r252272)
@@ -786,6 +786,9 @@ _nvme_qpair_submit_request(struct nvme_q
 
        switch (req->type) {
        case NVME_REQUEST_VADDR:
+               KASSERT(req->payload_size <= qpair->ctrlr->max_xfer_size,
+                   ("payload_size (%d) exceeds max_xfer_size (%d)\n",
+                   req->payload_size, qpair->ctrlr->max_xfer_size));
                err = bus_dmamap_load(tr->qpair->dma_tag, tr->payload_dma_map,
                    req->u.payload, req->payload_size, nvme_payload_map, tr, 0);
                if (err != 0)
@@ -805,6 +808,10 @@ _nvme_qpair_submit_request(struct nvme_q
                break;
 #ifdef NVME_UNMAPPED_BIO_SUPPORT
        case NVME_REQUEST_BIO:
+               KASSERT(req->u.bio->bio_bcount <= qpair->ctrlr->max_xfer_size,
+                   ("bio->bio_bcount (%jd) exceeds max_xfer_size (%d)\n",
+                   (intmax_t)req->u.bio->bio_bcount,
+                   qpair->ctrlr->max_xfer_size));
                err = bus_dmamap_load_bio(tr->qpair->dma_tag,
                    tr->payload_dma_map, req->u.bio, nvme_payload_map, tr, 0);
                if (err != 0)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to