Commit f6e043699a for qemu.org

commit f6e043699a5356867995a1e141b0c1153155acbb
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
Date:   Sun Oct 4 14:23:35 2026 +0400

    chardev/char-ringbuf: use actual read length in qmp_ringbuf_read

    qmp_ringbuf_read() used the requested size rather than the actual
    number of bytes returned by ringbuf_chr_read() for base64 encoding
    and null-termination. Since ringbuf_count() is called without the
    lock, a concurrent writer can advance the consumer index, leaving
    fewer bytes available by the time ringbuf_chr_read() runs. This
    could encode uninitialized data or misplace the null terminator.

    Reported-by: Hui Peng <benquike@gmail.com>
    Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
    Message-ID: <20261004-issue-4560-v1-21-ccbef537cbeb@redhat.com>

diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index a80519f8d6..4d83663e9a 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -167,6 +167,7 @@ char *qmp_ringbuf_read(const char *device, int64_t size,
     Chardev *chr;
     uint8_t *read_data;
     size_t count;
+    int actual;
     char *data;

     chr = qemu_chr_find(device);
@@ -189,10 +190,10 @@ char *qmp_ringbuf_read(const char *device, int64_t size,
     size = size > count ? count : size;
     read_data = g_malloc(size + 1);

-    ringbuf_chr_read(chr, read_data, size);
+    actual = ringbuf_chr_read(chr, read_data, size);

     if (has_format && (format == DATA_FORMAT_BASE64)) {
-        data = g_base64_encode(read_data, size);
+        data = g_base64_encode(read_data, actual);
         g_free(read_data);
     } else {
         /*
@@ -202,7 +203,7 @@ char *qmp_ringbuf_read(const char *device, int64_t size,
          * when) ring buffer lost characters since last read, initial
          * continuation characters should be dropped.
          */
-        read_data[size] = 0;
+        read_data[actual] = 0;
         data = (char *)read_data;
     }