GCC 13 on Lunar exhibits AddressSanitizer/UndefinedBehaviorSanitizer bug that doesn't manifest elsewhere

Bug #2023424 reported by Edward Nolan
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
gcc-13 (Ubuntu)
New
Undecided
Unassigned

Bug Description

When initializing a class with a data member with alignment `__attribute__((aligned(64)))` and enabling both AddressSanitizer and UndefinedBehaviorSanitizer, Ubuntu 23.04's version of g++, 13-20230320-1ubuntu1, triggers UndefinedBehaviorSanitizer warnings on valid code.

One-liner reproduction:

```
docker run ubuntu:23.04 bash -c 'apt-get update && apt-get install -y g++-13 && echo "struct Packet { int a = 0; int b __attribute__((aligned(64))); }; int main() { Packet packet; }" > ./foo.cpp && g++-13 -fsanitize=address -fsanitize=undefined ./foo.cpp && ./a.out'
```

```
foo.cpp:1:8: runtime error: member access within misaligned address 0x7f535a800020 for type 'struct Packet', which requires 64 byte alignment
0x7f535a800020: note: pointer points here
 fe 7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              ^
```

This also occurs if a more recent version, 13.1.0-2ubuntu2~23.04, is installed from the ubuntu-toolchain-r PPA:

```
docker run ubuntu:23.04 bash -c 'apt-get update && apt-get install -y software-properties-common && add-apt-repository ppa:ubuntu-toolchain-r/ppa && apt-get update && apt-get install -y g++-13 && echo "struct Packet { int a = 0; int b __attribute__((aligned(64))); }; int main() { Packet packet; }" > ./foo.cpp && g++-13 -fsanitize=address -fsanitize=undefined ./foo.cpp && ./a.out'
```

The issue does not manifest on Fedora:

```
docker run fedora:38 bash -c 'yum -y update && yum -y install g++ libasan libubsan && echo "struct Packet { int a = 0; int b __attribute__((aligned(64))); }; int main() { Packet packet; }" > ./foo.cpp && g++ -fsanitize=address -fsanitize=undefined ./foo.cpp && ./a.out'
```

Or on Compiler Explorer: https://godbolt.org/z/Ybr6cfEGj

I suspect that an Ubuntu GCC patch is introducing the bug.

Revision history for this message
Edward Nolan (ednolan2) wrote :

This issue is also likely not to be coming from Debian since the `docker run` reproduction doesn't occur when the image used is `debian:sid`

Revision history for this message
Matthias Klose (doko) wrote :

hardening flags are turned on by default in Ubuntu. You can explicitly add -fstack-protector to reproduce it

Revision history for this message
Dimitry Andric (dimitry.unified-streaming.com) wrote :

There is something weird going on here. I'm seeing the same thing with Ubuntu 24.04's gcc 13.2.0-23ubuntu4, after hitting some issues with x264 (which declared a local variable with __attribute__((aligned(64))) but then it actually wasn't aligned as such, and some AVX512 function then segfaults due to unaligned access).

In my case I can compile the following example on Ubuntu 22.04, and the resulting binary asserts:

#undef NDEBUG
#include <assert.h>
#include <stdio.h>
#include <stdint.h>

int main(void)
{
  char c __attribute__((__aligned__(64)));
  uintptr_t addr = (uintptr_t)&c;
  printf("explicitly aligned char: %#lx\n", addr);
  assert(addr % 64 == 0);
  return 0;
}

$ gcc -fsanitize=address asan-align.c -o asan-align

$ ./asan-align
explicitly aligned char: 0x7f6e19000020
asan-align: asan-align.c:11: main: Assertion `addr % 64 == 0' failed.
Aborted

However, running _exactly_ the same binary on Ubuntu 22.04 does not assert. E.g.:

$ ./asan-align
explicitly aligned char: 0x7ffd1fea4e40

So it looks like there is something that causes main()'s stack to be differently aligned. Whether that is due to Ubuntu 22.04 and 24.04 having different crt*.o files, or due to some AddressSanitizer difference, is not clear to me yet.

Revision history for this message
Dimitry Andric (dimitry.unified-streaming.com) wrote :

Eh sorry, I meant in the example that asserts, that I compiled and ran it on Ubuntu 24.04 first! And the same binary does run fine on Ubuntu 22.04.

Revision history for this message
Dimitry Andric (dimitry.unified-streaming.com) wrote :

FWIW I've built stock releases/gcc-13.2.0 locally on a Ubuntu 24.04 box (configured with --disable-multilib --disable-bootstrap --enable-languages=c,c++ --enable-libsanitizer --disable-libquadmath --disable-libgomp --disable-libvtv --disable-werror --disable-nls), and indeed it also reproduces with that. And you need both -fsanitize=address and -fstack-protector:

$ ~/ins/gcc-13.2.0-0-gc891d8dc23e/bin/gcc -fsanitize=address asan-align.c -o asan-align

$ ./asan-align
explicitly aligned variable: 0x7f1241c00040

$ ~/ins/gcc-13.2.0-0-gc891d8dc23e/bin/gcc -fsanitize=address -fstack-protector asan-align.c -o asan-align

$ ./asan-align
explicitly aligned variable: 0x7f869ea00020
asan-align: asan-align.c:11: main: Assertion `addr % 64 == 0' failed.
Aborted

Revision history for this message
Dimitry Andric (dimitry.unified-streaming.com) wrote :

I bisected, and it seems to have regressed with https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=f732bf6a603721f61102a08ad2d023c7c2670870 ["libsanitizer: merge from upstream (0a1bcab9f3bf75c4c5d3e53bafb3eeb80320af46].

Unfortunately, that is a fairly large merge from the upstream sanitizer libraries, so it is not that easy to pinpoint where the culprit is.

I tried very recent gcc master, and there the test with -fsanitize=address -fstack-protector even segfaults! So I guess an upstream gcc bug report is probably the best way forward.

Revision history for this message
Dimitry Andric (dimitry.unified-streaming.com) wrote :

Ok, I found https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110027 : "[11/12 regression] Stack objects with extended alignments (vectors etc) misaligned on detect_stack_use_after_return".

As described in that bug, turning _off_ the ASAN_OPTION detect_stack_use_after_return makes the misalignment go away:

$ ~/ins/gcc-13-103-gf732bf6a603/bin/gcc -fsanitize=address -fstack-protector asan-align.c -o asan-align

$ LD_LIBRARY_PATH=/home/ubuntu/ins/gcc-13-103-gf732bf6a603/lib64 ./asan-align
explicitly aligned variable: 0x7f6c6f100020
asan-align: asan-align.c:11: main: Assertion `addr % 64 == 0' failed.
Aborted

$ LD_LIBRARY_PATH=/home/ubuntu/ins/gcc-13-103-gf732bf6a603/lib64 ASAN_OPTIONS="detect_stack_use_after_return=false" ./asan-align
explicitly aligned variable: 0x7ffe189ec4c0

The fix for master (14.x) is in https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=467898d513e602f5b5fc4183052217d7e6d6e8ab, while it was merged to 13.x in https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=a16d90ec302e588dab5d7d31ccdd7b3fd5c6214e .

I think it should be relatively safe to apply this patch to Ubuntu's gcc packages?

Revision history for this message
Dimitry Andric (dimitry.unified-streaming.com) wrote :

It's pretty strange, but the upstream fix does not seem to work on Ubuntu, at least not on 24.04. I tried Debian Sid, and there the regular gcc-13 package (13.2.0-24) has no trouble at all with the test case: no alignment issue, no segfaults.

Whereas on Ubuntu 24.04, anything after upstream's https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=28219f7f99a80519d1c6ab5e5dc83b4c7f8d7251 (libsanitizer: merge from upstream) and https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=aaf0f12175bfc0a7bdc6c80b8d481fb09ae44e25 (libsanitizer: Apply local patches) just segfaults, e.g.:

Program received signal SIGSEGV, Segmentation fault.
0x00007f5b91d9ba44 in __interception::InterceptFunction (name=0x7f5b91dc5717 "strcat", ptr_to_real=0x7f5b91d44128 <__interception::real_strcat>, func=140031265358128, trampoline=140031265358128)
    at /home/ubuntu/src/gcc/master/libsanitizer/interception/interception_linux.cpp:62
warning: Source file is more recent than executable.
62 *ptr_to_real = (uptr)addr;
(gdb) bt
#0 0x00007f5b91d9ba44 in __interception::InterceptFunction (name=0x7f5b91dc5717 "strcat", ptr_to_real=0x7f5b91d44128 <__interception::real_strcat>, func=140031265358128,
    trampoline=140031265358128) at /home/ubuntu/src/gcc/master/libsanitizer/interception/interception_linux.cpp:62
#1 0x00007f5b91d477d4 in __asan::InitializeAsanInterceptors () at /home/ubuntu/src/gcc/master/libsanitizer/asan/asan_interceptors.cpp:759
#2 0x00007f5b91d5c2b1 in __asan::AsanInitInternal () at /home/ubuntu/src/gcc/master/libsanitizer/asan/asan_rtl.cpp:446
#3 0x00007f5b91d5c819 in __asan_init () at /home/ubuntu/src/gcc/master/libsanitizer/asan/asan_rtl.cpp:626
#4 0x00007f5b92345873 in _dl_init (main_map=0x7f5b923792e0, argc=1, argv=0x7fffed4940b8, env=0x7fffed4940c8) at ./elf/dl-init.c:106
#5 0x00007f5b9235f5a0 in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#6 0x0000000000000001 in ?? ()
#7 0x00007fffed495667 in ?? ()
#8 0x0000000000000000 in ?? ()

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.