From patchwork Wed Jan 23 14:07:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 156380 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp758616jaa; Wed, 23 Jan 2019 06:07:58 -0800 (PST) X-Google-Smtp-Source: ALg8bN7vD0lduwr5z9UKl9RhfP7DhGW19faJ/C2rEv38tbIU4c/m/w0Mh+8nXghEzF7D0IL6Nr3L X-Received: by 2002:a63:83c1:: with SMTP id h184mr2037690pge.437.1548252478850; Wed, 23 Jan 2019 06:07:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548252478; cv=none; d=google.com; s=arc-20160816; b=LGBZ6oHAplhDqmMK0E+T+mvehHk/ZUhKIjksz2HAKUi5GRkxmCq3ddhbEMZ6aFAc3B KER+KGByAVaFoh/unedvYWTVof43QF4s0GwRJ4oyykjQYQaP/cC0tDJKo4QTSDTQe6WM MkSoAzYdTqYD1CR2iIOZEc4fblI4pl0G0RaCaDEKQueXLYpwJn10pxOHYwjRDRKqfw0/ 7lxOlh2kXEDaV6Vo5TEtwiW6TbtOjM7NUHYs1IYROr9R3ZSfYElmeX7GE1FddK4waB7O Up6YA92d2yCg9yGjr/FBbe6ul7i0ewD5I7YSW30zEOcXoWV0HaPDk9n+wlo66HhFtx5u GKmQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:to:from:dkim-signature:delivered-to:sender :list-help:list-post:list-archive:list-subscribe:list-unsubscribe :list-id:precedence:mailing-list:dkim-signature:domainkey-signature; bh=xitEIpTjZhgkto9U4zw4Qczg+4AsaEzqlIQ1zDE7db0=; b=jbtS1O8cEIvzZh11dMxiEDgB2N7iauv9bbMuhZouypS9BwQzgfRR64zaCgHi9h54UK LIoXkVE8v+qy4IgcuKppaQG9UVHIBYO14TBD1ax8cibrcfvhqSQdS5piGhUu/FPiZtio YCDON+nbV8I8h9j5ouvYipyccKcJ+rsiLjHH62PfwHefvXtjPyZafQ/b7IAD8wC+/h/1 TlOL+BTsWFR9YeV555epWVxCNyVk4Cboi7kNX+qGU7yfgLhBDJCfRkS/MMdb4SQ5P0+j +UwIvQdr6FiVjoXoTdauHj/S8/ij2bvE6ja0bRHysvXeAW8KSBcJnBmXbF93QQPSkPsh LSEA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=JZo0dJ0J; dkim=pass header.i=@linaro.org header.s=google header.b="S/3SWAGS"; spf=pass (google.com: domain of libc-alpha-return-99507-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-99507-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id p75si10854939pfa.34.2019.01.23.06.07.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Jan 2019 06:07:58 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-99507-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=JZo0dJ0J; dkim=pass header.i=@linaro.org header.s=google header.b="S/3SWAGS"; spf=pass (google.com: domain of libc-alpha-return-99507-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-99507-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=azOJYGlHZCeEOMA+RzYTFKVJAmKharA8xDtCCjeVKaAzy8liCPMiL pYXuVo75cuNGN1rUrSkyvlXXy2WzP39XftXZbwznWjD0n34ZeYGoteHnGTmkCJPH LCHLocxYjKtmOeFhcqF5BS/LsFu1LOkievfmzly6ww56VV0gR8KbZY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=vIOIBCEcMuxodNRkmPYDW+/m7Qw=; b=JZo0dJ0JRm7knkKEgYsjcSb3bGc3 h7GLe+L9VpFE+C3H7pJSC4kh/iTOmTulTVJbmL4YjipTzqlw+nISAKiSFHXj6gEj fLtoVPTCpi/1jlKQKnPnHs9xleFVfwl7nG06O3La/1ObRHNMzRvPwXzWnM5VjOUg Re1LATYNjkJWEnM= Received: (qmail 74434 invoked by alias); 23 Jan 2019 14:07:50 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 74422 invoked by uid 89); 23 Jan 2019 14:07:49 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=cookie, Hx-languages-length:8810 X-HELO: mail-qk1-f196.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id; bh=xitEIpTjZhgkto9U4zw4Qczg+4AsaEzqlIQ1zDE7db0=; b=S/3SWAGSpYImtTa++qSD56FnCEsZQtPqYkGxkjlRPSAwOgKjC1oCuIkWRjkld5eROh FvzMJM631bCAfNVGRP4u3F8sCstMZJyy24zYpDhlxN4SpDZ0CVR0zph76otvJ6v/CKGt 01I30xoG32DoprwjCPLAP5wF+79H3iusTB6Hw= Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH] elf: Fix LD_AUDIT for modules with invalid version (BZ#24122) Date: Wed, 23 Jan 2019 12:07:40 -0200 Message-Id: <20190123140740.27433-1-adhemerval.zanella@linaro.org> The error handling patch for invalid audit modules version access invalid memory: elf/rtld.c: 1454 unsigned int (*laversion) (unsigned int); 1455 unsigned int lav; 1456 if (err_str == NULL 1457 && (laversion = largs.result) != NULL 1458 && (lav = laversion (LAV_CURRENT)) > 0 1459 && lav <= LAV_CURRENT) 1460 { [...] 1526 else 1527 { 1528 /* We cannot use the DSO, it does not have the 1529 appropriate interfaces or it expects something 1530 more recent. */ 1531 #ifndef NDEBUG 1532 Lmid_t ns = dlmargs.map->l_ns; 1533 #endif 1534 _dl_close (dlmargs.map); 1535 1536 /* Make sure the namespace has been cleared entirely. */ 1537 assert (GL(dl_ns)[ns]._ns_loaded == NULL); 1538 assert (GL(dl_ns)[ns]._ns_nloaded == 0); 1539 1540 GL(dl_tls_max_dtv_idx) = tls_idx; 1541 goto not_loaded; 1542 } 1431 const char *err_str = NULL; 1432 bool malloced; 1433 (void) _dl_catch_error (&objname, &err_str, &malloced, dlmopen_doit, 1434 &dlmargs); 1435 if (__glibc_unlikely (err_str != NULL)) 1436 { 1437 not_loaded: 1438 _dl_error_printf ("\ 1439 ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", 1440 name, err_str); 1441 if (malloced) 1442 free ((char *) err_str); 1443 } On failure the err_str will be NULL and _dl_debug_vdprintf does not handle it properly: elf/dl-misc.c: 200 case 's': 201 /* Get the string argument. */ 202 iov[niov].iov_base = va_arg (arg, char *); 203 iov[niov].iov_len = strlen (iov[niov].iov_base); 204 if (prec != -1) 205 iov[niov].iov_len = MIN ((size_t) prec, iov[niov].iov_len); 206 ++niov; 207 break; This patch fixes the issues and improves the error message. Checked on x86_64-linux-gnu and i686-linux-gnu [BZ #24122] * elf/Makefile (tests): Add tst-audit13. (modules-names): Add tst-audit13mod1. (tst-audit13.out, tst-audit13-ENV): New rule. * elf/rtld.c (dl_main): Handle invalid audit module version. * elf/tst-audit13.c: New file. * elf/tst-audit13mod1.c: Likewise. --- ChangeLog | 10 +++++ elf/Makefile | 8 +++- elf/rtld.c | 19 ++++++--- elf/tst-audit13.c | 28 +++++++++++++ elf/tst-audit13mod1.c | 91 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 elf/tst-audit13.c create mode 100644 elf/tst-audit13mod1.c -- 2.17.1 Reviewed-by: Carlos O'Donell Reviewed-by: Carlos O'Donell diff --git a/elf/Makefile b/elf/Makefile index 9cf5cd8dfd..f71ed7cfff 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -187,7 +187,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \ - tst-unwind-ctor tst-unwind-main + tst-unwind-ctor tst-unwind-main tst-audit13 # reldep9 tests-internal += loadtest unload unload2 circleload1 \ neededtest neededtest2 neededtest3 neededtest4 \ @@ -275,7 +275,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-latepthreadmod $(tst-tls-many-dynamic-modules) \ tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \ tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \ - tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib + tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib \ + tst-audit13mod1 # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. modules-names-tests = $(filter-out ifuncmod% tst-libc_dlvsym-dso tst-tlsmod%,\ @@ -1382,6 +1383,9 @@ tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so $(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map +$(objpfx)tst-audit13.out: $(objpfx)tst-audit13mod1.so +tst-audit13-ENV = LD_AUDIT=$(objpfx)tst-audit13mod1.so + # Override -z defs, so that we can reference an undefined symbol. # Force lazy binding for the same reason. LDFLAGS-tst-latepthreadmod.so = \ diff --git a/elf/rtld.c b/elf/rtld.c index 5d97f41b7b..ad62c58e17 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1453,10 +1453,12 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", unsigned int (*laversion) (unsigned int); unsigned int lav; - if (err_str == NULL - && (laversion = largs.result) != NULL - && (lav = laversion (LAV_CURRENT)) > 0 - && lav <= LAV_CURRENT) + if (err_str != NULL) + goto not_loaded; + + if ((laversion = largs.result) != NULL + && (lav = laversion (LAV_CURRENT)) > 0 + && lav <= LAV_CURRENT) { /* Allocate structure for the callback function pointers. This call can never fail. */ @@ -1538,7 +1540,14 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", assert (GL(dl_ns)[ns]._ns_nloaded == 0); GL(dl_tls_max_dtv_idx) = tls_idx; - goto not_loaded; + _dl_error_printf ("\ +ERROR: ld.so: object '%s' cannot be loaded as audit interface: ", name); + if (laversion == NULL) + _dl_error_printf ("la_version function not found.\n"); + else + _dl_error_printf ( +"invalid version '%u' (expected minimum of '%u'); ignored.\n", + lav, LAV_CURRENT); } } } diff --git a/elf/tst-audit13.c b/elf/tst-audit13.c new file mode 100644 index 0000000000..6f587baf58 --- /dev/null +++ b/elf/tst-audit13.c @@ -0,0 +1,28 @@ +/* Check for invalid audit version (BZ#24122). + Copyright (C) 2019 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 + +static int +do_test (void) +{ + puts ("plt call"); + return 0; +} + +#include diff --git a/elf/tst-audit13mod1.c b/elf/tst-audit13mod1.c new file mode 100644 index 0000000000..96f1adef7a --- /dev/null +++ b/elf/tst-audit13mod1.c @@ -0,0 +1,91 @@ +/* Check for invalid audit version (BZ#24122). + Copyright (C) 2019 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 + +unsigned int +la_version (unsigned int version) +{ + /* Invalid version, object should be discarded by the loader. */ + return 0; +} + +void +la_activity (uintptr_t *cookie, unsigned int flag) +{ + exit (EXIT_FAILURE); +} + +char * +la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) +{ + exit (EXIT_FAILURE); +} + +unsigned int +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t * cookie) +{ + exit (EXIT_FAILURE); +} + +void +la_preinit (uintptr_t * cookie) +{ + exit (EXIT_FAILURE); +} + +uintptr_t +#if __ELF_NATIVE_CLASS == 32 +la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +#else +la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, unsigned int *flags, const char *symname) +#endif +{ + exit (EXIT_FAILURE); +} + +unsigned int +la_objclose (uintptr_t * cookie) +{ + exit (EXIT_FAILURE); +} + +#include +#if (!defined (pltenter) || !defined (pltexit) || !defined (La_regs) \ + || !defined (La_retval) || !defined (int_retval)) +# error "architecture specific code needed in sysdeps/CPU/tst-audit.h" +#endif + +ElfW(Addr) +pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, La_regs *regs, unsigned int *flags, + const char *symname, long int *framesizep) +{ + exit (EXIT_FAILURE); +} + +unsigned int +pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, + uintptr_t *defcook, const La_regs *inregs, La_retval *outregs, + const char *symname) +{ + exit (EXIT_FAILURE); +}