[llvm] [LFI][AArch64] Fix Segfault due to infinite recursion in LFI rewriter (PR #210267)

Sharjeel Khan via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 17 01:12:20 PDT 2026


https://github.com/Sharjeel-Khan created https://github.com/llvm/llvm-project/pull/210267

When emitting a deferred LR guard, if debug info is enabled, the emission of the guard instruction can trigger temporary labels (e.g. for DWARF line entries), which recursively calls onLabel. Since DeferredLRGuard was only set to false after emission, the nested call would re-emit the guard, causing infinite recursion which leads to a SegFault due to stack overflow. This was detected compiling ubsan_minimal_handlers.cpp in compiler-rt. I fixed it by setting DeferredLRGuard = false before emitting the guard.

>From 8cdce186f4503d8099e142cd4a17625d2086360d Mon Sep 17 00:00:00 2001
From: Sharjeel Khan <sharjeelkhan at google.com>
Date: Thu, 16 Jul 2026 23:21:03 +0000
Subject: [PATCH] [LFI][AArch64] Fix Segfault due to infinite recursion in LFI
 rewriter

When emitting a deferred LR guard, if debug info is enabled, the
emission of the guard instruction can trigger temporary labels (e.g. for
DWARF line entries). This recursively calls onLabel. Since
DeferredLRGuard was only set to false after emission, the nested call
would re-emit the guard, causing infinite recursion which leads to a
SegFault due to stack overflow. This was detected compiling
ubsan_minimal_handlers.cpp in compiler-rt. I fixed it by setting
DeferredLRGuard = false before emitting the guard.
---
 .../AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp   |  6 +++---
 llvm/test/MC/AArch64/LFI/debug-info.s               | 13 +++++++++++++
 2 files changed, 16 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/MC/AArch64/LFI/debug-info.s

diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp
index 3c24f5ab62a61..98d82aa43eed3 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp
@@ -301,8 +301,8 @@ void AArch64MCLFIRewriter::onLabel(const MCSymbol *, MCStreamer &Out) {
   // Flush a deferred LR guard before the label, since the label is a potential
   // branch target and code reached through it may use LR for control flow.
   if (DeferredLRGuard && LastSTI) {
-    emitAddMask(AArch64::LR, AArch64::LR, Out, *LastSTI);
     DeferredLRGuard = false;
+    emitAddMask(AArch64::LR, AArch64::LR, Out, *LastSTI);
   }
 
   // Invalidate guard state since the label is a potential branch target.
@@ -312,8 +312,8 @@ void AArch64MCLFIRewriter::onLabel(const MCSymbol *, MCStreamer &Out) {
 void AArch64MCLFIRewriter::finish(MCStreamer &Out) {
   // Flush a deferred LR guard at the end of the stream.
   if (DeferredLRGuard && LastSTI) {
-    emitAddMask(AArch64::LR, AArch64::LR, Out, *LastSTI);
     DeferredLRGuard = false;
+    emitAddMask(AArch64::LR, AArch64::LR, Out, *LastSTI);
   }
 }
 
@@ -948,8 +948,8 @@ void AArch64MCLFIRewriter::doRewriteInst(const MCInst &Inst, MCStreamer &Out,
   // modified LR is sandboxed before it can be used to transfer control.
   if (DeferredLRGuard && (isReturn(Inst) || isIndirectBranch(Inst) ||
                           isCall(Inst) || isBranch(Inst))) {
-    emitAddMask(AArch64::LR, AArch64::LR, Out, STI);
     DeferredLRGuard = false;
+    emitAddMask(AArch64::LR, AArch64::LR, Out, STI);
   }
 
   // PAC authenticated branches/calls expand to authenticate + guarded branch.
diff --git a/llvm/test/MC/AArch64/LFI/debug-info.s b/llvm/test/MC/AArch64/LFI/debug-info.s
new file mode 100644
index 0000000000000..9c6efbd79f6a2
--- /dev/null
+++ b/llvm/test/MC/AArch64/LFI/debug-info.s
@@ -0,0 +1,13 @@
+// RUN: llvm-mc -triple aarch64_lfi -filetype=obj %s -o /dev/null
+// RUN: llvm-mc -triple aarch64_lfi %s | FileCheck %s
+
+// CHECK:      mov	x30, x0
+// CHECK:      add	x30, x27, w30, uxtw
+// CHECK:      next_func:
+// CHECK-NEXT: nop
+
+.file 1 "debug-info.s"
+mov x30, x0
+.loc 1 10 0
+next_func:
+  nop



More information about the llvm-commits mailing list