From 3bc6d308ef8ba549e0ef072692903ea2afa883d1 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Sun, 27 May 2018 07:15:35 -0700 Subject: Check non-lazy binding with LD_PRELOAD and weak reference Check non-lazy binding with 1. Reference to unrelocated IFUNC function with LD_PRELOAD. 2. Weak reference. [BZ #23176] [BZ #23240] * elf/Makefile (tests): Add reldep6a. (tests-internal): Add ifuncpreload1 (modules-names): Add ifuncpreloadmod1a and ifuncpreloadmod1b. ($(objpfx)reldep6a): New. ($(objpfx)reldep6a.out): Likewise. (reldep6a-ENV): Likewise. ($(objpfx)ifuncpreload1): Likewise. ($(objpfx)ifuncpreload1.out): Likewise. (ifuncpreload1-ENV): Likewise. * elf/ifuncpreload1.c: New file. * elf/ifuncpreloadmod1a.c: Likewise. * elf/ifuncpreloadmod1b.c: Likewise. * elf/reldep6a.c: Likewise. --- elf/Makefile | 18 ++++++++++++++---- elf/ifuncpreload1.c | 39 +++++++++++++++++++++++++++++++++++++++ elf/ifuncpreloadmod1a.c | 23 +++++++++++++++++++++++ elf/ifuncpreloadmod1b.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ elf/reldep6a.c | 1 + 5 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 elf/ifuncpreload1.c create mode 100644 elf/ifuncpreloadmod1a.c create mode 100644 elf/ifuncpreloadmod1b.c create mode 100644 elf/reldep6a.c diff --git a/elf/Makefile b/elf/Makefile index f54c4657c7..08a090a1b3 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -170,8 +170,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ constload1 order noload filter \ reldep reldep2 reldep3 reldep4 nodelete nodelete2 \ nodlopen nodlopen2 lateglobal initfirst global \ - restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ - tst-tls4 tst-tls5 \ + restest2 next dblload dblunload reldep5 reldep6 reldep6a \ + reldep7 reldep8 tst-tls4 tst-tls5 \ tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \ tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \ tst-align tst-align2 \ @@ -328,7 +328,7 @@ tests-internal += \ ifuncmain1staticpic \ ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \ ifuncmain5 ifuncmain5pic ifuncmain5staticpic \ - ifuncmain7 ifuncmain7pic + ifuncmain7 ifuncmain7pic ifuncpreload1 ifunc-test-modules = ifuncdep1 ifuncdep1pic ifuncdep2 ifuncdep2pic \ ifuncdep5 ifuncdep5pic extra-test-objs += $(ifunc-test-modules:=.o) @@ -339,7 +339,8 @@ ifunc-pie-tests = ifuncmain1pie ifuncmain1vispie ifuncmain1staticpie \ tests-internal += $(ifunc-pie-tests) tests-pie += $(ifunc-pie-tests) endif -modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6 +modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6 \ + ifuncpreloadmod1a ifuncpreloadmod1b endif endif @@ -885,6 +886,10 @@ $(objpfx)reldep5.out: $(objpfx)reldepmod5.so $(objpfx)reldepmod6.so $(objpfx)reldep6: $(libdl) $(objpfx)reldep6.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so +$(objpfx)reldep6a: $(libdl) +$(objpfx)reldep6a.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so +reldep6a-ENV = LD_BIND_NOW=1 + $(objpfx)reldep7: $(libdl) $(objpfx)reldep7.out: $(objpfx)reldep7mod1.so $(objpfx)reldep7mod2.so @@ -1454,3 +1459,8 @@ tst-libc_dlvsym-static-ENV = \ $(objpfx)tst-libc_dlvsym-static.out: $(objpfx)tst-libc_dlvsym-dso.so $(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so + +$(objpfx)ifuncpreload1: $(objpfx)ifuncpreloadmod1a.so +$(objpfx)ifuncpreload1.out: $(objpfx)ifuncpreloadmod1b.so +ifuncpreload1-ENV = \ + LD_PRELOAD=$(objpfx)ifuncpreloadmod1b.so LD_BIND_NOW=1 diff --git a/elf/ifuncpreload1.c b/elf/ifuncpreload1.c new file mode 100644 index 0000000000..172df33ac3 --- /dev/null +++ b/elf/ifuncpreload1.c @@ -0,0 +1,39 @@ +/* Test for relocation over with IFUNC symbols. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +extern void bar (char *, const char *, unsigned int); + +static int +do_test (void) +{ + char dst[50]; + const char src[] = + { + "This is a test" + }; + bar (dst, src, sizeof (src)); + if (__builtin_memcmp (dst, src, sizeof (src)) != 0) + __builtin_abort (); + return 0; +} + +#include diff --git a/elf/ifuncpreloadmod1a.c b/elf/ifuncpreloadmod1a.c new file mode 100644 index 0000000000..be9f8832b8 --- /dev/null +++ b/elf/ifuncpreloadmod1a.c @@ -0,0 +1,23 @@ +/* Shared module to test for relocation over with IFUNC symbols. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +void +bar (char *dst, const char *src, unsigned int size) +{ + __builtin_memmove (dst, src, size); +} diff --git a/elf/ifuncpreloadmod1b.c b/elf/ifuncpreloadmod1b.c new file mode 100644 index 0000000000..1194ae20e4 --- /dev/null +++ b/elf/ifuncpreloadmod1b.c @@ -0,0 +1,49 @@ +/* Shared module to test for relocation over with IFUNC symbols. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +void * +my_memmove(void *dst_p, const void *src_p, size_t n) +{ + const char *src = src_p; + char *dst = dst_p; + char *ret = dst; + if (src < dst) + { + dst += n; + src += n; + while (n--) + *--dst = *--src; + } + else + while (n--) + *dst++ = *src++; + return ret; +} + +void *memmove (void *, const void *, size_t) + __attribute__ ((ifunc ("resolve_memmove"))); + +typedef void *(*memmove_t) (void *, const void *, size_t); + +static memmove_t +resolve_memmove (void) +{ + return my_memmove; +} diff --git a/elf/reldep6a.c b/elf/reldep6a.c new file mode 100644 index 0000000000..28ed7008fa --- /dev/null +++ b/elf/reldep6a.c @@ -0,0 +1 @@ +#include "reldep6.c" -- cgit 1.4.1