[PATCH] fix ldd segfault
Dmitry V. Levin
ldv@altlinux.org
Sun Jan 13 15:04:00 GMT 2008
Hi,
_dl_check_map_versions() contains an optimization for trace mode which in
certain circumstances may lead to improper highest version index
initialization and segfault in trace mode:
Program received signal SIGSEGV, Segmentation fault.
0x0000555555561722 in _dl_check_map_versions (map=0x2aaaaaaab000, verbose=1, trace_mode=1)
at dl-version.c:328
328 map->l_versions[ndx].filename = &strtab[ent->vn_file];
Original bug report (in Russian):
https://bugzilla.altlinux.org/show_bug.cgi?id=11271
Proposed fix is attached.
--
ldv
-------------- next part --------------
2008-01-13 Dmitry V. Levin <ldv@altlinux.org>
* elf/dl-version.c (_dl_check_map_versions): Compare version
inidices for all dependency symbols in trace mode as well.
This fixes highest version index initialization in trace mode.
--- libc/elf/dl-version.c
+++ libc/elf/dl-version.c
@@ -229,15 +229,15 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
and no stub entry was created. This should never happen. */
assert (needed != NULL);
- /* Make sure this is no stub we created because of a missing
- dependency. */
- if (__builtin_expect (! trace_mode, 1)
- || ! __builtin_expect (needed->l_faked, 0))
+ /* NEEDED is the map for the file we need. Now look for the
+ dependency symbols. */
+ aux = (ElfW (Vernaux) *) ((char *) ent + ent->vn_aux);
+ while (1)
{
- /* NEEDED is the map for the file we need. Now look for the
- dependency symbols. */
- aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
- while (1)
+ /* Make sure this is no stub we created because of a missing
+ dependency. */
+ if (__builtin_expect (!trace_mode, 1)
+ || !__builtin_expect (needed->l_faked, 0))
{
/* Match the symbol. */
result |= match_symbol ((*map->l_name
@@ -246,18 +246,18 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
strtab + aux->vna_name,
needed->l_real, verbose,
aux->vna_flags & VER_FLG_WEAK);
+ }
- /* Compare the version index. */
- if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high)
- ndx_high = aux->vna_other & 0x7fff;
+ /* Compare the version index. */
+ if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high)
+ ndx_high = aux->vna_other & 0x7fff;
- if (aux->vna_next == 0)
- /* No more symbols. */
- break;
+ if (aux->vna_next == 0)
+ /* No more symbols. */
+ break;
- /* Next symbol. */
- aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next);
- }
+ /* Next symbol. */
+ aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next);
}
if (ent->vn_next == 0)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20080113/cc5aef9b/attachment.sig>
More information about the Libc-alpha
mailing list