Skip to content

Commit cd8248f

Browse files
Fixed a bug in -fsanitize-kcfi-arity (#142867)
Compiling with `fsanitize-kcfi-arity` can crash the compiler if a function has more than 6 arguments, including floating-point arguments passed in XMM registers. This patch fixes the feature by only counter integer and stack arguments toward kCFI arity. For example, the compiler crashed when it attempted to generate kCFI arity information for this function: https://github.com/torvalds/linux/blob/16b70698aa3ae7888826d0c84567c72241cf6713/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h#L680 As noted in a comment, floating-point registers are not relevant to enforcing kCFI at this time.
1 parent bb00fd0 commit cd8248f

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

llvm/lib/Target/X86/X86AsmPrinter.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,27 @@ void X86AsmPrinter::emitKCFITypeId(const MachineFunction &MF) {
198198
// Determine the function's arity (i.e., the number of arguments) at the ABI
199199
// level by counting the number of parameters that are passed
200200
// as registers, such as pointers and 64-bit (or smaller) integers. The
201-
// Linux x86-64 ABI allows up to 6 parameters to be passed in GPRs.
201+
// Linux x86-64 ABI allows up to 6 integer parameters to be passed in GPRs.
202202
// Additional parameters or parameters larger than 64 bits may be passed on
203-
// the stack, in which case the arity is denoted as 7.
203+
// the stack, in which case the arity is denoted as 7. Floating-point
204+
// arguments passed in XMM0-XMM7 are not counted toward arity because
205+
// floating-point values are not relevant to enforcing kCFI at this time.
204206
const unsigned ArityToRegMap[8] = {X86::EAX, X86::ECX, X86::EDX, X86::EBX,
205207
X86::ESP, X86::EBP, X86::ESI, X86::EDI};
206-
int Arity = MF.getInfo<X86MachineFunctionInfo>()->getArgumentStackSize() > 0
207-
? 7
208-
: MF.getRegInfo().liveins().size();
208+
int Arity;
209+
if (MF.getInfo<X86MachineFunctionInfo>()->getArgumentStackSize() > 0) {
210+
Arity = 7;
211+
} else {
212+
Arity = 0;
213+
for (const auto &LI : MF.getRegInfo().liveins()) {
214+
auto Reg = LI.first;
215+
if (X86::GR8RegClass.contains(Reg) || X86::GR16RegClass.contains(Reg) ||
216+
X86::GR32RegClass.contains(Reg) ||
217+
X86::GR64RegClass.contains(Reg)) {
218+
++Arity;
219+
}
220+
}
221+
}
209222
DestReg = ArityToRegMap[Arity];
210223
}
211224

llvm/test/CodeGen/X86/kcfi-arity.ll

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,39 @@ entry:
192192
ret void
193193
}
194194

195+
;; Ensure that floating-point values are not counted toward the arity
196+
; ASM-LABEL: __cfi_f12:
197+
; ASM: movl $2253188362, %ebp
198+
define dso_local void @f12(i32 noundef %v1, i32 noundef %v2, float noundef %v3, double noundef %v4, float noundef %v5, i32 noundef %v6, i32 noundef %v7, i32 noundef %v8) #0 !kcfi_type !7 {
199+
entry:
200+
%v1.addr = alloca i32, align 4
201+
%v2.addr = alloca i32, align 4
202+
%v3.addr = alloca float, align 4
203+
%v4.addr = alloca double, align 4
204+
%v5.addr = alloca float, align 4
205+
%v6.addr = alloca i32, align 4
206+
%v7.addr = alloca i32, align 4
207+
%v8.addr = alloca i32, align 4
208+
store i32 %v1, ptr %v1.addr, align 4
209+
store i32 %v2, ptr %v2.addr, align 4
210+
store float %v3, ptr %v3.addr, align 4
211+
store double %v4, ptr %v4.addr, align 4
212+
store float %v5, ptr %v5.addr, align 4
213+
store i32 %v6, ptr %v6.addr, align 4
214+
store i32 %v7, ptr %v7.addr, align 4
215+
store i32 %v8, ptr %v8.addr, align 4
216+
ret void
217+
}
218+
195219
attributes #0 = { "target-features"="+retpoline-indirect-branches,+retpoline-indirect-calls" }
196220

197-
!llvm.module.flags = !{!0, !7}
221+
!llvm.module.flags = !{!0, !8}
198222
!0 = !{i32 4, !"kcfi", i32 1}
199223
!1 = !{i32 12345678}
200224
!2 = !{i32 4196274163}
201225
!3 = !{i32 98693133}
202226
!4 = !{i32 199571451}
203227
!5 = !{i32 1046421190}
204228
!6 = !{i32 1342488295}
205-
!7 = !{i32 4, !"kcfi-arity", i32 1}
229+
!7 = !{i32 2253188362}
230+
!8 = !{i32 4, !"kcfi-arity", i32 1}

0 commit comments

Comments
 (0)