From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by sourceware.org (Postfix) with ESMTPS id 06BF9386F804 for ; Wed, 13 Jan 2021 20:53:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 06BF9386F804 Received: by mail-pg1-x530.google.com with SMTP id 15so2264277pgx.7 for ; Wed, 13 Jan 2021 12:53:23 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=XaL97BHi1S2fANTXfcjb/x7CTNHsjK7L7u3vCFYCV6k=; b=nENBoC+5W0MNe9h2bXte+6BSjUyQAOWv3rtffcBjhTQ+ZBs3vuGVXBPCcvhKACF9si eQ005QyahlTL88Rmd9IqQ/4O+MVi02G7fgXl8h3P4oR65rl0echxLBC+bEEsfHsdOzg5 L42FIJt4jadNZ9+tjXjBtgTXXWwQ67rU2RDqN1mxlCzASJDCJvGr7c9oXpUbENELP0uM s2nsC0h5mnftuY9jLkPT6OAj6A/W0ftT+ifWbDB6Ek/Qf2FFua2duDOns/a/6T1R6xZk MobYmoh50qGKMMN2CPSLrj+NCNPtswq/dQ0kwQXHTDLjXd4DkVpOyaFyJiZMBMHwvog3 eUJA== X-Gm-Message-State: AOAM530LY3BUMNG0frcbW/y/DkjbvMgrRr4YZ7TLp9UxiGPDPoRKP9L9 DFCnSzDsSWfqT/SfR3I6OnoygWUq7hY= X-Google-Smtp-Source: ABdhPJzaoKzK24Gn0R0yt8Hwen8M3/AcUYiZfh+0+IuNaWC3YVkySckYmYj/unod8k93PqHu6C4seA== X-Received: by 2002:a62:7ac4:0:b029:19d:b6ee:c64c with SMTP id v187-20020a627ac40000b029019db6eec64cmr3942737pfc.3.1610571202819; Wed, 13 Jan 2021 12:53:22 -0800 (PST) Received: from gnu-cfl-2.localdomain (c-69-181-90-243.hsd1.ca.comcast.net. [69.181.90.243]) by smtp.gmail.com with ESMTPSA id u12sm3515899pfh.98.2021.01.13.12.53.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Jan 2021 12:53:21 -0800 (PST) Received: by gnu-cfl-2.localdomain (Postfix, from userid 1000) id C4FF91A04D5; Wed, 13 Jan 2021 12:53:20 -0800 (PST) Date: Wed, 13 Jan 2021 12:53:20 -0800 From: "H.J. Lu" To: libc-stable@sourceware.org Subject: [BACKPORT] [PATCH] x86: Check IFUNC definition in unrelocated executable [BZ #20019] Message-ID: <20210113205320.GA2594290@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3039.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-stable@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-stable mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2021 20:53:26 -0000 I am backporting these 2 commits to release branches. H.J. ---- Calling an IFUNC function defined in unrelocated executable also leads to segfault. Issue a fatal error message when calling IFUNC function defined in the unrelocated executable from a shared library. On x86, ifuncmain6pie failed with: [hjl@gnu-cfl-2 build-i686-linux]$ ./elf/ifuncmain6pie --direct ./elf/ifuncmain6pie: IFUNC symbol 'foo' referenced in '/export/build/gnu/tools-build/glibc-32bit/build-i686-linux/elf/ifuncmod6.so' is defined in the executable and creates an unsatisfiable circular dependency. [hjl@gnu-cfl-2 build-i686-linux]$ readelf -rW elf/ifuncmod6.so | grep foo 00003ff4 00000706 R_386_GLOB_DAT 0000400c foo_ptr 00003ff8 00000406 R_386_GLOB_DAT 00000000 foo 0000400c 00000401 R_386_32 00000000 foo [hjl@gnu-cfl-2 build-i686-linux]$ Remove non-JUMP_SLOT relocations against foo in ifuncmod6.so, which trigger the circular IFUNC dependency, and build ifuncmain6pie with -Wl,-z,lazy. (cherry picked from commits 6ea5b57afa5cdc9ce367d2b69a2cebfb273e4617 and 7137d682ebfcb6db5dfc5f39724718699922f06c) --- NEWS | 1 + elf/Makefile | 2 ++ elf/ifuncmain6pie.c | 14 +++----------- elf/ifuncmod6.c | 8 ++++---- sysdeps/i386/dl-machine.h | 16 +++++++++++----- sysdeps/x86_64/dl-machine.h | 16 +++++++++++----- 6 files changed, 32 insertions(+), 25 deletions(-) diff --git a/NEWS b/NEWS index 8b589b175b..f278041512 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ using `glibc' in the "product" field. The following bugs are resolved with this release: + [20019] NULL pointer dereference in libc.so.6 IFUNC due to uninitialized GOT [26224] iconv hangs when converting some invalid inputs from several IBM character sets (CVE-2020-27618) [26534] libm.so 2.32 SIGILL in pow() due to FMA4 instruction on non-FMA4 diff --git a/elf/Makefile b/elf/Makefile index 0b78721848..355e70037b 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -1381,6 +1381,8 @@ CFLAGS-ifuncmain7pie.c += $(pie-ccflag) CFLAGS-ifuncmain9pie.c += $(pie-ccflag) CFLAGS-tst-ifunc-textrel.c += $(pic-ccflag) +LDFLAGS-ifuncmain6pie = -Wl,-z,lazy + $(objpfx)ifuncmain1pie: $(objpfx)ifuncmod1.so $(objpfx)ifuncmain1staticpie: $(objpfx)ifuncdep1pic.o $(objpfx)ifuncmain1vispie: $(objpfx)ifuncmod1.so diff --git a/elf/ifuncmain6pie.c b/elf/ifuncmain6pie.c index 04faeb86ef..4a01906836 100644 --- a/elf/ifuncmain6pie.c +++ b/elf/ifuncmain6pie.c @@ -9,7 +9,6 @@ #include "ifunc-sel.h" typedef int (*foo_p) (void); -extern foo_p foo_ptr; static int one (void) @@ -28,20 +27,17 @@ foo_ifunc (void) } extern int foo (void); -extern foo_p get_foo (void); +extern int call_foo (void); extern foo_p get_foo_p (void); -foo_p my_foo_ptr = foo; +foo_p foo_ptr = foo; int main (void) { foo_p p; - p = get_foo (); - if (p != foo) - abort (); - if ((*p) () != -30) + if (call_foo () != -30) abort (); p = get_foo_p (); @@ -52,12 +48,8 @@ main (void) if (foo_ptr != foo) abort (); - if (my_foo_ptr != foo) - abort (); if ((*foo_ptr) () != -30) abort (); - if ((*my_foo_ptr) () != -30) - abort (); if (foo () != -30) abort (); diff --git a/elf/ifuncmod6.c b/elf/ifuncmod6.c index 2e16c1d06d..2f6d0715e6 100644 --- a/elf/ifuncmod6.c +++ b/elf/ifuncmod6.c @@ -4,7 +4,7 @@ extern int foo (void); typedef int (*foo_p) (void); -foo_p foo_ptr = foo; +extern foo_p foo_ptr; foo_p get_foo_p (void) @@ -12,8 +12,8 @@ get_foo_p (void) return foo_ptr; } -foo_p -get_foo (void) +int +call_foo (void) { - return foo; + return foo (); } diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 0f08079e48..672d8f27ce 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -338,16 +338,22 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, { # ifndef RTLD_BOOTSTRAP if (sym_map != map - && sym_map->l_type != lt_executable && !sym_map->l_relocated) { const char *strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]); - _dl_error_printf ("\ + if (sym_map->l_type == lt_executable) + _dl_fatal_printf ("\ +%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \ +and creates an unsatisfiable circular dependency.\n", + RTLD_PROGNAME, strtab + refsym->st_name, + map->l_name); + else + _dl_error_printf ("\ %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n", - RTLD_PROGNAME, map->l_name, - sym_map->l_name, - strtab + refsym->st_name); + RTLD_PROGNAME, map->l_name, + sym_map->l_name, + strtab + refsym->st_name); } # endif value = ((Elf32_Addr (*) (void)) value) (); diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index ca73d8fef9..363a749cb2 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -315,16 +315,22 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, { # ifndef RTLD_BOOTSTRAP if (sym_map != map - && sym_map->l_type != lt_executable && !sym_map->l_relocated) { const char *strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]); - _dl_error_printf ("\ + if (sym_map->l_type == lt_executable) + _dl_fatal_printf ("\ +%s: IFUNC symbol '%s' referenced in '%s' is defined in the executable \ +and creates an unsatisfiable circular dependency.\n", + RTLD_PROGNAME, strtab + refsym->st_name, + map->l_name); + else + _dl_error_printf ("\ %s: Relink `%s' with `%s' for IFUNC symbol `%s'\n", - RTLD_PROGNAME, map->l_name, - sym_map->l_name, - strtab + refsym->st_name); + RTLD_PROGNAME, map->l_name, + sym_map->l_name, + strtab + refsym->st_name); } # endif value = ((ElfW(Addr) (*) (void)) value) (); -- 2.29.2