From: sashiko-bot@kernel.org
To: "Kiryl Shutsemau" <kirill@shutemov.name>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v6 3/3] x86/tdx: Fix zero-extension for 32-bit port I/O
Date: Mon, 13 Jul 2026 13:51:08 +0000 [thread overview]
Message-ID: <20260713135109.1DA951F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260713133753.223947-4-kirill@shutemov.name>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] The TDX #VE handler for the CPUID instruction fails to zero the upper 32 bits of the destination registers, exposing the guest to potentially malicious or garbage data from the VMM.
- [High] The TDX #VE handler for MMIO reads fails to zero the upper 32 bits of the destination register for 32-bit MOVZX and MOVSX instructions.
- [High] The TDX #VE handler for MSR writes corrupts the MSR data sent to the VMM if the guest's RAX register contains non-zero upper 32 bits.
--
--- Patch [3]: [PATCH v6 3/3] x86/tdx: Fix zero-extension for 32-bit port I/O ---
commit 54fa9007fcfc0403e17720722b833050a2d55438
Author: Kiryl Shutsemau (Meta) <kas@kernel.org>
x86/tdx: Fix zero-extension for 32-bit port I/O
This commit updates handle_in() to use insn_assign_reg() for 32-bit port IN
instructions. This ensures proper partial-register-write semantics where
4-byte forms correctly zero-extend to the full 64-bit register.
Link: https://lore.kernel.org/all/CAKw_Dz96rfSQc6Rn+9QBcUFHhmkK+9zu+P=bxowfZwxrATCBRg@mail.gmail.com/
> diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
> index b8bbd715fb624..f904a636d449b 100644
> --- a/arch/x86/coco/tdx/tdx.c
> +++ b/arch/x86/coco/tdx/tdx.c
> @@ -703,11 +703,9 @@ static bool handle_in(struct pt_regs *regs, int size, int port)
> * "TDG.VP.VMCALL<Instruction.IO>".
> */
> success = !__tdx_hypercall(&args);
> + val = success ? args.r11 : 0;
>
> - /* Update part of the register affected by the emulated instruction */
> - regs->ax &= ~mask;
> - if (success)
> - regs->ax |= args.r11 & mask;
> + insn_assign_reg(®s->ax, val, size);
>
> return success;
> }
[Severity: High]
This is a pre-existing issue, but since you are fixing zero-extension issues
in this file, I noticed another zero-extension problem in handle_mmio() for
32-bit destination registers.
If a guest executes an instruction like MOVZX EAX, BYTE PTR [mem], the #VE
handler calculates extend_size:
arch/x86/coco/tdx/tdx.c:handle_mmio() {
...
case INSN_MMIO_READ_ZERO_EXTEND:
/* Zero extend based on operand size */
extend_size = insn.opnd_bytes;
break;
...
}
If insn.opnd_bytes is 4, doesn't this cause the subsequent memset to only
clear the lower 4 bytes of regs->ax, leaving the upper 32 bits containing
stale data and violating x86-64 architecture rules?
[Severity: High]
This isn't a bug introduced by this patch, but does handle_cpuid() have a
similar problem with zero-extending registers?
When a guest executes CPUID, it traps to the #VE handler. handle_cpuid()
copies the VMM hypercall results directly into the registers:
arch/x86/coco/tdx/tdx.c:handle_cpuid() {
...
regs->ax = args.r12;
regs->bx = args.r13;
regs->cx = args.r14;
regs->dx = args.r15;
...
}
Could an untrusted VMM inject non-zero data into the upper 32 bits of these
registers and violate x86-64 CPUID semantics since they are not being
zero-extended?
[Severity: High]
This is also a pre-existing issue, but could write_msr() corrupt the MSR
data sent to the VMM if the guest's RAX register contains non-zero upper
32 bits?
The payload for WRMSR is constructed like this:
arch/x86/coco/tdx/tdx.c:write_msr() {
...
struct tdx_module_args args = {
...
.r13 = (u64)regs->dx << 32 | regs->ax,
};
...
}
Since WRMSR ignores the upper 32 bits of RAX, the architecture permits
garbage in them. Because regs->ax is not cast to a 32-bit integer before
the bitwise-OR, won't any set bits in its upper 32 bits bleed into the
EDX portion of the payload?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260713133753.223947-1-kirill@shutemov.name?part=3
next prev parent reply other threads:[~2026-07-13 13:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-13 13:37 [PATCH v6 0/3] x86/tdx: Fix port I/O handling bugs Kiryl Shutsemau
2026-07-13 13:37 ` [PATCH v6 1/3] x86/tdx: Fix off-by-one in port I/O handling Kiryl Shutsemau
2026-07-13 13:50 ` sashiko-bot
2026-07-13 21:46 ` [tip: x86/tdx] " tip-bot2 for Kiryl Shutsemau (Meta)
2026-07-13 13:37 ` [PATCH v6 2/3] x86/insn-eval: Move assign_register() out of KVM as insn_assign_reg() Kiryl Shutsemau
2026-07-13 21:46 ` [tip: x86/tdx] " tip-bot2 for Kiryl Shutsemau (Meta)
2026-07-13 13:37 ` [PATCH v6 3/3] x86/tdx: Fix zero-extension for 32-bit port I/O Kiryl Shutsemau
2026-07-13 13:51 ` sashiko-bot [this message]
2026-07-13 21:46 ` [tip: x86/tdx] " tip-bot2 for Kiryl Shutsemau (Meta)
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=20260713135109.1DA951F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=kirill@shutemov.name \
--cc=kvm@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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.