[PATCH v3] elf: Fix DTV gap reuse logic (BZ #27135)

Stefan Liebler stli@linux.ibm.com
Thu Jul 15 15:03:39 GMT 2021


On 15/07/2021 15:51, Adhemerval Zanella via Libc-alpha wrote:
> 
> 
> On 15/07/2021 10:36, Stefan Liebler via Libc-alpha wrote:
>> On 14/07/2021 20:11, Adhemerval Zanella via Libc-alpha wrote:
>>>
>>>
>>> On 14/07/2021 13:57, Carlos O'Donell wrote:
>>>> On 7/14/21 9:52 AM, Adhemerval Zanella wrote:
>>>>>
>>>>>
>>>>> On 09/07/2021 12:05, Szabolcs Nagy wrote:
>>>>>> The 07/09/2021 10:50, Adhemerval Zanella wrote:
>>>>>>> Changes from previous version:
>>>>>>>
>>>>>>>   - Fix commit message and add a line about the bug fixes.
>>>>>>>   - Use atomic operation while setting the slotinfo.
>>>>>>>   - Use test_verbose on tst-tls20.c.
>>>>>>>
>>>>>>> ---
>>>>>>>
>>>>>>> This is updated version of the 572bd547d57a (reverted by 40ebfd016ad2)
>>>>>>> that fixes the _dl_next_tls_modid issues.
>>>>>>>
>>>>>>> This issue with 572bd547d57a patch is the DTV entry will be only
>>>>>>> update on dl_open_worker() with the update_tls_slotinfo() call after
>>>>>>> all dependencies are being processed by _dl_map_object_deps().  However
>>>>>>> _dl_map_object_deps() itself might call _dl_next_tls_modid(), and since
>>>>>>> the _dl_tls_dtv_slotinfo_list::map is not yet set the entry will be
>>>>>>> wrongly reused.
>>>>>>>
>>>>>>> This patch fixes by renaming the _dl_next_tls_modid() function to
>>>>>>> _dl_assign_tls_modid() and by passing the link_map so it can set
>>>>>>> the slotinfo value so a so subsequente _dl_next_tls_modid() call will
>>>>>>> see the entry as allocated.
>>>>>>
>>>>>> this paragraph still has 'so a so subsequente'
>>>>>> and i would add the bug number into the first sentence.
>>>>>
>>>>> Fixed.
>>>>>
>>>>>>
>>>>>>>
>>>>>>> The intermediary value is cleared up on remove_slotinfo() for the case
>>>>>>> a library fails to load with RTLD_NOW.
>>>>>>>
>>>>>>> This patch fixes BZ #27135.
>>>>>>>
>>>>>>> Checked on x86_64-linux-gnu.
>>>>>>
>>>>>> the patch looks ok to me, with the commit message
>>>>>> and the comment issue below fixed.
>>>>>>
>>>>>> Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
>>>>>
>>>>> Carlos, is it for push?
>>>>
>>>> It's a non-ABI bug fix, so we can push it. Thanks for asking.
>>>>
>>>
>>> And it is in, let's hope it does not brake anything again ;)
>>>
>>
>> Hi Adhemerval,
>>
>> I'm getting a segfault on s390x in elf/tst-tls20. It is at the end of
>> do_test() when the stack-protector-canary is compared.
>>
>> I'm also getting such an error on x86_64,
>> $ <glibc>/configure --prefix=/usr --enable-stack-protector=strong
>> $ make
>> $ make subdirs=elf check
>> $ make t=elf/tst-tls20 test
>> ...
>> *** stack smashing detected ***: terminated
>> make[2]: Leaving directory 'glibc/elf'
>> FAIL: elf/tst-tls20
>> original exit status 1
>> Didn't expect signal from child: got `Aborted'
>>
>>
>> If configuring without --enable-stack-protector=strong, then
>> elf/tst-tls20 succeeds.
>>
>> Can you please have a look?
> 
> Sigh, it is overlook in array access.  I reproduced it on x86_64 as well, 
> this should fix it:
> 
> diff --git a/elf/tst-tls20.c b/elf/tst-tls20.c
> index d8d04fe574..831c3336c9 100644
> --- a/elf/tst-tls20.c
> +++ b/elf/tst-tls20.c
> @@ -226,12 +226,12 @@ do_test_dependency (void)
>        int mods[nmods];
>        /* We use '0' as indication for a gap, to avoid the dlclose on iteration
>          cleanup.  */
> -      for (int n = 1; n <= nmods; n++)
> +      for (int n = 1; n < nmods; n++)
>         {
>           load_mod (n);
>            mods[n] = n;
>         }
> -      for (int n = 1; n <= nmods; n++)
> +      for (int n = 1; n < nmods; n++)
>         {
>           if (!is_mod_set (g, n))
>             {
> @@ -304,12 +304,12 @@ do_test_invalid_dependency (bool bind_now)
>        int mods[nmods];
>        /* We use '0' as indication for a gap, to avoid the dlclose on iteration
>          cleanup.  */
> -      for (int n = 1; n <= nmods; n++)
> +      for (int n = 1; n < nmods; n++)
>         {
>           load_mod (n);
>            mods[n] = n;
>         }
> -      for (int n = 1; n <= nmods; n++)
> +      for (int n = 1; n < nmods; n++)
>         {
>           if (!is_mod_set (g, n))
>             {
> 

Tested on s390x/s390 with and without --enable-stack-protector=strong.
The test elf/tst-tls20 is now passing.

Thanks,
Stefan


More information about the Libc-alpha mailing list