Bug 2397265

Summary: Regression: safe-stack+cfi fails to link since f41
Product: [Fedora] Fedora Reporter: Marc-Andre Lureau <marcandre.lureau>
Component: clang18Assignee: Jens Petersen <petersen>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: unspecified    
Version: 43CC: berrange, petersen
Target Milestone: ---Keywords: Regression
Target Release: ---Flags: petersen: needinfo? (marcandre.lureau)
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Marc-Andre Lureau 2025-09-22 10:12:25 UTC
In fc40, clang 18.1.8-2.fc40, this command succeeded:
$ clang test.c -flto -fsanitize=cfi-icall -fno-sanitize-trap=cfi-icall  -fsanitize=safe-stack

Since fc41, it fails with:
/usr/bin/ld: /usr/bin/../lib/clang/20/lib/x86_64-redhat-linux-gnu/libclang_rt.safestack.a(safestack.cpp.o): in function `__sanitizer_internal_memcpy':
(.text.__sanitizer_internal_memcpy+0x0): multiple definition of `__sanitizer_internal_memcpy'; /usr/bin/../lib/clang/20/lib/x86_64-redhat-linux-gnu/libclang_rt.ubsan_standalone.a(sanitizer_libc.cpp.o):(.text.__sanitizer_internal_memcpy+0x0): first defined here
/usr/bin/ld: /usr/bin/../lib/clang/20/lib/x86_64-redhat-linux-gnu/libclang_rt.safestack.a(safestack.cpp.o): in function `__sanitizer_internal_memmove':
(.text.__sanitizer_internal_memmove+0x0): multiple definition of `__sanitizer_internal_memmove'; /usr/bin/../lib/clang/20/lib/x86_64-redhat-linux-gnu/libclang_rt.ubsan_standalone.a(sanitizer_libc.cpp.o):(.text.__sanitizer_internal_memmove+0x0): first defined here
/usr/bin/ld: /usr/bin/../lib/clang/20/lib/x86_64-redhat-linux-gnu/libclang_rt.safestack.a(safestack.cpp.o): in function `__sanitizer_internal_memset':
(.text.__sanitizer_internal_memset+0x0): multiple definition of `__sanitizer_internal_memset'; /usr/bin/../lib/clang/20/lib/x86_64-redhat-linux-gnu/libclang_rt.ubsan_standalone.a(sanitizer_libc.cpp.o):(.text.__sanitizer_internal_memset+0x0): first defined here
clang: error: linker command failed with exit code 1 (use -v to see invocation)

This is an issue hit with QEMU when both "cfi_debug" and "safe_stack" are enabled.

Reproducible: Always

Comment 1 Jens Petersen 2025-09-24 07:56:25 UTC
Does it happen with newer Fedora and/or clang? (F40 is already EOL)

I don't have time to work on older clang proactively but if there are upstream fixes we can integration that can be an option.

Comment 2 Jens Petersen 2025-09-24 07:57:46 UTC
Sorry misread: you were saying it work on f40 but not f41+.

How about version 19 or later?  Not sure if there is a new upstream minor release.

Comment 3 Daniel Berrangé 2025-09-24 13:43:57 UTC
(In reply to Jens Petersen from comment #2)
> Sorry misread: you were saying it work on f40 but not f41+.

Correct.
 
> How about version 19 or later?  Not sure if there is a new upstream minor
> release.

It fails on Fedora rawhide too with clang 21, and F42 with clang 20

$ rpm -q clang
clang-21.1.1-1.fc44.x86_64
$ clang  -o test test.c -flto -fsanitize=cfi-icall -fno-sanitize-trap=cfi-icall  -fsanitize=safe-stack 
/usr/bin/ld: /usr/bin/../lib/clang/21/lib/x86_64-redhat-linux-gnu/libclang_rt.safestack.a(safestack.cpp.o): in function `__sanitizer_internal_memcpy':
(.text.__sanitizer_internal_memcpy+0x0): multiple definition of `__sanitizer_internal_memcpy'; /usr/bin/../lib/clang/21/lib/x86_64-redhat-linux-gnu/libclang_rt.ubsan_standalone.a(sanitizer_libc.cpp.o):(.text.__sanitizer_internal_memcpy+0x0): first defined here
/usr/bin/ld: /usr/bin/../lib/clang/21/lib/x86_64-redhat-linux-gnu/libclang_rt.safestack.a(safestack.cpp.o): in function `__sanitizer_internal_memmove':
(.text.__sanitizer_internal_memmove+0x0): multiple definition of `__sanitizer_internal_memmove'; /usr/bin/../lib/clang/21/lib/x86_64-redhat-linux-gnu/libclang_rt.ubsan_standalone.a(sanitizer_libc.cpp.o):(.text.__sanitizer_internal_memmove+0x0): first defined here
/usr/bin/ld: /usr/bin/../lib/clang/21/lib/x86_64-redhat-linux-gnu/libclang_rt.safestack.a(safestack.cpp.o): in function `__sanitizer_internal_memset':
(.text.__sanitizer_internal_memset+0x0): multiple definition of `__sanitizer_internal_memset'; /usr/bin/../lib/clang/21/lib/x86_64-redhat-linux-gnu/libclang_rt.ubsan_standalone.a(sanitizer_libc.cpp.o):(.text.__sanitizer_internal_memset+0x0): first defined here
clang: error: linker command failed with exit code 1 (use -v to see invocation)

$ cat test.c
#include <stdio.h>

int main(void) {

  printf("%d\n", 82);
  return 0;
}


FYI, this was observed first when trying to build QEMU in our CI system. We built QEMU with clang with both SafeStack and CFI debug enabled (the 'CFI debug' QEMU option tells QEMU to add "-fno-sanitize-trap=cfi-icall" to compiler/linker flags). Our CI passed when run on Fedora 40, but failed when we updated to Fedora 41, unless removing the '-fno-sanitize-trap=cfi-icall' arg.