From 82bf1f0cf2e092f86ad7fa9de4c3ce5799979c22 Mon Sep 17 00:00:00 2001 From: "Edgar E. Iglesias" Date: Wed, 22 Apr 2026 18:45:06 +0200 Subject: [PATCH] arm64/insn: Avoid undefined behaviour in branch offset decode Branch offset decoding sign-extends the immediate by shifting it left into bit 31 and back. Perform the left shift in uint32_t and cast to int32_t only for the final right shift to avoid UBSAN failures on negative offsets. Fixes: 6dbf3f0e3074 ("xen/arm: arm64: Add helpers to decode and encode branch instructions") Signed-off-by: Edgar E. Iglesias Reviewed-by: Stefano Stabellini (cherry picked from commit 65a99a4063ccac92237f6d2cd45cb94b5574baa9) --- xen/arch/arm/arm64/insn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xen/arch/arm/arm64/insn.c b/xen/arch/arm/arm64/insn.c index 81f7914610..6b97a84ba7 100644 --- a/xen/arch/arm/arm64/insn.c +++ b/xen/arch/arm/arm64/insn.c @@ -225,22 +225,22 @@ u32 __kprobes aarch64_insn_gen_nop(void) */ int32_t aarch64_get_branch_offset(uint32_t insn) { - int32_t imm; + uint32_t imm; if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) { imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn); - return (imm << 6) >> 4; + return (int32_t)(imm << 6) >> 4; } if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) || aarch64_insn_is_bcond(insn)) { imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_19, insn); - return (imm << 13) >> 11; + return (int32_t)(imm << 13) >> 11; } if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) { imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_14, insn); - return (imm << 18) >> 16; + return (int32_t)(imm << 18) >> 16; } /* Unhandled instruction */