Bug 1827338 - -fsanitize=address seems to mask linker errors causing unexpected crashes in compiled binaries
Summary: -fsanitize=address seems to mask linker errors causing unexpected crashes in...
Keywords:
Status: CLOSED EOL
Alias: None
Product: Fedora
Classification: Fedora
Component: compiler-rt
Version: 37
Hardware: Unspecified
OS: Unspecified
unspecified
medium
Target Milestone: ---
Assignee: serge_sans_paille
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2020-04-23 16:53 UTC by Frantisek Sumsal
Modified: 2023-12-05 20:59 UTC (History)
5 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2023-12-05 20:59:20 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Frantisek Sumsal 2020-04-23 16:53:35 UTC
Description of problem:
LLVM 10 with the respective runtime libraries appears to have an interesting issue, where using `-fsanitize=address` and omitting some otherwise necessary linker flags makes the compilation pass, but upon executing the compiled binary ASan dies with SIGSEGV.

Version-Release number of selected component (if applicable):
llvm-10.0.0-2.fc33.x86_64
clang-10.0.0-1.fc33.x86_64
compiler-rt-10.0.0-1.fc33.x86_64

How reproducible:
always

Steps to Reproduce:
# cat >> main.c << EOF
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <crypt.h>

int main(void) {
	struct crypt_data data = {};
	char *r = NULL;

	r = crypt_r("helo", "there", &data);
	printf("%s\n", r);

	return 0;
}
EOF

1) Expected error (without ASan and necessary -lcrypt):
# clang  -o main main.c
/usr/bin/ld: /tmp/main-e512d8.o: in function `main':
main.c:(.text+0x59): undefined reference to `crypt_r'
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)

2) Working example (without ASan + -lcrypt):
# clang -lcrypt -o main main.c
# ./main
thuM9s02x7C8M

3) Unexpected pass (ASan + missing -lcrypt):
# clang -fsanitize=address -o main main.c
# ./main
AddressSanitizer:DEADLYSIGNAL
=================================================================
==37096==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffed20fdd30 sp 0x7ffed20fd4c8 T0)
==37096==Hint: pc points to the zero page.
==37096==The signal is caused by a READ memory access.
==37096==Hint: address points to the zero page.
    #0 0x0  (<unknown module>)
    #1 0x7f68380f069f  (/lib64/libpthread.so.0+0x1469f)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==37096==ABORTING

4) Expected pass (ASan + lcrypt)
# clang -lcrypt -fsanitize=address -o main main.c
# ./main
thuM9s02x7C8M

Step #3 is definitely unexpected and breaks library detection in build systems when ASan is enabled.

Comment 1 serge_sans_paille 2020-04-24 09:31:27 UTC
I can confirm 1), 2) and 3), and attest that it has been introduced with LLVM10, as showcased by this godblot run: https://godbolt.org/z/p9ikW8

Comment 2 Frantisek Sumsal 2020-05-15 13:08:46 UTC
Looks like ASan in GCC 10 picked up the problematic change as well:

# gcc -fsanitize=address -o main main.c
# ./main 
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1895==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffe035cd2a0 sp 0x7ffe035cca28 T0)
==1895==Hint: pc points to the zero page.
==1895==The signal is caused by a READ memory access.
==1895==Hint: address points to the zero page.
    #0 0x0  (<unknown module>)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==1895==ABORTING
# rpm -q gcc libasan
gcc-10.1.1-1.fc33.x86_64
libasan-10.1.1-1.fc33.x86_64

Comment 3 Frantisek Sumsal 2020-05-15 17:08:35 UTC
Also, I noticed another mildly infuriating thing, which is probably related to the above issue.

As I tried to workaround this, since right now we can't use either compiler to test systemd under sanitizers, I noticed that `-lcrypt` is already used, yet the resulting binary has no `libcrypt` reference. The relevant part of the cc's command line (generated by meson) looks like this:

-fsanitize=address,undefined -Wl,--as-needed -Wl,--no-undefined -Wl,-z,relro -Wl,-z,now -fstack-protector -Wl,--gc-sections -Wl,--start-group src/shared/libsystemd-shared-245.so -pthread -lcrypt /usr/lib/libssl.so /usr/lib/libcrypto.so /usr/lib/libpwquality.so -Wl,--end-group

If I shrink it into a minimal example, it looks like this:

-fsanitize=address -Wl,--as-needed -Wl,--start-group -lcrypt -Wl,--end-group

This, with gcc/clang 9.x fails as expected:
# clang -fsanitize=address -Wl,--as-needed -Wl,--start-group -lcrypt -Wl,--end-group -o main main.c
/usr/bin/ld: /tmp/main-a14b1f.o: in function `main':
main.c:(.text+0x15f): undefined reference to `crypt_r'
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)

# gcc -fsanitize=address -Wl,--as-needed -Wl,--start-group -lcrypt -Wl,--end-group -o main main.c
/usr/bin/ld: /tmp/ccO5SyXX.o: in function `main':
main.c:(.text+0x15d): undefined reference to `crypt_r'
collect2: error: ld returned 1 exit status


however with gcc/clang 10.x the compilation passes, but the resulting binary crashes as before, since it's apparently not linked against libcrypt's DSO:
# clang -fsanitize=address -Wl,--as-needed -Wl,--start-group -lcrypt -Wl,--end-group -o main main.c
# ./main
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1575==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffd11ba1b30 sp 0x7ffd11ba12c8 T0)
==1575==Hint: pc points to the zero page.
==1575==The signal is caused by a READ memory access.
==1575==Hint: address points to the zero page.
    #0 0x0  (<unknown module>)
    #1 0x7f499270b6ef  (/lib64/libpthread.so.0+0x146ef)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==1575==ABORTING
# ldd main | grep crypt; echo $?
1


Dropping -Wl,--as-needed (or calling meson with LDFLAGS="-Wl,--no-as-needed" in my case) makes everything work properly once again.

Comment 4 Frantisek Sumsal 2020-05-15 18:11:41 UTC
Scratch that last comment, it's just a variation of the aforementioned issue - --Wl,--as-needed is in the "unsanitized" run as well, yet it works because -lcrypt is correctly propagated/added to the other targets. Sorry for the noise.

Comment 5 serge_sans_paille 2020-07-31 09:08:20 UTC
I have a preliminary patch submited upstream, and will discuss a more generic solution with the code owners.

https://reviews.llvm.org/D85011

Comment 6 Ben Cotton 2020-08-11 15:27:29 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 33 development cycle.
Changing version to 33.

Comment 7 Ben Cotton 2021-11-04 17:36:24 UTC
This message is a reminder that Fedora 33 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora 33 on 2021-11-30.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
Fedora 'version' of '33'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 33 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 8 Ben Cotton 2021-11-30 16:19:04 UTC
Fedora 33 changed to end-of-life (EOL) status on 2021-11-30. Fedora 33 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.

Comment 9 Ben Cotton 2022-02-08 21:24:17 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 36 development cycle.
Changing version to 36.

Comment 10 Mamoru TASAKA 2022-03-23 13:47:02 UTC
Same on rawhide.

Comment 11 Ben Cotton 2022-08-09 13:10:54 UTC
This bug appears to have been reported against 'rawhide' during the Fedora Linux 37 development cycle.
Changing version to 37.

Comment 12 Tom Stellard 2023-10-14 01:14:31 UTC
It looks like this bug is unlikely to be fixed upstream.  Does this cause all library detection routines to fail or just the ones that check for libcrypt?

Comment 13 Aoife Moloney 2023-11-23 00:03:06 UTC
This message is a reminder that Fedora Linux 37 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora Linux 37 on 2023-12-05.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
'version' of '37'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, change the 'version' 
to a later Fedora Linux version. Note that the version field may be hidden.
Click the "Show advanced fields" button if you do not see it.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora Linux 37 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora Linux, you are encouraged to change the 'version' to a later version
prior to this bug being closed.

Comment 14 Aoife Moloney 2023-12-05 20:59:20 UTC
Fedora Linux 37 entered end-of-life (EOL) status on None.

Fedora Linux 37 is no longer maintained, which means that it
will not receive any further security or bug fix updates. As a result we
are closing this bug.

If you can reproduce this bug against a currently maintained version of Fedora Linux
please feel free to reopen this bug against that version. Note that the version
field may be hidden. Click the "Show advanced fields" button if you do not see
the version field.

If you are unable to reopen this bug, please file a new report against an
active release.

Thank you for reporting this bug and we are sorry it could not be fixed.


Note You need to log in before you can comment on or make changes to this bug.