[Pkg-cmake-team] Bug#820334: Segfaults caused by new DT_MIPS_RLD_MAP_REL tag and RPATH removers

Mathieu Malaterre malat at debian.org
Sat Apr 9 11:22:09 UTC 2016


Thanks to aurel32 at d.o chrpath has been fixed. Could an equivalent
patch be included in cmake ?

On 2016-04-07 15:46, Mathieu Malaterre wrote:
> Package: src:chrpath
> Version: 0.16-1
>
> Hi,
>
> I've managed to find the cause of the openmpi segfault (#818909). It
> might affect a number of different packages.
>
> The segfault is caused by the interaction of the
> new DT_MIPS_RLD_MAP_REL dynamic tag (from binutils 2.26) and chrpath.
> Unlike all other tags, this tag is relative to the offset of the tag
> within the executable. chrpath is used to remove rpaths from ELF files.
> It does this by moving all of the other dynamic tags up one entry, but
> since the DT_MIPS_RLD_MAP_REL is not updated, it now points to an
> incorrect offset. The dynamic linker will then overwrite some other
> memory when processing the DT_MIPS_RLD_MAP_REL tag.

Please find below a patch to correctly handle this tag in chrpath. If
you are fine with the patch, a quick upload would be appreciated as
chrpath currently generates broken binaries. Thanks!

Aurelien


--- chrpath-0.16.orig/killrpath.c
+++ chrpath-0.16/killrpath.c
@@ -73,10 +73,26 @@
    dynpos = 0;
    for (i = 0; DYNSS(i, d_tag) != DT_NULL; i++)
      {
-       if (is_e32())
+       if (is_e32()) {
         ((Elf32_Dyn *)dyns)[dynpos] = ((Elf32_Dyn *)dyns)[i];
-       else
+#ifdef DT_MIPS_RLD_MAP_REL
+        /* DT_MIPS_RLD_MAP_REL is relative to the offset of the tag.
+           Adjust it consequently.  */
+        if (DYNSS(i, d_tag) == DT_MIPS_RLD_MAP_REL)
+         ((Elf32_Dyn *)dyns)[dynpos].d_un.d_val =
+          DO_SWAPU32(DYNSU(i, d_un.d_val) +
+          (i - dynpos) * sizeof(Elf32_Dyn));
+#endif
+       } else {
         ((Elf64_Dyn *)dyns)[dynpos] = ((Elf64_Dyn *)dyns)[i];
+#ifdef DT_MIPS_RLD_MAP_REL
+        /* Ditto */
+        if (DYNSS(i, d_tag) == DT_MIPS_RLD_MAP_REL)
+         ((Elf64_Dyn *)dyns)[dynpos].d_un.d_val =
+          DO_SWAPU64(DYNSU(i, d_un.d_val) +
+          (i - dynpos) * sizeof(Elf64_Dyn));
+#endif
+       }
        if ( ! elf_dynpath_tag(DYNSS(i, d_tag)) )
         dynpos++;
      }

--
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien at aurel32.net                 http://www.aurel32.net



More information about the Pkg-cmake-team mailing list