aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyle Russell <bkylerussell@gmail.com>2018-09-28 07:55:56 -0700
committerMark Hatle <mark.hatle@windriver.com>2018-10-12 10:12:33 -0400
commitd4eabd20d162796b081255431bf5fd3c288983aa (patch)
treeb0be8561c2c7ff1bc948db5165cbcc063f50ec20
parent53da4ff06d04a16a485dbe3229f7fd719bc78336 (diff)
downloadprelink-cross-d4eabd20d162796b081255431bf5fd3c288983aa.tar.gz
prelink-cross-d4eabd20d162796b081255431bf5fd3c288983aa.tar.bz2
prelink-cross-d4eabd20d162796b081255431bf5fd3c288983aa.zip
rtld: get machine from undef_map for protected symbols
Avoids rtld segfault when _dl_lookup_symbol_x is called with NULL for skip_map on a protected symbol relocation. Global protected symbols may not actually require a copy relocaton, in which case skip_map is undefined, so use the undef_map to determine the symbol arch. Signed-off-by: Kyle Russell <bkylerussell@gmail.com> DCO for Kyle added per email on YP list. Added ChangeLog entry. Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
-rw-r--r--ChangeLog7
-rw-r--r--src/rtld/dl-lookupX.h6
-rw-r--r--testsuite/Makefile.am2
-rw-r--r--testsuite/reloc12.c19
-rw-r--r--testsuite/reloc12.h11
-rwxr-xr-xtestsuite/reloc12.sh20
-rw-r--r--testsuite/reloc12lib1.c11
-rw-r--r--testsuite/reloc12lib2.c16
8 files changed, 88 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index af93050..1faef5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-10-12 Kyle Russell <bkylerussell@gmail.com>
+ * src/rtld/dl-lookupX.h: Fix rtld segfault when _dl_lookup_symbol_x
+ is NULL on protected symbol relocations
+ * testsuite/Makefile.am, testsuite/reloc12.c, testsuite/reloc12.h,
+ testsuite/reloc12.sh, testsuite/reloc12lib1.c, testsuite/reloc12lib2.c:
+ Add a new test for these relocations
+
2018-10-12 Mark Hatle <mark.hatle@windriver.com>
* Add 'Developer's Certificate of Origin' to patch requirements
diff --git a/src/rtld/dl-lookupX.h b/src/rtld/dl-lookupX.h
index 425bb4b..250c509 100644
--- a/src/rtld/dl-lookupX.h
+++ b/src/rtld/dl-lookupX.h
@@ -679,10 +679,10 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
&protected_value, *scope, i, version, flags,
skip_map,
- (ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(skip_map->machine)
+ (ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(undef_map->machine)
&& ELFW(ST_TYPE) ((*ref)->st_info) == STT_OBJECT
- && type_class == ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(skip_map->machine))
- ? ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(skip_map->machine)
+ && type_class == ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(undef_map->machine))
+ ? ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(undef_map->machine)
: ELF_RTYPE_CLASS_PLT, NULL) != 0)
break;
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 030f65b..21de6a9 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -5,7 +5,7 @@ AM_CFLAGS = -Wall
TESTS = movelibs.sh \
reloc1.sh reloc2.sh reloc3.sh reloc4.sh reloc5.sh reloc6.sh \
- reloc7.sh reloc8.sh reloc9.sh reloc10.sh reloc11.sh \
+ reloc7.sh reloc8.sh reloc9.sh reloc10.sh reloc11.sh reloc12.sh \
shuffle1.sh shuffle2.sh shuffle3.sh shuffle4.sh shuffle5.sh \
shuffle6.sh shuffle7.sh shuffle8.sh shuffle9.sh undo1.sh \
layout1.sh layout2.sh unprel1.sh \
diff --git a/testsuite/reloc12.c b/testsuite/reloc12.c
new file mode 100644
index 0000000..cfa8888
--- /dev/null
+++ b/testsuite/reloc12.c
@@ -0,0 +1,19 @@
+#include "reloc12.h"
+#include <stdlib.h>
+
+int main()
+{
+ A* ptr = find('b');
+ if(b(ptr) != 0)
+ abort();
+
+ ptr = find('a');
+ if(b(ptr) != 1)
+ abort();
+
+ ptr = find('r');
+ if(b(ptr) != 2)
+ abort();
+
+ exit(0);
+}
diff --git a/testsuite/reloc12.h b/testsuite/reloc12.h
new file mode 100644
index 0000000..8e09405
--- /dev/null
+++ b/testsuite/reloc12.h
@@ -0,0 +1,11 @@
+typedef struct
+ {
+ char a;
+ int b;
+ } A;
+
+extern A foo[] __attribute ((visibility ("protected")));
+
+A* find(char a);
+char a(const A*);
+int b(const A*);
diff --git a/testsuite/reloc12.sh b/testsuite/reloc12.sh
new file mode 100755
index 0000000..a8a43c7
--- /dev/null
+++ b/testsuite/reloc12.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+. `dirname $0`/functions.sh
+rm -f reloc12 reloc12lib*.so reloc12.log
+rm -f prelink.cache
+$RUN_HOST $CC -shared -O2 -fpic -o reloc12lib1.so $srcdir/reloc12lib1.c
+$RUN_HOST $CC -shared -O2 -fpic -o reloc12lib2.so $srcdir/reloc12lib2.c
+BINS="reloc12"
+LIBS="reloc12lib1.so reloc12lib2.so"
+$RUN_HOST $CCLINK -o reloc12 $srcdir/reloc12.c -Wl,--rpath-link,. ${LIBS}
+savelibs
+echo $PRELINK ${PRELINK_OPTS--vm} ./reloc12 > reloc12.log
+$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc12 >> reloc12.log 2>&1 || exit 1
+grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc12.log && exit 2
+if [ "x$CROSS" = "x" ]; then
+ $RUN LD_LIBRARY_PATH=. ./reloc12 || exit 3
+fi
+$RUN_HOST $READELF -a ./reloc12 >> reloc12.log 2>&1 || exit 4
+# So that it is not prelinked again
+chmod -x ./reloc12
+comparelibs >> reloc12.log 2>&1 || exit 5
diff --git a/testsuite/reloc12lib1.c b/testsuite/reloc12lib1.c
new file mode 100644
index 0000000..db7e64f
--- /dev/null
+++ b/testsuite/reloc12lib1.c
@@ -0,0 +1,11 @@
+#include "reloc12.h"
+
+char a(const A *d)
+{
+ return d ? d->a : 0;
+}
+
+int b(const A *d)
+{
+ return d ? d->b : -1;
+}
diff --git a/testsuite/reloc12lib2.c b/testsuite/reloc12lib2.c
new file mode 100644
index 0000000..ffa60a0
--- /dev/null
+++ b/testsuite/reloc12lib2.c
@@ -0,0 +1,16 @@
+#include "reloc12.h"
+
+A foo[] = {
+ { 'b', 0 },
+ { 'a', 1 },
+ { 'r', 2 }
+};
+
+A* find(char a)
+{
+ for(A* ptr = foo; ptr < foo + sizeof(foo)/sizeof(foo[0]); ptr++)
+ if(ptr->a == a)
+ return ptr;
+
+ return 0;
+}