Bug 2130006 - sem_timedwait hang with AddressSanitizer with 32 bit binary
Summary: sem_timedwait hang with AddressSanitizer with 32 bit binary
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: gcc
Version: 8.6
Hardware: All
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Marek Polacek
QA Contact: qe-baseos-tools-bugs
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2022-09-26 21:07 UTC by Paulo Andrade
Modified: 2023-07-18 14:19 UTC (History)
5 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-09-27 16:14:36 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
sem_timedwait.tar (10.00 KB, application/x-tar)
2022-09-26 21:07 UTC, Paulo Andrade
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker RHELPLAN-134942 0 None None None 2022-09-26 21:13:36 UTC

Description Paulo Andrade 2022-09-26 21:07:41 UTC
Created attachment 1914471 [details]
sem_timedwait.tar

In the sample reproducer it is expected to have the output:

thread_func_one loop 1
thread_func_two loop 1
thread_func_one loop 2
thread_func_two loop 2
thread_func_one loop 3
thread_func_two loop 3
thread_func_one loop 4
thread_func_two loop 4
thread_func_one loop 5
thread_func_two loop 5
thread_func_one loop 6
thread_func_two loop 6
thread_func_one loop 7
thread_func_two loop 7
thread_func_one loop 8
thread_func_two loop 8
thread_func_one loop 9
thread_func_one done
thread_func_two loop 9
thread_func_two done
data_one.count=0 data_one.other=0
data_two.count=0 data_two.other=0

Instead, it hangs.

The problem is that libasan is binding to the wrong sem_init symbol.
It is binding to __old_sem_init instead of __new_sem_init.

The issue should be due to libasan not choosing the symbol from
libpthread.

A workaround is to play with the way __new_sem_init works, for example.
use the pseudo patch:

-sem_init(&sem_one, 0,1);
+sem_init(&sem_one, 0,2);

  This is due to glibc code:
...
__new_sem_init (sem_t *sem, int pshared, unsigned int value)
...
#if __HAVE_64B_ATOMICS
  isem->data = value;
#else
  isem->value = value << SEM_VALUE_SHIFT;
  /* pad is used as a mutex on pre-v9 sparc and ignored otherwise.  */
  isem->pad = 0;
  isem->nwaiters = 0;
#endif
...

SEM_VALUE_SHIFT is one.

Comment 1 Marek Polacek 2022-09-26 21:19:08 UTC
I see the same thing with F36 gcc (libasan-12.2.1-2.fc36.i686).  So it looks like it needs to be fixed upstream first, if it's a real bug.

Comment 2 Jakub Jelinek 2022-09-26 23:04:41 UTC
There is COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN macro that can be used instead of COMMON_INTERCEPT_FUNCTION, but it is used only for a few interceptors, I'm afraid i?86-linux needs far more than that.
readelf -Ws /lib/libc.so.6  | grep '[^@]@[^@]' | grep -v GLIBC_PRIVATE | awk '{print $NF}' | sort -u
shows a lot of symbols.
Of course not everything is intercepted etc.

Comment 3 Marek Polacek 2022-09-27 16:14:36 UTC
Reproduced with clang as well, upstream issue opened:
https://github.com/llvm/llvm-project/issues/58023

So this needs to be fixed in upstream first; closing this RHBZ thus.


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