The spec requires not only NUL termination of the device ID string, but
NUL padding:
VIRTIO_BLK_T_GET_ID requests fetch the device ID string from the
device into data. The device ID string is a NUL-padded ASCII string
up to 20 bytes long. If the string is 20 bytes long then there is no
NUL terminator.
Zero out all of the remaining bytes in the request buffer.
Signed-off-by: Kevin Wolf <[email protected]>
---
hw/block/virtio-blk.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 536d71a91ad..3f236f22d57 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1011,14 +1011,18 @@ static int virtio_blk_handle_request(VirtIOBlockReq
*req, MultiReqBuffer *mrb)
case VIRTIO_BLK_T_GET_ID:
{
/*
- * NB: per existing s/n string convention the string is
+ * The spec requires NUL-padding for the output. The string is
* terminated by '\0' only when shorter than buffer.
*/
const char *serial = s->conf.serial ? s->conf.serial : "";
- size_t size = MIN(strlen(serial) + 1,
- MIN(iov_size(in_iov, in_num),
- VIRTIO_BLK_ID_BYTES));
+ size_t req_size = MIN(iov_size(in_iov, in_num), VIRTIO_BLK_ID_BYTES);
+ size_t size = MIN(strlen(serial), req_size);
+ size_t padding = req_size - size;
+
iov_from_buf(in_iov, in_num, 0, serial, size);
+ if (padding) {
+ iov_memset(in_iov, in_num, size, 0, padding);
+ }
virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
g_free(req);
break;
--
2.56.0