From nobody Sun Jul 26 10:06:46 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.dev ARC-Seal: i=1; a=rsa-sha256; t=1783562796; cv=none; d=zohomail.com; s=zohoarc; b=gu/OjIAs1OvTdFworE54WoAondqzgHN3TGIPoXjykAhUAD5cnlrEbTeBaSHArNhVCroYiWLuC6n35KjTuSsEpG2Ow2CI65t0vGwbQXAb2kMuZSTEzToyBm0PZ/pQl/HeB/WiyIyOQRf7EovSED11sJQWBbVj0bWT3KeQ0Kbk1fY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783562796; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=w3JZLxnO6XLta1pKoilZoueRwppuc8ig9aUa6rlyn2s=; b=GA7Me++7xyi6CTiwSpSgln4WION7cFa7h+lO6l++GiWrS2/9zzzhIxDS0+8sbL+igIy+jGN7f+A/9vg+bzdkJXqHdJT9YfD+jVJLZZHq2lLut60knt+PQltnmRxdAMmK5hmkciSIsgj+a6RIA+FdHtfX2zc9jWOPbC7AW/ss50g= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783562795800930.1593942951326; Wed, 8 Jul 2026 19:06:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1whe98-0004ez-Vi; Wed, 08 Jul 2026 22:05:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1whe97-0004eo-B7 for qemu-devel@nongnu.org; Wed, 08 Jul 2026 22:05:49 -0400 Received: from out-186.mta0.migadu.com ([2001:41d0:1004:224b::ba]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1whe95-0006kF-5Q for qemu-devel@nongnu.org; Wed, 08 Jul 2026 22:05:49 -0400 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1783562745; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=w3JZLxnO6XLta1pKoilZoueRwppuc8ig9aUa6rlyn2s=; b=VqvumEPX7QgEUUlPuWI9ATHBG+qi9nysIpwY0ZXXiUarZt64SdZ2rMyig+YmhjrmJU3mVA dGne5aye8u+sLJ6A42bcuSW95uJK+/DtxliAsIsReAQsFHze7/TKBIL6MNpOdG4CDx7GsC zXHa7lKz/pc+mXsz4g613eJEKrCzIJ8= From: Tao Cui To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, pbonzini@redhat.com, cuitao@kylinos.cn, cui.tao@linux.dev Subject: [PATCH v1 1/2] accel/tcg: fix crash on instruction straddling address-space end Date: Thu, 9 Jul 2026 10:05:28 +0800 Message-ID: <20260709020529.126652-2-cui.tao@linux.dev> In-Reply-To: <20260709020529.126652-1-cui.tao@linux.dev> References: <20260709020529.126652-1-cui.tao@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2001:41d0:1004:224b::ba; envelope-from=cui.tao@linux.dev; helo=out-186.mta0.migadu.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.dev) X-ZM-MESSAGEID: 1783562798072158500 Content-Type: text/plain; charset="utf-8" From: Tao Cui translator_ld() reads the bytes of a page-crossing instruction into a contiguous buffer. When computing the second page address it assumes the two pages are virtually contiguous (second =3D page0 + TARGET_PAGE_SIZE) and asserts that the read pointer pc is on that page. On targets whose address space is narrower than vaddr (the 32-bit targets, e.g. i386 or ARM AArch32 Thumb), an instruction at the very end of the address space wraps the second page back to the start of the address space. The target advances its fetch PC as a target_ulong, so pc wraps to 0, while the linear page0 + TARGET_PAGE_SIZE stays at 0x1_0000_0000; the assert fails and QEMU aborts. A guest can trigger this by mapping the last page executable and running a straddling instruction, i.e. a guest-triggered host crash (DoS). Instead of asserting, take the second page from pc: if the linear page0 + TARGET_PAGE_SIZE does not land on pc's page, use pc's page. This is correct for both the normal contiguous case and the wraparound case, without needing to know the address-space width. Tested with a minimal i386 multiboot payload that executes an instruction at 0xfffffffe: before this change QEMU aborts (translator.c:296), after it translates and runs normally. Signed-off-by: Tao Cui --- accel/tcg/translator.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index cd7d079fe0..750c132bbc 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -283,16 +283,16 @@ static bool translator_ld(CPUArchState *env, DisasCon= textBase *db, } =20 /* - * The read must conclude on the second page and not extend to a third. - * - * TODO: We could allow the two pages to be virtually discontiguous, - * since we already allow the two pages to be physically discontiguous. - * The only reasonable use case would be executing an insn at the end - * of the address space wrapping around to the beginning. For that, - * we would need to know the current width of the address space. - * In the meantime, assert. + * The read must conclude on the second page and must not extend to a + * third. An instruction that straddles the end of the address space + * wraps the second page back to the start of the address space, so the + * linear page0 + TARGET_PAGE_SIZE does not land on pc's page; in that + * case take the second page from pc instead of asserting. */ base =3D (base & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; + if (((base ^ pc) & TARGET_PAGE_MASK) !=3D 0) { + base =3D pc & TARGET_PAGE_MASK; + } assert(((base ^ pc) & TARGET_PAGE_MASK) =3D=3D 0); assert(((base ^ last) & TARGET_PAGE_MASK) =3D=3D 0); host =3D db->host_addr[1]; --=20 2.43.0 From nobody Sun Jul 26 10:06:46 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=linux.dev ARC-Seal: i=1; a=rsa-sha256; t=1783562774; cv=none; d=zohomail.com; s=zohoarc; b=NtMyjdWSx2iqB2yST9NMhzJdhat4/imXG1kzMvKzG6a3Pt1pxcxxp3j2TFxhsF8Gqzew/FVqXwfeT1eTw97LJuDSL4PLH5HtcikiH2m2Q3DflQjq8KGSEIjkNZDMqYoI1xPFR8NDMQ5gJ9y3xLZ6FaXkCg04IrVG7QBU2s0XO+s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783562774; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=M340HysvhMOP5FOFCjNkrui4LPGMUf+jwONfghVISXA=; b=idO8ooOR9wdnhFnHfCswcnXflrXLw2Y/GAQS3BEmocKJcaF/syJZrPMu73yBMk6BOLeTGLHs8dZKPC+V9H/1DSveqRcLMiqO1NEjiJL5BZZxo2q9nhdTw3MQMSeTCahgXsq7egntj834JNN3/ApZkAXPI/vKZFbHaRu1Zmy3Zsk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1783562773871969.744084589324; Wed, 8 Jul 2026 19:06:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1whe9B-0004ff-PN; Wed, 08 Jul 2026 22:05:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1whe9A-0004fH-5o for qemu-devel@nongnu.org; Wed, 08 Jul 2026 22:05:52 -0400 Received: from out-181.mta0.migadu.com ([2001:41d0:1004:224b::b5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1whe97-0006kh-Tf for qemu-devel@nongnu.org; Wed, 08 Jul 2026 22:05:51 -0400 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1783562747; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=M340HysvhMOP5FOFCjNkrui4LPGMUf+jwONfghVISXA=; b=hIU1IP+qriQmi9LBvUezV7RRpsfJw2rnmgExKDxLn6KkPQYpm+HG/n4mJBrbY1jARt5UWB fVjzQJE+nn1tGceJk5/g22/GR9+JFLJOkJBqqusbFwvsMKb5E10xatI8Vq2vjOsaPVPPTW yjheqkCkIuoNS2jvJnhj8gdYWJbmkdc= From: Tao Cui To: qemu-devel@nongnu.org Cc: richard.henderson@linaro.org, pbonzini@redhat.com, cuitao@kylinos.cn, cui.tao@linux.dev Subject: [PATCH v1 2/2] tests/multiboot: add regression test for translator_ld wraparound Date: Thu, 9 Jul 2026 10:05:29 +0800 Message-ID: <20260709020529.126652-3-cui.tao@linux.dev> In-Reply-To: <20260709020529.126652-1-cui.tao@linux.dev> References: <20260709020529.126652-1-cui.tao@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2001:41d0:1004:224b::b5; envelope-from=cui.tao@linux.dev; helo=out-181.mta0.migadu.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @linux.dev) X-ZM-MESSAGEID: 1783562780751158500 Content-Type: text/plain; charset="utf-8" From: Tao Cui Add a multiboot test case that reaches an instruction straddling the end of the 32-bit address space (0xfffffffe). Before the translator_ld fix QEMU aborts at translator.c:296; afterwards the case reaches isa-debug-exit and passes. The top page (0xfffff000) is SeaBIOS ROM, so the cross-boundary byte is the ROM's own 0x00 (add r/m8, r8) at 0xffffffff, whose modrm is fetched from [0x0]. A short exit stub is placed there. The case runs on qemu-system-i386 since the bug is 32-bit only. Signed-off-by: Tao Cui --- tests/multiboot/Makefile | 7 +++++- tests/multiboot/run_test.sh | 8 +++++- tests/multiboot/wraparound.c | 46 ++++++++++++++++++++++++++++++++++ tests/multiboot/wraparound.out | 5 ++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 tests/multiboot/wraparound.c create mode 100644 tests/multiboot/wraparound.out diff --git a/tests/multiboot/Makefile b/tests/multiboot/Makefile index ed4225e7d1..b5045855d7 100644 --- a/tests/multiboot/Makefile +++ b/tests/multiboot/Makefile @@ -9,7 +9,7 @@ LIBS=3D$(shell $(CC) $(CCFLAGS) -print-libgcc-file-name) =20 AOUT_KLUDGE_BIN=3D$(foreach x,$(shell seq 1 9),aout_kludge_$x.bin) =20 -all: mmap.elf modules.elf $(AOUT_KLUDGE_BIN) +all: mmap.elf modules.elf wraparound.elf $(AOUT_KLUDGE_BIN) =20 mmap.elf: start.o mmap.o libc.o link.ld $(LD) $(LDFLAGS_ELF) -o $@ $^ $(LIBS) @@ -17,6 +17,11 @@ mmap.elf: start.o mmap.o libc.o link.ld modules.elf: start.o modules.o libc.o link.ld $(LD) $(LDFLAGS_ELF) -o $@ $^ $(LIBS) =20 +# link.ld is provided via LDFLAGS_ELF (-T); keep it out of the +# prerequisite list so $^ does not pass it to ld a second time. +wraparound.elf: start.o wraparound.o libc.o + $(LD) $(LDFLAGS_ELF) -o $@ $^ $(LIBS) + aout_kludge_%.bin: aout_kludge_%.o link.ld $(LD) $(LDFLAGS_BIN) -o $@ $^ $(LIBS) =20 diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh index f968bf797e..517281ba49 100755 --- a/tests/multiboot/run_test.sh +++ b/tests/multiboot/run_test.sh @@ -73,9 +73,15 @@ aout_kludge() { done } =20 +wraparound() { + # The translator_ld wraparound bug is i386-only (32-bit address space); + # the default x86_64 QEMU does not reproduce it. + QEMU=3D"${QEMU%x86_64}i386" run_qemu wraparound.elf -m 4G +} + make all =20 -for t in mmap modules aout_kludge; do +for t in mmap modules aout_kludge wraparound; do =20 echo > test.log pass=3D1 diff --git a/tests/multiboot/wraparound.c b/tests/multiboot/wraparound.c new file mode 100644 index 0000000000..3b757f3f98 --- /dev/null +++ b/tests/multiboot/wraparound.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Regression test for the translator_ld crash when an instruction + * straddles the end of the 32-bit address space (i386). + */ + +#include "libc.h" +#include "multiboot.h" + +int test_main(uint32_t magic, struct mb_info *mbi) +{ + (void) magic; + (void) mbi; + + printf("cross-boundary insn at end of address space\n"); + + /* + * The top page (0xfffff000) is SeaBIOS ROM and cannot be written. + * Its byte at 0xffffffff (0x00 =3D "add r/m8, r8") already crosses the + * page boundary into page1 at 0x0, which is exactly the case + * translator_ld must handle without aborting. Reaching 0xfffffffe + * runs the ROM's cld, then that add; the add's modrm is fetched from + * [0x0], which is RAM, so build a short exit stub there: + * + * [0x0] c0 modrm -> "add al, al" (reg; EIP -> 1) + * [1] eb 00 jmp +0 (EIP -> 3) + * [3] b8 00 00 00 00 mov eax, 0 + * [8] e7 f4 out 0xf4, eax -> isa-debug-exit(0) + * + * Without the translator_ld fix QEMU aborts while reading the modrm + * at the wrapped address 0x0 (translator.c assert). + * + * Note: this relies on the SeaBIOS byte at 0xffffffff being 0x00 + * (add r/m8, r8); if that ever changes, the stub below must move. + */ + volatile uint8_t *p =3D (uint8_t *)0x00000000; + p[0] =3D 0xC0; /* modrm: add al, al */ + p[1] =3D 0xEB; p[2] =3D 0x00; /* jmp +0 -> 0x3 */ + /* mov eax, 0 */ + p[3] =3D 0xB8; p[4] =3D 0x00; p[5] =3D 0x00; p[6] =3D 0x00; p[7] =3D 0= x00; + p[8] =3D 0xE7; p[9] =3D 0xF4; /* out 0xf4, eax -> exit 0 */ + + asm volatile("mov $0xFFFFFFFE, %%eax; jmp *%%eax" : : : "eax"); + + return 1; /* unreachable */ +} diff --git a/tests/multiboot/wraparound.out b/tests/multiboot/wraparound.out new file mode 100644 index 0000000000..23cb05ed11 --- /dev/null +++ b/tests/multiboot/wraparound.out @@ -0,0 +1,5 @@ + + +=3D=3D=3D Running test case: wraparound.elf -m 4G =3D=3D=3D + +cross-boundary insn at end of address space --=20 2.43.0