commit 020b43544a26237d752eae4a715c403f29226542 Author: Siddhesh Poyarekar Date: Thu Feb 2 07:49:02 2023 -0500 cdefs: Limit definition of fortification macros Define the __glibc_fortify and other macros only when __FORTIFY_LEVEL > 0. This has the effect of not defining these macros on older C90 compilers that do not have support for variable length argument lists. Also trim off the trailing backslashes from the definition of __glibc_fortify and __glibc_fortify_n macros. Signed-off-by: Siddhesh Poyarekar Reviewed-by: Florian Weimer (cherry picked from commit 2337e04e21ba6040926ec871e403533f77043c40) diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index 66d6702123..c37a3ff637 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -152,6 +152,7 @@ # define __glibc_objsize(__o) __bos (__o) #endif +#if __USE_FORTIFY_LEVEL > 0 /* Compile time conditions to choose between the regular, _chk and _chk_warn variants. These conditions should get evaluated to constant and optimized away. */ @@ -187,7 +188,7 @@ ? __ ## f ## _alias (__VA_ARGS__) \ : (__glibc_unsafe_len (__l, __s, __osz) \ ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ - : __ ## f ## _chk (__VA_ARGS__, __osz))) \ + : __ ## f ## _chk (__VA_ARGS__, __osz))) /* Fortify function f, where object size argument passed to f is the number of elements and not total size. */ @@ -197,7 +198,8 @@ ? __ ## f ## _alias (__VA_ARGS__) \ : (__glibc_unsafe_len (__l, __s, __osz) \ ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ - : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \ + : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) +#endif #if __GNUC_PREREQ (4,3) # define __warnattr(msg) __attribute__((__warning__ (msg))) commit 9f8513dc64119a424b312db97cef5d87d376defa Author: caiyinyu Date: Tue Jan 31 20:40:10 2023 +0800 LoongArch: Add new relocation types. diff --git a/elf/elf.h b/elf/elf.h index b6a75c13a8..4bc0e4299c 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -4159,6 +4159,46 @@ enum #define R_LARCH_GNU_VTINHERIT 57 #define R_LARCH_GNU_VTENTRY 58 +/* reserved 59-63 */ + +#define R_LARCH_B16 64 +#define R_LARCH_B21 65 +#define R_LARCH_B26 66 +#define R_LARCH_ABS_HI20 67 +#define R_LARCH_ABS_LO12 68 +#define R_LARCH_ABS64_LO20 69 +#define R_LARCH_ABS64_HI12 70 +#define R_LARCH_PCALA_HI20 71 +#define R_LARCH_PCALA_LO12 72 +#define R_LARCH_PCALA64_LO20 73 +#define R_LARCH_PCALA64_HI12 74 +#define R_LARCH_GOT_PC_HI20 75 +#define R_LARCH_GOT_PC_LO12 76 +#define R_LARCH_GOT64_PC_LO20 77 +#define R_LARCH_GOT64_PC_HI12 78 +#define R_LARCH_GOT_HI20 79 +#define R_LARCH_GOT_LO12 80 +#define R_LARCH_GOT64_LO20 81 +#define R_LARCH_GOT64_HI12 82 +#define R_LARCH_TLS_LE_HI20 83 +#define R_LARCH_TLS_LE_LO12 84 +#define R_LARCH_TLS_LE64_LO20 85 +#define R_LARCH_TLS_LE64_HI12 86 +#define R_LARCH_TLS_IE_PC_HI20 87 +#define R_LARCH_TLS_IE_PC_LO12 88 +#define R_LARCH_TLS_IE64_PC_LO20 89 +#define R_LARCH_TLS_IE64_PC_HI12 90 +#define R_LARCH_TLS_IE_HI20 91 +#define R_LARCH_TLS_IE_LO12 92 +#define R_LARCH_TLS_IE64_LO20 93 +#define R_LARCH_TLS_IE64_HI12 94 +#define R_LARCH_TLS_LD_PC_HI20 95 +#define R_LARCH_TLS_LD_HI20 96 +#define R_LARCH_TLS_GD_PC_HI20 97 +#define R_LARCH_TLS_GD_HI20 98 +#define R_LARCH_32_PCREL 99 +#define R_LARCH_RELAX 100 + /* ARC specific declarations. */ /* Processor specific flags for the Ehdr e_flags field. */ commit fb7b95dc47b0d5ecd48339512d091b6b23e7d900 Author: Andreas Schwab Date: Thu Jan 26 14:25:05 2023 +0100 Use 64-bit time_t interfaces in strftime and strptime (bug 30053) Both functions use time_t only internally, so the ABI is not affected. (cherry picked from commit 41349f6f67c83e7bafe49f985b56493d2c4c9c77) diff --git a/NEWS b/NEWS index ad5196a5f1..4da140db31 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,12 @@ See the end for copying conditions. Please send GNU C library bug reports via using `glibc' in the "product" field. +Version 2.37.1 + +The following bugs are resolved with this release: + + [30053] time: strftime %s returns -1 after 2038 on 32 bits systems + Version 2.37 Major new features: diff --git a/time/Makefile b/time/Makefile index d86f2105c5..92bc3db315 100644 --- a/time/Makefile +++ b/time/Makefile @@ -50,7 +50,7 @@ tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1 \ tst-adjtime tst-ctime tst-difftime tst-mktime4 tst-clock_settime \ tst-settimeofday tst-itimer tst-gmtime tst-timegm \ - tst-timespec_get tst-timespec_getres + tst-timespec_get tst-timespec_getres tst-strftime4 tests-time64 := \ tst-adjtime-time64 \ @@ -65,6 +65,7 @@ tests-time64 := \ tst-itimer-time64 \ tst-mktime4-time64 \ tst-settimeofday-time64 \ + tst-strftime4-time64 \ tst-timegm-time64 \ tst-timespec_get-time64 \ tst-timespec_getres-time64 \ diff --git a/time/strftime_l.c b/time/strftime_l.c index e09561c39c..402c6c4111 100644 --- a/time/strftime_l.c +++ b/time/strftime_l.c @@ -159,6 +159,10 @@ extern char *tzname[]; #ifdef _LIBC # define tzname __tzname # define tzset __tzset + +# define time_t __time64_t +# define __gmtime_r(t, tp) __gmtime64_r (t, tp) +# define mktime(tp) __mktime64 (tp) #endif #if !HAVE_TM_GMTOFF diff --git a/time/strptime_l.c b/time/strptime_l.c index 80fd705b8d..85c3249fcc 100644 --- a/time/strptime_l.c +++ b/time/strptime_l.c @@ -30,8 +30,10 @@ #ifdef _LIBC # define HAVE_LOCALTIME_R 0 # include "../locale/localeinfo.h" -#endif +# define time_t __time64_t +# define __localtime_r(t, tp) __localtime64_r (t, tp) +#endif #if ! HAVE_LOCALTIME_R && ! defined localtime_r # ifdef _LIBC diff --git a/time/tst-strftime4-time64.c b/time/tst-strftime4-time64.c new file mode 100644 index 0000000000..4d47ee7d79 --- /dev/null +++ b/time/tst-strftime4-time64.c @@ -0,0 +1 @@ +#include "tst-strftime4.c" diff --git a/time/tst-strftime4.c b/time/tst-strftime4.c new file mode 100644 index 0000000000..659716d0fa --- /dev/null +++ b/time/tst-strftime4.c @@ -0,0 +1,52 @@ +/* Test strftime and strptime after 2038-01-19 03:14:07 UTC (bug 30053). + Copyright (C) 2023 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 +#include +#include + +static int +do_test (void) +{ + TEST_VERIFY_EXIT (setenv ("TZ", "UTC0", 1) == 0); + tzset (); + if (sizeof (time_t) > 4) + { + time_t wrap = (time_t) 2147483648LL; + char buf[80]; + struct tm *tm = gmtime (&wrap); + TEST_VERIFY_EXIT (tm != NULL); + TEST_VERIFY_EXIT (strftime (buf, sizeof buf, "%s", tm) > 0); + puts (buf); + TEST_VERIFY (strcmp (buf, "2147483648") == 0); + + struct tm tm2; + char *p = strptime (buf, "%s", &tm2); + TEST_VERIFY_EXIT (p != NULL && *p == '\0'); + time_t t = mktime (&tm2); + printf ("%lld\n", (long long) t); + TEST_VERIFY (t == wrap); + } + else + FAIL_UNSUPPORTED ("32-bit time_t"); + return 0; +} + +#include commit 07b9521fc6369d000216b96562ff7c0ed32a16c4 Author: Carlos O'Donell Date: Thu Jan 19 12:50:20 2023 +0100 Account for grouping in printf width (bug 30068) This is a partial fix for mishandling of grouping when formatting integers. It properly computes the width in the presence of grouping characters when the width is larger than the number of significant digits. The precision related issue is documented in bug 23432. Co-authored-by: Andreas Schwab (cherry picked from commit c980549cc6a1c03c23cc2fe3e7b0fe626a0364b0) diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 34fdd6d1f8..652d9e5f95 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -196,6 +196,7 @@ tests := \ tst-gets \ tst-grouping \ tst-grouping2 \ + tst-grouping3 \ tst-long-dbl-fphex \ tst-memstream-string \ tst-obprintf \ @@ -340,6 +341,7 @@ $(objpfx)tst-sscanf.out: $(gen-locales) $(objpfx)tst-swprintf.out: $(gen-locales) $(objpfx)tst-vfprintf-mbs-prec.out: $(gen-locales) $(objpfx)tst-vfprintf-width-i18n.out: $(gen-locales) +$(objpfx)tst-grouping3.out: $(gen-locales) endif tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace \ diff --git a/stdio-common/tst-grouping3.c b/stdio-common/tst-grouping3.c new file mode 100644 index 0000000000..e9e39218e2 --- /dev/null +++ b/stdio-common/tst-grouping3.c @@ -0,0 +1,54 @@ +/* Test printf with grouping and padding (bug 30068) + Copyright (C) 2023 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 +#include + +static int +do_test (void) +{ + char buf[80]; + + xsetlocale (LC_NUMERIC, "de_DE.UTF-8"); + + /* The format string has the following conversion specifier: + ' - Use thousands grouping. + + - The result of a signed conversion shall begin with a sign. + - - Left justified. + 13 - Minimum 13 bytes of width. + 9 - Minimum 9 digits of precision. + + In bug 30068 the grouping characters were not accounted for in + the width, and were added after the fact resulting in a 15-byte + output instead of a 13-byte output. The two additional bytes + come from the locale-specific thousands separator. This increase + in size could result in a buffer overflow if a reasonable caller + calculated the size of the expected buffer using nl_langinfo to + determine the sie of THOUSEP in bytes. + + This bug is distinct from bug 23432 which has to do with the + minimum precision calculation (digit based). */ + sprintf (buf, "%+-'13.9d", 1234567); + TEST_COMPARE_STRING (buf, "+001.234.567 "); + + return 0; +} + +#include diff --git a/stdio-common/vfprintf-process-arg.c b/stdio-common/vfprintf-process-arg.c index 24c9125f9f..8c0fcbcf78 100644 --- a/stdio-common/vfprintf-process-arg.c +++ b/stdio-common/vfprintf-process-arg.c @@ -186,11 +186,17 @@ LABEL (unsigned_number): /* Unsigned number of base BASE. */ bool octal_marker = (prec <= number_length && number.word != 0 && alt && base == 8); - prec = MAX (0, prec - (workend - string)); + /* At this point prec_inc is the additional bytes required for the + specificed precision. It is 0 if the precision would not have + required additional bytes i.e. the number of input digits is more + than the precision. It is greater than zero if the precision is + more than the number of digits without grouping (precision only + considers digits). */ + unsigned int prec_inc = MAX (0, prec - (workend - string)); if (!left) { - width -= number_length + prec; + width -= number_length + prec_inc; if (number.word != 0 && alt && (base == 16 || base == 2)) /* Account for 0X, 0x, 0B or 0b hex or binary marker. */ @@ -221,7 +227,7 @@ LABEL (unsigned_number): /* Unsigned number of base BASE. */ Xprintf_buffer_putc (buf, spec); } - width += prec; + width += prec_inc; Xprintf_buffer_pad (buf, L_('0'), width); if (octal_marker) @@ -237,6 +243,8 @@ LABEL (unsigned_number): /* Unsigned number of base BASE. */ } else { + /* Perform left justification adjustments. */ + if (is_negative) { Xprintf_buffer_putc (buf, L_('-')); @@ -263,9 +271,13 @@ LABEL (unsigned_number): /* Unsigned number of base BASE. */ if (octal_marker) --width; - width -= workend - string + prec; + /* Adjust the width by subtracting the number of bytes + required to represent the number with grouping characters + (NUMBER_LENGTH) and any additional bytes required for + precision. */ + width -= number_length + prec_inc; - Xprintf_buffer_pad (buf, L_('0'), prec); + Xprintf_buffer_pad (buf, L_('0'), prec_inc); if (octal_marker) Xprintf_buffer_putc (buf, L_('0')); commit 6fe86ecd787a2624cd638131629ba9a824040308 Author: Carlos O'Donell Date: Mon Feb 6 10:36:32 2023 -0500 NEWS: Document CVE-2023-25139. Reviewed-by: Siddhesh Poyarekar (cherry picked from commit 67c37737ed474d25fd4dc535dfd822c426e6b971) diff --git a/NEWS b/NEWS index 4da140db31..7ba8846fcc 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,15 @@ using `glibc' in the "product" field. Version 2.37.1 +Security related changes: + + CVE-2023-25139: When the printf family of functions is called with a + format specifier that uses an (enable grouping) and a + minimum width specifier, the resulting output could be larger than + reasonably expected by a caller that computed a tight bound on the + buffer size. The resulting larger than expected output could result + in a buffer overflow in the printf family of functions. + The following bugs are resolved with this release: [30053] time: strftime %s returns -1 after 2038 on 32 bits systems commit d8e1a7590d375159fb5aac07ad8111ab4699e994 Author: Florian Weimer Date: Wed Feb 8 18:11:04 2023 +0100 elf: Smoke-test ldconfig -p against system /etc/ld.so.cache The test is sufficient to detect the ldconfig bug fixed in commit 9fe6f6363886aae6b2b210cae3ed1f5921299083 ("elf: Fix 64 time_t support for installed statically binaries"). Reviewed-by: Carlos O'Donell (cherry picked from commit 9fd63e35371b9939e9153907c6a753e6960b68ad) diff --git a/elf/Makefile b/elf/Makefile index b509b3eada..2fc6391183 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -626,6 +626,7 @@ ifeq ($(run-built-tests),yes) tests-special += \ $(objpfx)noload-mem.out \ $(objpfx)tst-ldconfig-X.out \ + $(objpfx)tst-ldconfig-p.out \ $(objpfx)tst-leaks1-mem.out \ $(objpfx)tst-rtld-help.out \ # tests-special @@ -2396,6 +2397,11 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh $(objpfx)ldconfig '$(run-program-env)' > $@; \ $(evaluate-test) +$(objpfx)tst-ldconfig-p.out : tst-ldconfig-p.sh $(objpfx)ldconfig + $(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \ + '$(run-program-env)' > $@; \ + $(evaluate-test) + # Test static linking of all the libraries we can possibly link # together. Note that in some configurations this may be less than the # complete list of libraries we build but we try to maxmimize this list. diff --git a/elf/tst-ldconfig-p.sh b/elf/tst-ldconfig-p.sh new file mode 100644 index 0000000000..ec937bf4ec --- /dev/null +++ b/elf/tst-ldconfig-p.sh @@ -0,0 +1,77 @@ +#!/bin/sh +# Test that ldconfig -p prints something useful. +# Copyright (C) 2023 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 +# . + +# Check that the newly built ldconfig -p can dump the system +# /etc/ld.so.cache file. This should always work even if the ABIs are +# not compatible, except in a cross-endian build (that presumably +# involves emulation when running ldconfig). + +common_objpfx=$1 +test_wrapper_env=$2 +run_program_env=$3 + +if ! test -r /etc/ld.so.cache; then + echo "warning: /etc/ld.so.cache does not exist, test skipped" + exit 77 +fi + +testout="${common_objpfx}elf/tst-ldconfig-p.out" +# Truncate file. +: > "$testout" + +${test_wrapper_env} \ +${run_program_env} \ +${common_objpfx}elf/ldconfig -p \ + $testroot/lib >>"$testout" 2>>"$testout" +status=$? +echo "info: ldconfig exit status: $status" >>"$testout" + +errors=0 +case $status in + (0) + if head -n 1 "$testout" | \ + grep -q "libs found in cache \`/etc/ld.so.cache'\$" ; then + echo "info: initial string found" >>"$testout" + else + echo "error: initial string not found" >>"$testout" + errors=1 + fi + if grep -q "^ libc\.so\..* => " "$testout"; then + echo "info: libc.so.* string found" >>"$testout" + else + echo "error: libc.so.* string not found" >>"$testout" + errors=1 + fi + ;; + (1) + if head -n 1 "$testout" | \ + grep -q ": Cache file has wrong endianness\.$" ; then + echo "info: cache file has wrong endianess" >> "$testout" + else + echo "error: unexpected ldconfig error message" >> "$testout" + errors=1 + fi + ;; + (*) + echo "error: unexpected exit status" >> "$testout" + errors=1 + ;; +esac + +exit $errors commit 790e504a172a5ef7399b3e3f481d76394dce0a23 Author: Vitaly Buka Date: Sat Feb 18 12:53:41 2023 -0800 stdlib: Undo post review change to 16adc58e73f3 [BZ #27749] Post review removal of "goto restart" from https://sourceware.org/pipermail/libc-alpha/2021-April/125470.html introduced a bug when some atexit handers skipped. Signed-off-by: Vitaly Buka Reviewed-by: Adhemerval Zanella (cherry picked from commit fd78cfa72ea2bab30fdb4e1e0672b34471426c05) diff --git a/stdlib/Makefile b/stdlib/Makefile index e0fc82fc4d..005eede5d9 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -171,6 +171,7 @@ tests := \ test-a64l \ test-at_quick_exit-race \ test-atexit-race \ + test-atexit-recursive \ test-bz22786 \ test-canon \ test-canon2 \ diff --git a/stdlib/exit.c b/stdlib/exit.c index 6b1eed6445..1cd0bdfe94 100644 --- a/stdlib/exit.c +++ b/stdlib/exit.c @@ -51,7 +51,10 @@ __run_exit_handlers (int status, struct exit_function_list **listp, exit (). */ while (true) { - struct exit_function_list *cur = *listp; + struct exit_function_list *cur; + + restart: + cur = *listp; if (cur == NULL) { @@ -113,7 +116,7 @@ __run_exit_handlers (int status, struct exit_function_list **listp, if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called)) /* The last exit function, or another thread, has registered more exit functions. Start the loop over. */ - continue; + goto restart; } *listp = cur->next; diff --git a/stdlib/test-atexit-recursive.c b/stdlib/test-atexit-recursive.c new file mode 100644 index 0000000000..0596b9763b --- /dev/null +++ b/stdlib/test-atexit-recursive.c @@ -0,0 +1,75 @@ +/* Support file for atexit/exit, etc. race tests (BZ #27749). + Copyright (C) 2023 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 + . */ + +/* Check that atexit handler registed from another handler still called. */ + +#include +#include +#include +#include +#include +#include + +static void +atexit_cb (void) +{ +} + +static void +atexit_last (void) +{ + _exit (1); +} + +static void +atexit_recursive (void) +{ + atexit (&atexit_cb); + atexit (&atexit_last); +} + +_Noreturn static void +test_and_exit (int count) +{ + for (int i = 0; i < count; ++i) + atexit (&atexit_cb); + atexit (&atexit_recursive); + exit (0); +} + +static int +do_test (void) +{ + for (int i = 0; i < 100; ++i) + if (xfork () == 0) + test_and_exit (i); + + for (int i = 0; i < 100; ++i) + { + int status; + xwaitpid (0, &status, 0); + if (!WIFEXITED (status)) + FAIL_EXIT1 ("Failed iterations %d", i); + TEST_COMPARE (WEXITSTATUS (status), 1); + } + + return 0; +} + +#define TEST_FUNCTION do_test +#include commit 590d0e089b06f158ded713f5e5600eaa66dcea44 Author: Joan Bruguera Date: Sat Feb 18 21:52:15 2023 +0000 elf: Restore ldconfig libc6 implicit soname logic [BZ #30125] While cleaning up old libc version support, the deprecated libc4 code was accidentally kept in `implicit_soname`, instead of the libc6 code. This causes additional symlinks to be created by `ldconfig` for libraries without a soname, e.g. a library `libsomething.123.456.789` without a soname will create a `libsomething.123` -> `libsomething.123.456.789` symlink. As the libc6 version of the `implicit_soname` code is a trivial `xstrdup`, just inline it and remove `implicit_soname` altogether. Some further simplification looks possible (e.g. the call to `create_links` looks like a no-op if `soname == NULL`, other than the verbose printfs), but logic is kept as-is for now. Fixes: BZ #30125 Fixes: 8ee878592c4a ("Assume only FLAG_ELF_LIBC6 suport") Signed-off-by: Joan Bruguera Reviewed-by: Adhemerval Zanella (cherry picked from commit 1b0ea8c5d886fedabd611a569b5ec58a6f5153e6) diff --git a/NEWS b/NEWS index 7ba8846fcc..e1562857b1 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ Security related changes: The following bugs are resolved with this release: [30053] time: strftime %s returns -1 after 2038 on 32 bits systems + [30125] dynamic-link: [regression, bisected] glibc-2.37 creates new + symlink for libraries without soname Version 2.37 diff --git a/elf/Makefile b/elf/Makefile index 2fc6391183..0d19964d42 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -627,6 +627,7 @@ tests-special += \ $(objpfx)noload-mem.out \ $(objpfx)tst-ldconfig-X.out \ $(objpfx)tst-ldconfig-p.out \ + $(objpfx)tst-ldconfig-soname.out \ $(objpfx)tst-leaks1-mem.out \ $(objpfx)tst-rtld-help.out \ # tests-special @@ -859,6 +860,8 @@ modules-names += \ tst-initorderb2 \ tst-latepthreadmod \ tst-ldconfig-ld-mod \ + tst-ldconfig-soname-lib-with-soname \ + tst-ldconfig-soname-lib-without-soname \ tst-main1mod \ tst-nodelete2mod \ tst-nodelete-dlclose-dso \ @@ -2402,6 +2405,17 @@ $(objpfx)tst-ldconfig-p.out : tst-ldconfig-p.sh $(objpfx)ldconfig '$(run-program-env)' > $@; \ $(evaluate-test) +LDFLAGS-tst-ldconfig-soname-lib-with-soname.so = \ + -Wl,-soname,libtst-ldconfig-soname-lib-with-soname.so.1 + +$(objpfx)tst-ldconfig-soname.out : tst-ldconfig-soname.sh \ + $(objpfx)ldconfig \ + $(objpfx)tst-ldconfig-soname-lib-with-soname.so \ + $(objpfx)tst-ldconfig-soname-lib-without-soname.so + $(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \ + '$(run-program-env)' > $@; \ + $(evaluate-test) + # Test static linking of all the libraries we can possibly link # together. Note that in some configurations this may be less than the # complete list of libraries we build but we try to maxmimize this list. diff --git a/elf/ldconfig.c b/elf/ldconfig.c index 166dccb528..5b1c9139f6 100644 --- a/elf/ldconfig.c +++ b/elf/ldconfig.c @@ -616,7 +616,7 @@ manual_link (char *library) goto out; } if (soname == NULL) - soname = implicit_soname (libname, flag); + soname = xstrdup (libname); create_links (real_path, path, libname, soname); free (soname); out: @@ -849,7 +849,7 @@ search_dir (const struct dir_entry *entry) } if (soname == NULL) - soname = implicit_soname (direntry->d_name, flag); + soname = xstrdup (direntry->d_name); /* A link may just point to itself. */ if (is_link) diff --git a/elf/readlib.c b/elf/readlib.c index c5c3591eef..bc13d9acc6 100644 --- a/elf/readlib.c +++ b/elf/readlib.c @@ -166,24 +166,5 @@ process_file (const char *real_file_name, const char *file_name, return ret; } -/* Returns made up soname if lib doesn't have explicit DT_SONAME. */ - -char * -implicit_soname (const char *lib, int flag) -{ - char *soname = xstrdup (lib); - - /* Aout files don't have a soname, just return the name - including the major number. */ - char *major = strstr (soname, ".so."); - if (major) - { - char *dot = strstr (major + 4, "."); - if (dot) - *dot = '\0'; - } - return soname; -} - /* Get architecture specific version of process_elf_file. */ #include diff --git a/elf/tst-ldconfig-soname-lib-with-soname.c b/elf/tst-ldconfig-soname-lib-with-soname.c new file mode 100644 index 0000000000..d1ab56ad58 --- /dev/null +++ b/elf/tst-ldconfig-soname-lib-with-soname.c @@ -0,0 +1 @@ +/* This file intentionally left blank */ diff --git a/elf/tst-ldconfig-soname-lib-without-soname.c b/elf/tst-ldconfig-soname-lib-without-soname.c new file mode 100644 index 0000000000..d1ab56ad58 --- /dev/null +++ b/elf/tst-ldconfig-soname-lib-without-soname.c @@ -0,0 +1 @@ +/* This file intentionally left blank */ diff --git a/elf/tst-ldconfig-soname.sh b/elf/tst-ldconfig-soname.sh new file mode 100644 index 0000000000..406f526dbf --- /dev/null +++ b/elf/tst-ldconfig-soname.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# Test that ldconfig creates symlinks according to the library's soname +# (and in particular, does not create symlinks for libraries without a soname) +# Copyright (C) 2000-2023 Free Software Foundation, Inc. +# Copyright The GNU Toolchain Authors. +# 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 +# . + +set -ex + +common_objpfx=$1 +test_wrapper_env=$2 +run_program_env=$3 + +testroot="${common_objpfx}elf/bug30125-test-directory" +cleanup () { + rm -rf "$testroot" +} +trap cleanup 0 + +rm -rf "$testroot" +mkdir -p $testroot/lib +cp "${common_objpfx}elf/tst-ldconfig-soname-lib-with-soname.so" \ + $testroot/lib/libtst-ldconfig-soname-lib-with-soname.so.1.2.3 +cp "${common_objpfx}elf/tst-ldconfig-soname-lib-without-soname.so" \ + $testroot/lib/libtst-ldconfig-soname-lib-without-soname.so.1.2.3 + +${test_wrapper_env} \ +${run_program_env} \ +${common_objpfx}elf/ldconfig -vn $testroot/lib + +LINKS=$(cd $testroot/lib && find . -type l) +if [ "$LINKS" != "./libtst-ldconfig-soname-lib-with-soname.so.1" ]; then + echo "error: $0 - extra symlinks found" + exit 1 +fi diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h index 0e1a9a9515..e9e9e19d0f 100644 --- a/sysdeps/generic/ldconfig.h +++ b/sysdeps/generic/ldconfig.h @@ -90,8 +90,6 @@ extern int process_file (const char *real_file_name, const char *file_name, const char *lib, int *flag, unsigned int *isa_level, char **soname, int is_link, struct stat *stat_buf); -extern char *implicit_soname (const char *lib, int flag); - /* Declared in readelflib.c. */ extern int process_elf_file (const char *file_name, const char *lib, int *flag, unsigned int *isa_level, char **soname,