[Bug dynamic-link/21349] race condition between dl_open and rtld lazy symbol resolve

xujing99 at huawei dot com sourceware-bugzilla@sourceware.org
Mon Apr 19 06:19:23 GMT 2021


https://sourceware.org/bugzilla/show_bug.cgi?id=21349

xujing <xujing99 at huawei dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |xujing99 at huawei dot com

--- Comment #9 from xujing <xujing99 at huawei dot com> ---
(In reply to Maninder Singh from comment #5)
> Test case to reproduce issue. (But issue is reproduced on specific ARM
> target not on x86). on ARM reproduced veru easily with this testcase.
> 
> 
> =========
> library 1
> =========
> 
> $ cat libA.c
> // C program to demonstrate working of
> // __attribute__((constructor)) and
> // __attribute__((destructor))
> #include<stdio.h>
> #include<malloc.h>
> #include<pthread.h>
> 
> #define FALSE 0
> #define TRUE 1
> typedef struct test_task
> {
>         pthread_t       stThreadId;
>         pthread_attr_t  stAttr;
>         unsigned char   u8StopThread;
> 
> } TEST_TASK;
> 
> 
> 
> // Assigning functions to be executed before and
> // after main()
> void __attribute__((constructor)) calledFirst();
> void __attribute__((destructor)) calledLast();
> 
> void * lib_Tsk(void * p)
> {
>         int i = 0;
>         char * ptr;
>         struct ifaddrs *ifaddr, *ifa;
> 
>         usleep(1);
> 
>         printf("I am in Thread \n");
>         ptr = malloc(100);
>         free(ptr);
>         sleep(1);
>         if (getifaddrs(&ifaddr) == -1) {
>                 perror("getifaddrs");
>                 return ;
>         }
>         while(1);
> }
> 
> static void *task_create(void *arg)
> {
>         int iRet = FALSE;
>         int iErr = 0;
> 
>         TEST_TASK stTskCtrl;
> 
> 
>         iErr = pthread_attr_init(&stTskCtrl.stAttr);
>         if (iErr != 0)
>         {
>                 printf("[%s]Fail to create task\n", __FUNCTION__);
>                 goto END_TASK_INIT;
>         }
> 
>         iErr = pthread_attr_setdetachstate(&stTskCtrl.stAttr,
> PTHREAD_CREATE_DETACHED);
>         if (iErr != 0)
>         {
>                 printf("[%s]Fail to create task\n", __FUNCTION__);
>                 goto END_TASK_INIT;
>         }
> 
>         iErr = pthread_create(&stTskCtrl.stThreadId, &stTskCtrl.stAttr,
> lib_Tsk, NULL);
>         if (iErr != 0)
>         {
>                 printf("[%s]Fail to create task\n", __FUNCTION__);
>                 goto END_TASK_INIT;
>         }
> 
>         iRet = TRUE;
> 
> END_TASK_INIT:
>         return;
> }
> 
> 
> 
> // This function is assigned to execute before
> // main using __attribute__((constructor))
> void calledFirst()
> {
>         task_create(NULL);
> }
> 
> // This function is assigned to execute after
> // main using __attribute__((destructor))
> void calledLast()
> {
>         printf("\nI am called last");
> }
> 
> =========
> library 2
> =========
> 
> $ cat libB.c
> // C program to demonstrate working of
> // __attribute__((constructor)) and
> // __attribute__((destructor))
> #include<stdio.h>
> #include <dlfcn.h>
> 
> // Assigning functions to be executed before and
> // after main()
> void __attribute__((constructor)) First();
> 
> // This function is assigned to execute before
> // main using __attribute__((constructor))
> void First()
> {
>         void * pHandle = dlopen("./usr/dummy/lib/libB.so", RTLD_LAZY);
> 
>         if(pHandle == NULL) {
>                 printf("Unable to dlopen libB.so\n");
>                 return;
>         }
>         dlclose(pHandle);
> 
> }
> 
> // This function is assigned to execute after
> // main using __attribute__((destructor))
> void calledLast()
> {
>     printf("\nI am called last");
> }
> 
> =======
> main
> =======
> 
> $ cat main.c
> #include <stdio.h>
> 
> void main() {
>         printf("main");
> 
> }
> 
> 
> compilation steps:-
> 
> gcc -shared -fpic libA.c -o libA.so -lpthread
> gcc -shared -fpic libB.c -o libB.so -ldl
> gcc -Wl,--no-as-needed  main.c -lB -lA -L.
> 
> 
> Execution steps:-
> $ cp a.out libA.so libB.so ~/test/
> $ cd test
> $ mkdir -p ./usr/dummy/lib/
> $ cd ./usr/dummy/lib/
> $ ln -s ../../../libtvs.so libtvs.so 
> $ cd ~/test/
> $
> 
> Now run a.out in while (1)
> 
> while [ 1 ]
> do
>      ./a.out
> done
> 
> 
> =====================================
> 
> 
> Issue logs:-
> 
> Core was generated by `./a.out'.
> Program terminated with signal SIGSEGV, Segmentation fault.
> #0  strcmp () at ../sysdeps/arm/armv7/strcmp.S:183
> 183     ../sysdeps/arm/armv7/strcmp.S: No such file or directory.
> [Current thread is 1 (Thread 0xb678c470 (LWP 25189))]
> (gdb) bt
> #0  strcmp () at ../sysdeps/arm/armv7/strcmp.S
> #1  _dl_name_match_p (name=0xb67ac54d "libc.so.6",
>     map=map@entry=0xb67ce6c8) at dl-misc.c
> ...

Is libtvs.so necessary, I can't reproduce without it. In addition, I run the
testcase on aarch64.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Glibc-bugs mailing list