All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Denis V. Lunev" <den@openvz.org>
To: qemu-devel@nongnu.org
Cc: qemu-block@nongnu.org, "Denis V. Lunev" <den@openvz.org>,
	"XlabAI Team of Tencent Xuanwu Lab" <xlabai@tencent.com>,
	"John Snow" <jsnow@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>
Subject: [PATCH 01/11] hw/ide: reject an out-of-range PIO transfer window on load
Date: Thu, 20 Aug 2026 16:42:59 +0200	[thread overview]
Message-ID: <20260820144309.835173-2-den@openvz.org> (raw)
In-Reply-To: <20260820144309.835173-1-den@openvz.org>

From: Denis V. Lunev <den@openvz.org>

ide_drive_pio_post_load() validates end_transfer_fn_idx but takes
cur_io_buffer_offset and cur_io_buffer_len straight from the migration
stream, so data_ptr and data_end can be placed anywhere within +-2GB of
the 131076-byte io_buffer allocation. Both fields are signed 32-bit.

The subsection loader consumes every subsection present in the stream
without consulting needed(), so a crafted stream can inject
ide_drive/pio_state for a drive that was never in a DRQ state. Once
data_end is out of bounds, ide_data_writew() only compares the guest's
pointer against that same bogus data_end, and the resumed guest turns a
repeated outw to the data port into a controlled 16-bit heap write.
end_transfer_fn_idx picks the direction, so the read side of the same
code path leaks host heap instead.

Validate the window against io_buffer_total_len and fail the load. The
subtraction form avoids overflowing the addition.

Reported-by: XlabAI Team of Tencent Xuanwu Lab <xlabai@tencent.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/4179
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3738
Cc: John Snow <jsnow@redhat.com>
Cc: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 hw/ide/core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 8190549ee8..0dca2b5c52 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2898,6 +2898,12 @@ static int ide_drive_pio_post_load(void *opaque, int version_id)
     if (s->end_transfer_fn_idx >= ARRAY_SIZE(transfer_end_table)) {
         return -EINVAL;
     }
+    if (s->cur_io_buffer_offset < 0 || s->cur_io_buffer_len < 0 ||
+        s->cur_io_buffer_offset > s->io_buffer_total_len ||
+        s->cur_io_buffer_len >
+            s->io_buffer_total_len - s->cur_io_buffer_offset) {
+        return -EINVAL;
+    }
     s->end_transfer_func = transfer_end_table[s->end_transfer_fn_idx];
     s->data_ptr = s->io_buffer + s->cur_io_buffer_offset;
     s->data_end = s->data_ptr + s->cur_io_buffer_len;
-- 
2.53.0



  reply	other threads:[~2026-08-20 14:45 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-20 14:42 [PATCH 00/11] hw/ide: pending IDE fixes Denis V. Lunev
2026-08-20 14:42 ` Denis V. Lunev [this message]
2026-08-20 14:43 ` [PATCH 02/11] tests/qtest/ide-test: cover the migrated PIO transfer window Denis V. Lunev
2026-08-20 14:43 ` [PATCH 03/11] hw/ide/ahci: refuse a PIO transfer with no command header Denis V. Lunev
2026-08-20 14:43 ` [PATCH 04/11] hw/ide/ahci: clear cur_cmd when the command list is unmapped Denis V. Lunev
2026-08-20 14:43 ` [PATCH 05/11] tests/qtest/ahci: regression test for a PIO write vs. engine stop Denis V. Lunev
2026-08-20 14:43 ` [PATCH 06/11] hw/ide/ahci: treat a failed PRDT walk as a PIO transfer failure Denis V. Lunev
2026-08-20 14:43 ` [PATCH 07/11] hw/ide/ahci: reject a command header with an invalid FIS length Denis V. Lunev
2026-08-20 14:43 ` [PATCH 08/11] hw/ide/ahci: drain the ports on teardown Denis V. Lunev
2026-08-20 14:43 ` [PATCH 09/11] tests/qtest/ahci: regression test for a request outliving an unplug Denis V. Lunev
2026-08-20 14:43 ` [PATCH 10/11] hw/ide: report ATAPI UDMA5 with a matching standard and cable Denis V. Lunev
2026-08-20 14:43 ` [PATCH 11/11] tests/qtest/ide-test: cover the UDMA5 identify words Denis V. Lunev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260820144309.835173-2-den@openvz.org \
    --to=den@openvz.org \
    --cc=jsnow@redhat.com \
    --cc=philmd@oss.qualcomm.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=xlabai@tencent.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.