[PATCH v2 4/5] tests/qtest: Rework nvmetest_oob_cmb_test for BAR check

Navid Emamdoost posted 5 patches 2 days, 10 hours ago
Maintainers: John Snow <jsnow@redhat.com>, Fabiano Rosas <farosas@suse.de>, Laurent Vivier <lvivier@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Alexander Bulekov <alxndr@bu.edu>, Bandan Das <bsd@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>, Darren Kenny <darren.kenny@oracle.com>, Qiuhao Li <Qiuhao.Li@outlook.com>, Keith Busch <kbusch@kernel.org>, Klaus Jensen <its@irrelevant.dk>, Jesper Devantier <foss@defmacro.it>
[PATCH v2 4/5] tests/qtest: Rework nvmetest_oob_cmb_test for BAR check
Posted by Navid Emamdoost 2 days, 10 hours ago
The nvmetest_oob_cmb_test was designed to deliberately perform an
out-of-bounds write on a PCI BAR. This was intended as a regression
test for CVE-2018-16847.
The recent change to libqos introduced strict bounds checking on all
BAR accessors, which correctly caused this test to fail with a fatal
assertion, as it was performing an illegal memory access.
This change reworks the test to honor its original intent—verifying
safe accesses at the BAR boundary—without violating the new API contract.
Instead of attempting an illegal write, the test now performs several
valid read/write operations at the very end of the BAR (at offsets
size - 1, size - 2, and size - 4) to confirm the entire region
is accessible.
This makes the test compatible with the safer libqos API while still
serving as a regression test for the original issue.

Signed-off-by: Navid Emamdoost <navidem@google.com>
---
 tests/qtest/nvme-test.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/tests/qtest/nvme-test.c b/tests/qtest/nvme-test.c
index 5ad6821f7a..8be37ae043 100644
--- a/tests/qtest/nvme-test.c
+++ b/tests/qtest/nvme-test.c
@@ -48,23 +48,37 @@ static void *nvme_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
 /* This used to cause a NULL pointer dereference.  */
 static void nvmetest_oob_cmb_test(void *obj, void *data, QGuestAllocator *alloc)
 {
-    const int cmb_bar_size = 2 * MiB;
     QNvme *nvme = obj;
     QPCIDevice *pdev = &nvme->dev;
     QPCIBar bar;
+    const uint64_t expected_cmb_size = 2 * MiB;
 
+    /* Enable the device's I/O and memory resources at the PCI level. */
     qpci_device_enable(pdev);
+
+    /* Map BAR 2, which is the dedicated BAR for the Controller Memory Buffer. */
     bar = qpci_iomap(pdev, 2, NULL);
 
-    qpci_io_writel(pdev, bar, 0, 0xccbbaa99);
-    g_assert_cmpint(qpci_io_readb(pdev, bar, 0), ==, 0x99);
-    g_assert_cmpint(qpci_io_readw(pdev, bar, 0), ==, 0xaa99);
+    /* Sanity check that the probed BAR size matches the command line. */
+    g_assert_cmpint(bar.size, ==, expected_cmb_size);
+
+    /*
+     * Perform read/write checks at the very end of the BAR to ensure
+     * that the entire region is accessible and that boundary accesses of
+     * different sizes are handled correctly.
+     */
+
+    /* Test the last valid byte (the fix for the CVE was about 1-byte access) */
+    qpci_io_writeb(pdev, bar, bar.size - 1, 0x11);
+    g_assert_cmpint(qpci_io_readb(pdev, bar, bar.size - 1), ==, 0x11);
+
+    /* Test the last valid word */
+    qpci_io_writew(pdev, bar, bar.size - 2, 0x2233);
+    g_assert_cmpint(qpci_io_readw(pdev, bar, bar.size - 2), ==, 0x2233);
 
-    /* Test partially out-of-bounds accesses.  */
-    qpci_io_writel(pdev, bar, cmb_bar_size - 1, 0x44332211);
-    g_assert_cmpint(qpci_io_readb(pdev, bar, cmb_bar_size - 1), ==, 0x11);
-    g_assert_cmpint(qpci_io_readw(pdev, bar, cmb_bar_size - 1), !=, 0x2211);
-    g_assert_cmpint(qpci_io_readl(pdev, bar, cmb_bar_size - 1), !=, 0x44332211);
+    /* Test the last valid dword */
+    qpci_io_writel(pdev, bar, bar.size - 4, 0x44556677);
+    g_assert_cmpint(qpci_io_readl(pdev, bar, bar.size - 4), ==, 0x44556677);
 }
 
 static void nvmetest_reg_read_test(void *obj, void *data, QGuestAllocator *alloc)
-- 
2.52.0.158.g65b55ccf14-goog
Re: [PATCH v2 4/5] tests/qtest: Rework nvmetest_oob_cmb_test for BAR check
Posted by Peter Maydell 1 day, 20 hours ago
On Thu, 27 Nov 2025 at 00:13, Navid Emamdoost <navidem@google.com> wrote:
>
> The nvmetest_oob_cmb_test was designed to deliberately perform an
> out-of-bounds write on a PCI BAR. This was intended as a regression
> test for CVE-2018-16847.
> The recent change to libqos introduced strict bounds checking on all
> BAR accessors, which correctly caused this test to fail with a fatal
> assertion, as it was performing an illegal memory access.
> This change reworks the test to honor its original intent—verifying
> safe accesses at the BAR boundary—without violating the new API contract.
> Instead of attempting an illegal write, the test now performs several
> valid read/write operations at the very end of the BAR (at offsets
> size - 1, size - 2, and size - 4) to confirm the entire region
> is accessible.
> This makes the test compatible with the safer libqos API while still
> serving as a regression test for the original issue.

This one I'll have to leave for the nvme folks to review.
(You'll want to recast the commit message because this
change has to go before we add the assertions, not after.)

thanks
-- PMM