mirror of
https://git.yoctoproject.org/poky
synced 2026-04-05 08:02:25 +02:00
qemu: fix build error introduced by CVE-2021-3929 fix
The patch for CVE-2021-3929 applied on dunfell returns a value for a void function. This results in the following compiler warning/error: hw/block/nvme.c:77:6: error: void function 'nvme_addr_read' should not return a value [-Wreturn-type] return NVME_DATA_TRAS_ERROR; ^ ~~~~~~~~~~~~~~~~~~~~ In newer versions of qemu, the functions is changed to have a return value, but that is not present in the version of qemu used in “dunfell”. Backport some of the patches to correct this. (From OE-Core rev: 4ad98f0b27615ad59ae61110657cf69004c61ef4) Signed-off-by: Gaurav Gupta <gauragup@cisco.com> Signed-off-by: Gaurav Gupta <gauragup@cisco.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
This commit is contained in:
committed by
Steve Sakoman
parent
0c1e54eee1
commit
a526ef88ee
@@ -115,6 +115,8 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
|
||||
file://CVE-2021-3638.patch \
|
||||
file://CVE-2021-20196.patch \
|
||||
file://CVE-2021-3507.patch \
|
||||
file://hw-block-nvme-refactor-nvme_addr_read.patch \
|
||||
file://hw-block-nvme-handle-dma-errors.patch \
|
||||
file://CVE-2021-3929.patch \
|
||||
file://CVE-2022-4144.patch \
|
||||
file://CVE-2020-15859.patch \
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
From 736b01642d85be832385063f278fe7cd4ffb5221 Mon Sep 17 00:00:00 2001
|
||||
From: Klaus Jensen <k.jensen@samsung.com>
|
||||
Date: Fri, 17 Dec 2021 10:44:01 +0100
|
||||
Subject: [PATCH] hw/nvme: fix CVE-2021-3929
|
||||
From 2c682b5975b41495f98cc34b8243042c446eec44 Mon Sep 17 00:00:00 2001
|
||||
From: Gaurav Gupta <gauragup@cisco.com>
|
||||
Date: Wed, 29 Mar 2023 14:36:16 -0700
|
||||
Subject: [PATCH] hw/nvme: fix CVE-2021-3929 MIME-Version: 1.0 Content-Type:
|
||||
text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
@@ -17,21 +18,23 @@ Reviewed-by: Keith Busch <kbusch@kernel.org>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/736b01642d85be832385]
|
||||
Upstream-Status: Backport
|
||||
[https://gitlab.com/qemu-project/qemu/-/commit/736b01642d85be832385]
|
||||
CVE: CVE-2021-3929
|
||||
Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
|
||||
Signed-off-by: Gaurav Gupta <gauragup@cisco.com>
|
||||
---
|
||||
hw/block/nvme.c | 23 +++++++++++++++++++++++
|
||||
hw/block/nvme.h | 1 +
|
||||
2 files changed, 24 insertions(+)
|
||||
|
||||
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
|
||||
index 12d82542..e7d0750c 100644
|
||||
index bda446d..ae9b19f 100644
|
||||
--- a/hw/block/nvme.c
|
||||
+++ b/hw/block/nvme.c
|
||||
@@ -52,8 +52,31 @@
|
||||
|
||||
static void nvme_process_sq(void *opaque);
|
||||
@@ -60,8 +60,31 @@ static bool nvme_addr_is_cmb(NvmeCtrl *n, hwaddr addr)
|
||||
return addr >= low && addr < hi;
|
||||
}
|
||||
|
||||
+static inline bool nvme_addr_is_iomem(NvmeCtrl *n, hwaddr addr)
|
||||
+{
|
||||
@@ -51,18 +54,18 @@ index 12d82542..e7d0750c 100644
|
||||
+ return addr >= lo && addr < hi;
|
||||
+}
|
||||
+
|
||||
static void nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size)
|
||||
static int nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size)
|
||||
{
|
||||
+
|
||||
+ if (nvme_addr_is_iomem(n, addr)) {
|
||||
+ return NVME_DATA_TRAS_ERROR;
|
||||
+ return NVME_DATA_TRAS_ERROR;
|
||||
+ }
|
||||
+
|
||||
if (n->cmbsz && addr >= n->ctrl_mem.addr &&
|
||||
addr < (n->ctrl_mem.addr + int128_get64(n->ctrl_mem.size))) {
|
||||
if (n->cmbsz && nvme_addr_is_cmb(n, addr)) {
|
||||
memcpy(buf, (void *)&n->cmbuf[addr - n->ctrl_mem.addr], size);
|
||||
return 0;
|
||||
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
|
||||
index 557194ee..5a2b119c 100644
|
||||
index 557194e..5a2b119 100644
|
||||
--- a/hw/block/nvme.h
|
||||
+++ b/hw/block/nvme.h
|
||||
@@ -59,6 +59,7 @@ typedef struct NvmeNamespace {
|
||||
@@ -74,5 +77,5 @@ index 557194ee..5a2b119c 100644
|
||||
MemoryRegion ctrl_mem;
|
||||
NvmeBar bar;
|
||||
--
|
||||
2.30.2
|
||||
1.8.3.1
|
||||
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
From ea2a7c7676d8eb9d1458eaa4b717df46782dcb3a Mon Sep 17 00:00:00 2001
|
||||
From: Gaurav Gupta <gauragup@cisco.com>
|
||||
Date: Wed, 29 Mar 2023 14:07:17 -0700
|
||||
Subject: [PATCH 2/2] hw/block/nvme: handle dma errors
|
||||
|
||||
Handling DMA errors gracefully is required for the device to pass the
|
||||
block/011 test ("disable PCI device while doing I/O") in the blktests
|
||||
suite.
|
||||
|
||||
With this patch the device sets the Controller Fatal Status bit in the
|
||||
CSTS register when failing to read from a submission queue or writing to
|
||||
a completion queue; expecting the host to reset the controller.
|
||||
|
||||
If DMA errors occur at any other point in the execution of the command
|
||||
(say, while mapping the PRPs), the command is aborted with a Data
|
||||
Transfer Error status code.
|
||||
|
||||
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
|
||||
Signed-off-by: Gaurav Gupta <gauragup@cisco.com>
|
||||
---
|
||||
hw/block/nvme.c | 41 +++++++++++++++++++++++++++++++----------
|
||||
hw/block/trace-events | 3 +++
|
||||
2 files changed, 34 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
|
||||
index e6f24a6..bda446d 100644
|
||||
--- a/hw/block/nvme.c
|
||||
+++ b/hw/block/nvme.c
|
||||
@@ -60,14 +60,14 @@ static bool nvme_addr_is_cmb(NvmeCtrl *n, hwaddr addr)
|
||||
return addr >= low && addr < hi;
|
||||
}
|
||||
|
||||
-static void nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size)
|
||||
+static int nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size)
|
||||
{
|
||||
if (n->cmbsz && nvme_addr_is_cmb(n, addr)) {
|
||||
memcpy(buf, (void *)&n->cmbuf[addr - n->ctrl_mem.addr], size);
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
- pci_dma_read(&n->parent_obj, addr, buf, size);
|
||||
+ return pci_dma_read(&n->parent_obj, addr, buf, size);
|
||||
}
|
||||
|
||||
static int nvme_check_sqid(NvmeCtrl *n, uint16_t sqid)
|
||||
@@ -152,6 +152,7 @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
|
||||
hwaddr trans_len = n->page_size - (prp1 % n->page_size);
|
||||
trans_len = MIN(len, trans_len);
|
||||
int num_prps = (len >> n->page_bits) + 1;
|
||||
+ int ret;
|
||||
|
||||
if (unlikely(!prp1)) {
|
||||
trace_nvme_err_invalid_prp();
|
||||
@@ -178,7 +179,11 @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
|
||||
|
||||
nents = (len + n->page_size - 1) >> n->page_bits;
|
||||
prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
|
||||
- nvme_addr_read(n, prp2, (void *)prp_list, prp_trans);
|
||||
+ ret = nvme_addr_read(n, prp2, (void *)prp_list, prp_trans);
|
||||
+ if (ret) {
|
||||
+ trace_pci_nvme_err_addr_read(prp2);
|
||||
+ return NVME_DATA_TRAS_ERROR;
|
||||
+ }
|
||||
while (len != 0) {
|
||||
uint64_t prp_ent = le64_to_cpu(prp_list[i]);
|
||||
|
||||
@@ -191,8 +196,12 @@ static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
|
||||
i = 0;
|
||||
nents = (len + n->page_size - 1) >> n->page_bits;
|
||||
prp_trans = MIN(n->max_prp_ents, nents) * sizeof(uint64_t);
|
||||
- nvme_addr_read(n, prp_ent, (void *)prp_list,
|
||||
- prp_trans);
|
||||
+ ret = nvme_addr_read(n, prp_ent, (void *)prp_list,
|
||||
+ prp_trans);
|
||||
+ if (ret) {
|
||||
+ trace_pci_nvme_err_addr_read(prp_ent);
|
||||
+ return NVME_DATA_TRAS_ERROR;
|
||||
+ }
|
||||
prp_ent = le64_to_cpu(prp_list[i]);
|
||||
}
|
||||
|
||||
@@ -286,6 +295,7 @@ static void nvme_post_cqes(void *opaque)
|
||||
NvmeCQueue *cq = opaque;
|
||||
NvmeCtrl *n = cq->ctrl;
|
||||
NvmeRequest *req, *next;
|
||||
+ int ret;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) {
|
||||
NvmeSQueue *sq;
|
||||
@@ -295,15 +305,21 @@ static void nvme_post_cqes(void *opaque)
|
||||
break;
|
||||
}
|
||||
|
||||
- QTAILQ_REMOVE(&cq->req_list, req, entry);
|
||||
sq = req->sq;
|
||||
req->cqe.status = cpu_to_le16((req->status << 1) | cq->phase);
|
||||
req->cqe.sq_id = cpu_to_le16(sq->sqid);
|
||||
req->cqe.sq_head = cpu_to_le16(sq->head);
|
||||
addr = cq->dma_addr + cq->tail * n->cqe_size;
|
||||
+ ret = pci_dma_write(&n->parent_obj, addr, (void *)&req->cqe,
|
||||
+ sizeof(req->cqe));
|
||||
+ if (ret) {
|
||||
+ trace_pci_nvme_err_addr_write(addr);
|
||||
+ trace_pci_nvme_err_cfs();
|
||||
+ n->bar.csts = NVME_CSTS_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
+ QTAILQ_REMOVE(&cq->req_list, req, entry);
|
||||
nvme_inc_cq_tail(cq);
|
||||
- pci_dma_write(&n->parent_obj, addr, (void *)&req->cqe,
|
||||
- sizeof(req->cqe));
|
||||
QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
|
||||
}
|
||||
if (cq->tail != cq->head) {
|
||||
@@ -888,7 +904,12 @@ static void nvme_process_sq(void *opaque)
|
||||
|
||||
while (!(nvme_sq_empty(sq) || QTAILQ_EMPTY(&sq->req_list))) {
|
||||
addr = sq->dma_addr + sq->head * n->sqe_size;
|
||||
- nvme_addr_read(n, addr, (void *)&cmd, sizeof(cmd));
|
||||
+ if (nvme_addr_read(n, addr, (void *)&cmd, sizeof(cmd))) {
|
||||
+ trace_pci_nvme_err_addr_read(addr);
|
||||
+ trace_pci_nvme_err_cfs();
|
||||
+ n->bar.csts = NVME_CSTS_FAILED;
|
||||
+ break;
|
||||
+ }
|
||||
nvme_inc_sq_head(sq);
|
||||
|
||||
req = QTAILQ_FIRST(&sq->req_list);
|
||||
diff --git a/hw/block/trace-events b/hw/block/trace-events
|
||||
index c03e80c..4e4ad4e 100644
|
||||
--- a/hw/block/trace-events
|
||||
+++ b/hw/block/trace-events
|
||||
@@ -60,6 +60,9 @@ nvme_mmio_shutdown_set(void) "shutdown bit set"
|
||||
nvme_mmio_shutdown_cleared(void) "shutdown bit cleared"
|
||||
|
||||
# nvme traces for error conditions
|
||||
+pci_nvme_err_addr_read(uint64_t addr) "addr 0x%"PRIx64""
|
||||
+pci_nvme_err_addr_write(uint64_t addr) "addr 0x%"PRIx64""
|
||||
+pci_nvme_err_cfs(void) "controller fatal status"
|
||||
nvme_err_invalid_dma(void) "PRP/SGL is too small for transfer size"
|
||||
nvme_err_invalid_prplist_ent(uint64_t prplist) "PRP list entry is null or not page aligned: 0x%"PRIx64""
|
||||
nvme_err_invalid_prp2_align(uint64_t prp2) "PRP2 is not page aligned: 0x%"PRIx64""
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From 55428706d5b0b8889b8e009eac77137bb556a4f0 Mon Sep 17 00:00:00 2001
|
||||
From: Klaus Jensen <k.jensen@samsung.com>
|
||||
Date: Tue, 9 Jun 2020 21:03:17 +0200
|
||||
Subject: [PATCH 1/2] hw/block/nvme: refactor nvme_addr_read
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Pull the controller memory buffer check to its own function. The check
|
||||
will be used on its own in later patches.
|
||||
|
||||
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||||
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
|
||||
Reviewed-by: Keith Busch <kbusch@kernel.org>
|
||||
Message-Id: <20200609190333.59390-7-its@irrelevant.dk>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
hw/block/nvme.c | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
|
||||
index 12d8254..e6f24a6 100644
|
||||
--- a/hw/block/nvme.c
|
||||
+++ b/hw/block/nvme.c
|
||||
@@ -52,14 +52,22 @@
|
||||
|
||||
static void nvme_process_sq(void *opaque);
|
||||
|
||||
+static bool nvme_addr_is_cmb(NvmeCtrl *n, hwaddr addr)
|
||||
+{
|
||||
+ hwaddr low = n->ctrl_mem.addr;
|
||||
+ hwaddr hi = n->ctrl_mem.addr + int128_get64(n->ctrl_mem.size);
|
||||
+
|
||||
+ return addr >= low && addr < hi;
|
||||
+}
|
||||
+
|
||||
static void nvme_addr_read(NvmeCtrl *n, hwaddr addr, void *buf, int size)
|
||||
{
|
||||
- if (n->cmbsz && addr >= n->ctrl_mem.addr &&
|
||||
- addr < (n->ctrl_mem.addr + int128_get64(n->ctrl_mem.size))) {
|
||||
+ if (n->cmbsz && nvme_addr_is_cmb(n, addr)) {
|
||||
memcpy(buf, (void *)&n->cmbuf[addr - n->ctrl_mem.addr], size);
|
||||
- } else {
|
||||
- pci_dma_read(&n->parent_obj, addr, buf, size);
|
||||
+ return;
|
||||
}
|
||||
+
|
||||
+ pci_dma_read(&n->parent_obj, addr, buf, size);
|
||||
}
|
||||
|
||||
static int nvme_check_sqid(NvmeCtrl *n, uint16_t sqid)
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
Reference in New Issue
Block a user