mirror of
https://sourceware.org/git/glibc.git
synced 2025-09-11 12:10:50 +03:00
elf: Fix DTV gap reuse logic (BZ #27135)
This is updated version of the572bd547d5
(reverted by40ebfd016a
) that fixes the _dl_next_tls_modid issues. This issue with572bd547d5
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 subsequente _dl_next_tls_modid() call will see the entry as allocated. 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. Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
This commit is contained in:
17
elf/dl-tls.c
17
elf/dl-tls.c
@@ -126,8 +126,8 @@ oom (void)
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
_dl_next_tls_modid (void)
|
||||
void
|
||||
_dl_assign_tls_modid (struct link_map *l)
|
||||
{
|
||||
size_t result;
|
||||
|
||||
@@ -157,7 +157,11 @@ _dl_next_tls_modid (void)
|
||||
}
|
||||
|
||||
if (result - disp < runp->len)
|
||||
break;
|
||||
{
|
||||
/* Mark the entry as used, so any dependency see it. */
|
||||
atomic_store_relaxed (&runp->slotinfo[result - disp].map, l);
|
||||
break;
|
||||
}
|
||||
|
||||
disp += runp->len;
|
||||
}
|
||||
@@ -184,17 +188,14 @@ _dl_next_tls_modid (void)
|
||||
atomic_store_relaxed (&GL(dl_tls_max_dtv_idx), result);
|
||||
}
|
||||
|
||||
return result;
|
||||
l->l_tls_modid = result;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
_dl_count_modids (void)
|
||||
{
|
||||
/* It is rare that we have gaps; see elf/dl-open.c (_dl_open) where
|
||||
we fail to load a module and unload it leaving a gap. If we don't
|
||||
have gaps then the number of modids is the current maximum so
|
||||
return that. */
|
||||
/* The count is the max unless dlclose or failed dlopen created gaps. */
|
||||
if (__glibc_likely (!GL(dl_tls_dtv_gaps)))
|
||||
return GL(dl_tls_max_dtv_idx);
|
||||
|
||||
|
Reference in New Issue
Block a user