[PATCH v2 2/2] nvme: avoid memory corruption for sync passthrough

Vincent Fu vincent.fu at samsung.com
Thu Aug 31 07:09:34 PDT 2023


I tested this patch on a QEMU NVMe device.

I formatted the device with a 512+16 lbaf with a separate buffer for metadata:

nvme format /dev/ng0n1 -m 0 -i 1 -p 0 --lbaf 2 --force

Using the latest fio I wrote some data to it:

./fio --name=difdix --ioengine=io_uring_cmd --cmd_type=nvme \
  --filename=/dev/ng0n1 --rw=write --bs=512 --md_per_io_size=16 --pi_act=1 \
  --pi_chk=APPTAG --apptag=0x8888 --apptag_mask=0xFFFF --number_ios=128

Then I built nvme-cli with the following patch:

diff --git a/nvme.c b/nvme.c
index b5b05857..807a6643 100644
--- a/nvme.c
+++ b/nvme.c
@@ -7581,12 +7581,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
                        pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7;
                }

-               mbuffer_size = ((unsigned long long)cfg.block_count + 1) * ms;
-               if (ms && cfg.metadata_size < mbuffer_size)
-                       nvme_show_error("Rounding metadata size to fit block count (%lld bytes)",
-                                       mbuffer_size);
-               else
-                       mbuffer_size = cfg.metadata_size;
+               mbuffer_size = cfg.metadata_size;

                mbuffer = malloc(mbuffer_size);
                if (!mbuffer) {

Using the patched nvme-cli I ran commands like this:

./nvme read /dev/ng0n1 -n 1 -s 0 -z 0 -c 255 -z 131072 -y 8 -r 0 -m 0 -d out -M out-md

It reads 128k of data which should require 4k of metadata but provides a buffer
of only 8 bytes.

Without the patch there are no error messages but with the patch the read
request fails and I see error messages in the kernel log.

Tested-by: Vincent Fu <vincent.fu at samsung.com>



More information about the Linux-nvme mailing list