nvme-pci: fix out of bounds access in nvme_cqe_pending
authorHongbo Yao <yaohongbo@huawei.com>
Mon, 7 Jan 2019 02:22:07 +0000 (10:22 +0800)
committerChristoph Hellwig <hch@lst.de>
Wed, 9 Jan 2019 18:47:05 +0000 (13:47 -0500)
There is an out of bounds array access in nvme_cqe_peding().

When enable irq_thread for nvme interrupt, there is racing between the
nvmeq->cq_head updating and reading.

nvmeq->cq_head is updated in nvme_update_cq_head(), if nvmeq->cq_head
equals nvmeq->q_depth and before its value set to zero, nvme_cqe_pending()
uses its value as an array index, the index will be out of bounds.

Signed-off-by: Hongbo Yao <yaohongbo@huawei.com>
[hch: slight coding style update]
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/host/pci.c

index f891eb5..3f53a2c 100644 (file)
@@ -1020,9 +1020,11 @@ static void nvme_complete_cqes(struct nvme_queue *nvmeq, u16 start, u16 end)
 
 static inline void nvme_update_cq_head(struct nvme_queue *nvmeq)
 {
-       if (++nvmeq->cq_head == nvmeq->q_depth) {
+       if (nvmeq->cq_head == nvmeq->q_depth - 1) {
                nvmeq->cq_head = 0;
                nvmeq->cq_phase = !nvmeq->cq_phase;
+       } else {
+               nvmeq->cq_head++;
        }
 }