Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package glibc for openSUSE:Factory checked in at 2023-07-13 17:17:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/glibc (Old) and /work/SRC/openSUSE:Factory/.glibc.new.8922 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "glibc" Thu Jul 13 17:17:39 2023 rev:276 rq:1098078 version:2.37 Changes: -------- --- /work/SRC/openSUSE:Factory/glibc/glibc.changes 2023-05-31 21:54:05.796863251 +0200 +++ /work/SRC/openSUSE:Factory/.glibc.new.8922/glibc.changes 2023-07-13 17:17:40.664808960 +0200 @@ -1,0 +2,27 @@ +Mon Jul 10 08:46:18 UTC 2023 - Andreas Schwab <[email protected]> + +- gshadow-erange-rhandling.patch: gshadow: Matching sgetsgent, sgetsgent_r + ERANGE handling (BZ #30151) +- system-sigchld-block.patch: posix: Fix system blocks SIGCHLD erroneously + (BZ #30163) +- gmon-buffer-alloc.patch: gmon: Fix allocated buffer overflow (BZ #29444) +- check-pf-cancel-handler.patch: __check_pf: Add a cancellation cleanup + handler (BZ #20975) +- powerpc64-fcntl-lock.patch: io: Fix F_GETLK, F_SETLK, and F_SETLKW for + powerpc64 +- realloc-limit-chunk-reuse.patch: realloc: Limit chunk reuse to only + growing requests (BZ #30579) +- dl-find-object-return.patch: elf: _dl_find_object may return 1 during + early startup (BZ #30515) + +------------------------------------------------------------------- +Mon Jul 3 16:31:17 UTC 2023 - Andreas Schwab <[email protected]> + +- Need to build with GCC 12 as minimum + +------------------------------------------------------------------- +Thu Jun 29 13:05:55 UTC 2023 - Andreas Schwab <[email protected]> + +- fix-locking-in-_IO_cleanup.patch: Update to final version + +------------------------------------------------------------------- New: ---- check-pf-cancel-handler.patch dl-find-object-return.patch gmon-buffer-alloc.patch gshadow-erange-rhandling.patch powerpc64-fcntl-lock.patch realloc-limit-chunk-reuse.patch system-sigchld-block.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ glibc.spec ++++++ --- /var/tmp/diff_new_pack.8JYQrg/_old 2023-07-13 17:17:42.156817765 +0200 +++ /var/tmp/diff_new_pack.8JYQrg/_new 2023-07-13 17:17:42.160817789 +0200 @@ -49,6 +49,10 @@ %bcond_with usrmerged %endif +%if %{gcc_version} < 12 +%define with_gcc 12 +%endif + # Enable support for livepatching. %ifarch x86_64 %bcond_without livepatching @@ -205,8 +209,11 @@ BuildRequires: systemtap-headers BuildRequires: sysuser-tools BuildRequires: xz +%if 0%{?with_gcc:1} +BuildRequires: gcc%{with_gcc} +%endif %if %{build_testsuite} -BuildRequires: gcc-c++ +BuildRequires: gcc%{?with_gcc}-c++ BuildRequires: gdb BuildRequires: glibc-devel-static BuildRequires: libidn2-0 @@ -219,7 +226,7 @@ BuildRequires: zlib-devel %endif %if %{build_cross} -BuildRequires: cross-%{cross_arch}-gcc%{gcc_version}-bootstrap +BuildRequires: cross-%{cross_arch}-gcc%{!?with_gcc:%{gcc_version}}%{?with_gcc}-bootstrap BuildRequires: cross-%{cross_arch}-linux-glibc-devel %endif %if "%flavor" == "i686" @@ -288,14 +295,28 @@ Patch1001: strftime-time64.patch # PATCH-FIX-UPSTREAM getlogin_r: fix missing fallback if loginuid is unset (BZ #30235) Patch1002: getlogin-no-loginuid.patch +# PATCH-FIX-UPSTREAM Always to locking when accessing streams (BZ #15142) +Patch1003: fix-locking-in-_IO_cleanup.patch +# PATCH-FIX-UPSTREAM gshadow: Matching sgetsgent, sgetsgent_r ERANGE handling (BZ #30151) +Patch1004: gshadow-erange-rhandling.patch +# PATCH-FIX-UPSTREAM posix: Fix system blocks SIGCHLD erroneously (BZ #30163) +Patch1005: system-sigchld-block.patch +# PATCH-FIX-UPSTREAM gmon: Fix allocated buffer overflow (BZ #29444) +Patch1006: gmon-buffer-alloc.patch +# PATCH-FIX-UPSTREAM __check_pf: Add a cancellation cleanup handler (BZ #20975) +Patch1007: check-pf-cancel-handler.patch +# PATCH-FIX-UPSTREAM io: Fix F_GETLK, F_SETLK, and F_SETLKW for powerpc64 +Patch1008: powerpc64-fcntl-lock.patch +# PATCH-FIX-UPSTREAM realloc: Limit chunk reuse to only growing requests (BZ #30579) +Patch1009: realloc-limit-chunk-reuse.patch +# PATCH-FIX-UPSTREAM elf: _dl_find_object may return 1 during early startup (BZ #30515) +Patch1010: dl-find-object-return.patch ### # Patches awaiting upstream approval ### -# PATCH-FIX-UPSTREAM Always to locking when accessing streams (BZ #15142) -Patch2000: fix-locking-in-_IO_cleanup.patch # PATCH-FIX-UPSTREAM Avoid concurrency problem in ldconfig (BZ #23973) -Patch2001: ldconfig-concurrency.patch +Patch2000: ldconfig-concurrency.patch # Non-glibc patches # PATCH-FIX-OPENSUSE Remove debianisms from manpages @@ -516,10 +537,17 @@ %patch1000 -p1 %patch1001 -p1 %patch1002 -p1 +%patch1003 -p1 +%patch1004 -p1 +%patch1005 -p1 +%patch1006 -p1 +%patch1007 -p1 +%patch1008 -p1 +%patch1009 -p1 +%patch1010 -p1 %endif %patch2000 -p1 -%patch2001 -p1 %patch3000 rm -f manpages/catchsegv.1 @@ -579,8 +607,13 @@ %if "%flavor" == "i686" BuildFlags+=" -march=i686 -mtune=generic" %endif +%if 0%{?with_gcc:1} +BuildCC="gcc-%{with_gcc}" +BuildCCplus="g++-%{with_gcc}" +%else BuildCC="%__cc" BuildCCplus="%__cxx" +%endif # #now overwrite for some architectures ++++++ check-pf-cancel-handler.patch ++++++ >From f5d377c896b95fefc712b0fd5e5804ae3f48d392 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <[email protected]> Date: Thu, 27 Apr 2023 13:06:15 -0700 Subject: [PATCH] __check_pf: Add a cancellation cleanup handler [BZ #20975] There are reports for hang in __check_pf: https://github.com/JoeDog/siege/issues/4 It is reproducible only under specific configurations: 1. Large number of cores (>= 64) and large number of threads (> 3X of the number of cores) with long lived socket connection. 2. Low power (frequency) mode. 3. Power management is enabled. While holding lock, __check_pf calls make_request which calls __sendto and __recvmsg. Since __sendto and __recvmsg are cancellation points, lock held by __check_pf won't be released and can cause deadlock when thread cancellation happens in __sendto or __recvmsg. Add a cancellation cleanup handler for __check_pf to unlock the lock when cancelled by another thread. This fixes BZ #20975 and the siege hang issue. (cherry picked from commit a443bd3fb233186038b8b483959ecb7978d1abea) --- sysdeps/unix/sysv/linux/Makefile | 2 ++ sysdeps/unix/sysv/linux/check_pf.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile index f298878e8f..94747b37a6 100644 --- a/sysdeps/unix/sysv/linux/Makefile +++ b/sysdeps/unix/sysv/linux/Makefile @@ -456,6 +456,8 @@ sysdep_headers += netinet/if_fddi.h netinet/if_tr.h \ netrom/netrom.h netpacket/packet.h netrose/rose.h \ neteconet/ec.h netiucv/iucv.h sysdep_routines += netlink_assert_response + +CFLAGS-check_pf.c += -fexceptions endif # Don't compile the ctype glue code, since there is no old non-GNU C library. diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c index de207122b0..50654cb28d 100644 --- a/sysdeps/unix/sysv/linux/check_pf.c +++ b/sysdeps/unix/sysv/linux/check_pf.c @@ -292,6 +292,14 @@ make_request (int fd, pid_t pid) return NULL; } +#ifdef __EXCEPTIONS +static void +cancel_handler (void *arg __attribute__((unused))) +{ + /* Release the lock. */ + __libc_lock_unlock (lock); +} +#endif void attribute_hidden @@ -304,6 +312,10 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6, struct cached_data *olddata = NULL; struct cached_data *data = NULL; +#ifdef __EXCEPTIONS + /* Make sure that lock is released when the thread is cancelled. */ + __libc_cleanup_push (cancel_handler, NULL); +#endif __libc_lock_lock (lock); if (cache_valid_p ()) @@ -338,6 +350,9 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6, } } +#ifdef __EXCEPTIONS + __libc_cleanup_pop (0); +#endif __libc_lock_unlock (lock); if (data != NULL) -- 2.41.0 ++++++ dl-find-object-return.patch ++++++ >From 3f4b4e2cdd529266ea5a2c6c5e0c66bab81bfd0e Mon Sep 17 00:00:00 2001 From: Florian Weimer <[email protected]> Date: Fri, 7 Jul 2023 10:11:26 +0200 Subject: [PATCH] elf: _dl_find_object may return 1 during early startup (bug 30515) Success is reported with a 0 return value, and failure is -1. Enhance the kitchen sink test elf/tst-audit28 to cover _dl_find_object as well. Fixes commit 5d28a8962dcb ("elf: Add _dl_find_object function") and bug 30515. Reviewed-by: Carlos O'Donell <[email protected]> Tested-by: Carlos O'Donell <[email protected]> (cherry picked from commit 1bcfe0f732066ae5336b252295591ebe7e51c301) --- NEWS | 1 + elf/dl-find_object.c | 2 +- elf/tst-auditmod28.c | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/elf/dl-find_object.c b/elf/dl-find_object.c index 2ced2f3510..934e77e11f 100644 --- a/elf/dl-find_object.c +++ b/elf/dl-find_object.c @@ -46,7 +46,7 @@ _dl_find_object_slow (void *pc, struct dl_find_object *result) struct dl_find_object_internal internal; _dl_find_object_from_map (l, &internal); _dl_find_object_to_external (&internal, result); - return 1; + return 0; } /* Object not found. */ diff --git a/elf/tst-auditmod28.c b/elf/tst-auditmod28.c index f6ab991398..f6dfbbe202 100644 --- a/elf/tst-auditmod28.c +++ b/elf/tst-auditmod28.c @@ -71,6 +71,17 @@ la_version (unsigned int current) TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0); TEST_VERIFY (extra_info == handle); + /* Check _dl_find_object. */ + struct dl_find_object dlfo; + TEST_COMPARE (_dl_find_object (__builtin_return_address (0), &dlfo), 0); + /* "ld.so" is seen with --enable-hardcoded-path-in-tests. */ + if (strcmp (basename (dlfo.dlfo_link_map->l_name), "ld.so") != 0) + TEST_COMPARE_STRING (basename (dlfo.dlfo_link_map->l_name), LD_SO); + TEST_COMPARE (_dl_find_object (dlsym (handle, "environ"), &dlfo), 0); + TEST_COMPARE_STRING (basename (dlfo.dlfo_link_map->l_name), LIBC_SO); + TEST_COMPARE (_dl_find_object ((void *) 1, &dlfo), -1); + TEST_COMPARE (_dl_find_object ((void *) -1, &dlfo), -1); + /* Verify that dlmopen creates a new namespace. */ void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW); TEST_VERIFY (dlmopen_handle != handle); -- 2.41.0 ++++++ fix-locking-in-_IO_cleanup.patch ++++++ --- /var/tmp/diff_new_pack.8JYQrg/_old 2023-07-13 17:17:42.244818284 +0200 +++ /var/tmp/diff_new_pack.8JYQrg/_new 2023-07-13 17:17:42.248818308 +0200 @@ -2,13 +2,12 @@ Now that abort no longer calls fflush there is no reason to avoid locking the stdio streams anywhere. This fixes a conformance issue and potential -heap corruption during exit. The test nptl/tst-stdio1 is removed as that -was expecting the problematic behaviour. +heap corruption during exit. -Index: glibc-2.32/libio/genops.c +Index: glibc-2.37/libio/genops.c =================================================================== ---- glibc-2.32.orig/libio/genops.c -+++ glibc-2.32/libio/genops.c +--- glibc-2.37.orig/libio/genops.c ++++ glibc-2.37/libio/genops.c @@ -682,7 +682,7 @@ _IO_adjust_column (unsigned start, const libc_hidden_def (_IO_adjust_column) @@ -114,11 +113,11 @@ /* We currently don't have a reliable mechanism for making sure that C++ static destructors are executed in the correct order. -Index: glibc-2.32/libio/libioP.h +Index: glibc-2.37/libio/libioP.h =================================================================== ---- glibc-2.32.orig/libio/libioP.h -+++ glibc-2.32/libio/libioP.h -@@ -487,7 +487,6 @@ extern int _IO_new_do_write (FILE *, con +--- glibc-2.37.orig/libio/libioP.h ++++ glibc-2.37/libio/libioP.h +@@ -488,7 +488,6 @@ extern int _IO_new_do_write (FILE *, con extern int _IO_old_do_write (FILE *, const char *, size_t); extern int _IO_wdo_write (FILE *, const wchar_t *, size_t); libc_hidden_proto (_IO_wdo_write) @@ -126,77 +125,110 @@ extern int _IO_flush_all (void); libc_hidden_proto (_IO_flush_all) extern int _IO_cleanup (void); -Index: glibc-2.32/sysdeps/pthread/Makefile +Index: glibc-2.37/support/delayed_exit.c =================================================================== ---- glibc-2.32.orig/sysdeps/pthread/Makefile -+++ glibc-2.32/sysdeps/pthread/Makefile -@@ -99,7 +99,7 @@ tests += tst-cnd-basic tst-mtx-trylock t - tst-signal4 tst-signal5 tst-signal6 tst-signal8 \ - tst-spin1 tst-spin2 tst-spin3 tst-spin4 \ - tst-stack1 \ -- tst-stdio1 tst-stdio2 \ -+ tst-stdio2 \ - tst-pt-sysconf \ - tst-pt-tls1 tst-pt-tls2 \ - tst-tsd1 tst-tsd2 tst-tsd5 tst-tsd6 \ -Index: glibc-2.32/sysdeps/pthread/tst-stdio1.c +--- glibc-2.37.orig/support/delayed_exit.c ++++ glibc-2.37/support/delayed_exit.c +@@ -23,33 +23,58 @@ + #include <stdio.h> + #include <stdlib.h> + #include <support/check.h> ++#include <support/support.h> + #include <time.h> ++#include <unistd.h> ++ ++struct delayed_exit_request ++{ ++ void (*exitfunc) (int); ++ int seconds; ++}; + + static void * +-delayed_exit_thread (void *seconds_as_ptr) ++delayed_exit_thread (void *closure) + { +- int seconds = (uintptr_t) seconds_as_ptr; +- struct timespec delay = { seconds, 0 }; ++ struct delayed_exit_request *request = closure; ++ void (*exitfunc) (int) = request->exitfunc; ++ struct timespec delay = { request->seconds, 0 }; + struct timespec remaining = { 0 }; ++ free (request); ++ + if (nanosleep (&delay, &remaining) != 0) + FAIL_EXIT1 ("nanosleep: %m"); + /* Exit the process sucessfully. */ +- exit (0); ++ exitfunc (0); + return NULL; + } + +-void +-delayed_exit (int seconds) ++static void ++delayed_exit_1 (int seconds, void (*exitfunc) (int)) + { + /* Create the new thread with all signals blocked. */ + sigset_t all_blocked; + sigfillset (&all_blocked); + sigset_t old_set; + xpthread_sigmask (SIG_SETMASK, &all_blocked, &old_set); ++ struct delayed_exit_request *request = xmalloc (sizeof (*request)); ++ request->seconds = seconds; ++ request->exitfunc = exitfunc; + /* Create a detached thread. */ +- pthread_t thr = xpthread_create +- (NULL, delayed_exit_thread, (void *) (uintptr_t) seconds); ++ pthread_t thr = xpthread_create (NULL, delayed_exit_thread, request); + xpthread_detach (thr); + /* Restore the original signal mask. */ + xpthread_sigmask (SIG_SETMASK, &old_set, NULL); + } ++ ++void ++delayed_exit (int seconds) ++{ ++ delayed_exit_1 (seconds, exit); ++} ++ ++void ++delayed__exit (int seconds) ++{ ++ delayed_exit_1 (seconds, _exit); ++} +Index: glibc-2.37/support/xthread.h =================================================================== ---- glibc-2.32.orig/sysdeps/pthread/tst-stdio1.c -+++ /dev/null -@@ -1,55 +0,0 @@ --/* Copyright (C) 2002-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 -- <https://www.gnu.org/licenses/>. */ -- --#include <pthread.h> --#include <signal.h> --#include <stdio.h> --#include <unistd.h> -- --static int do_test (void); -- --#define TEST_FUNCTION do_test () --#include "../test-skeleton.c" -- --static void *tf (void *a) --{ -- flockfile (stdout); -- /* This call should never return. */ -- return a; --} -- -- --int --do_test (void) --{ -- pthread_t th; -- -- flockfile (stdout); -- -- if (pthread_create (&th, NULL, tf, NULL) != 0) -- { -- write_message ("create failed\n"); -- _exit (1); -- } -- +--- glibc-2.37.orig/support/xthread.h ++++ glibc-2.37/support/xthread.h +@@ -25,11 +25,14 @@ + + __BEGIN_DECLS + +-/* Terminate the process (with exit status 0) after SECONDS have +- elapsed, from a helper thread. The process is terminated with the +- exit function, so atexit handlers are executed. */ ++/* Terminate the process (with exit (0)) after SECONDS have elapsed, ++ from a helper thread. The process is terminated with the exit ++ function, so atexit handlers are executed. */ + void delayed_exit (int seconds); + ++/* Like delayed_exit, but use _exit (0). */ ++void delayed__exit (int seconds); ++ + /* Returns true if Priority Inheritance support CLOCK_MONOTONIC. */ + bool support_mutex_pi_monotonic (void); + +Index: glibc-2.37/sysdeps/pthread/tst-stdio1.c +=================================================================== +--- glibc-2.37.orig/sysdeps/pthread/tst-stdio1.c ++++ glibc-2.37/sysdeps/pthread/tst-stdio1.c +@@ -46,7 +46,7 @@ do_test (void) + _exit (1); + } + - delayed_exit (1); -- xpthread_join (th); -- -- puts ("join returned"); -- -- return 1; --} ++ delayed__exit (1); + xpthread_join (th); + + puts ("join returned"); ++++++ gmon-buffer-alloc.patch ++++++ >From 801af9fafd4689337ebf27260aa115335a0cb2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= <[email protected]> Date: Sat, 4 Feb 2023 14:41:38 +0300 Subject: [PATCH] gmon: Fix allocated buffer overflow (bug 29444) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `__monstartup()` allocates a buffer used to store all the data accumulated by the monitor. The size of this buffer depends on the size of the internal structures used and the address range for which the monitor is activated, as well as on the maximum density of call instructions and/or callable functions that could be potentially on a segment of executable code. In particular a hash table of arcs is placed at the end of this buffer. The size of this hash table is calculated in bytes as p->fromssize = p->textsize / HASHFRACTION; but actually should be p->fromssize = ROUNDUP(p->textsize / HASHFRACTION, sizeof(*p->froms)); This results in writing beyond the end of the allocated buffer when an added arc corresponds to a call near from the end of the monitored address range, since `_mcount()` check the incoming caller address for monitored range but not the intermediate result hash-like index that uses to write into the table. It should be noted that when the results are output to `gmon.out`, the table is read to the last element calculated from the allocated size in bytes, so the arcs stored outside the buffer boundary did not fall into `gprof` for analysis. Thus this "feature" help me to found this bug during working with https://sourceware.org/bugzilla/show_bug.cgi?id=29438 Just in case, I will explicitly note that the problem breaks the `make test t=gmon/tst-gmon-dso` added for Bug 29438. There, the arc of the `f3()` call disappears from the output, since in the DSO case, the call to `f3` is located close to the end of the monitored range. Signed-off-by: Ðеонид ЮÑÑев (Leonid Yuriev) <[email protected]> Another minor error seems a related typo in the calculation of `kcountsize`, but since kcounts are smaller than froms, this is actually to align the p->froms data. Co-authored-by: DJ Delorie <[email protected]> Reviewed-by: Carlos O'Donell <[email protected]> --- gmon/gmon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gmon/gmon.c b/gmon/gmon.c index dee64803ad..bf76358d5b 100644 --- a/gmon/gmon.c +++ b/gmon/gmon.c @@ -132,6 +132,8 @@ __monstartup (u_long lowpc, u_long highpc) p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER)); p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER)); p->textsize = p->highpc - p->lowpc; + /* This looks like a typo, but it's here to align the p->froms + section. */ p->kcountsize = ROUNDUP(p->textsize / HISTFRACTION, sizeof(*p->froms)); p->hashfraction = HASHFRACTION; p->log_hashfraction = -1; @@ -142,7 +144,7 @@ __monstartup (u_long lowpc, u_long highpc) instead of integer division. Precompute shift amount. */ p->log_hashfraction = ffs(p->hashfraction * sizeof(*p->froms)) - 1; } - p->fromssize = p->textsize / HASHFRACTION; + p->fromssize = ROUNDUP(p->textsize / HASHFRACTION, sizeof(*p->froms)); p->tolimit = p->textsize * ARCDENSITY / 100; if (p->tolimit < MINARCS) p->tolimit = MINARCS; -- 2.41.0 ++++++ gshadow-erange-rhandling.patch ++++++ >From 969e9733c7d17edf1e239a73fa172f357561f440 Mon Sep 17 00:00:00 2001 From: Florian Weimer <[email protected]> Date: Tue, 21 Feb 2023 09:20:28 +0100 Subject: [PATCH] gshadow: Matching sgetsgent, sgetsgent_r ERANGE handling (bug 30151) Before this change, sgetsgent_r did not set errno to ERANGE, but sgetsgent only check errno, not the return value from sgetsgent_r. Consequently, sgetsgent did not detect any error, and reported success to the caller, without initializing the struct sgrp object whose address was returned. This commit changes sgetsgent_r to set errno as well. This avoids similar issues in applications which only change errno. Reviewed-by: Siddhesh Poyarekar <[email protected]> --- gshadow/Makefile | 2 +- gshadow/sgetsgent_r.c | 5 ++- gshadow/tst-sgetsgent.c | 69 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 gshadow/tst-sgetsgent.c diff --git a/gshadow/Makefile b/gshadow/Makefile index 796fbbf473..a95524593a 100644 --- a/gshadow/Makefile +++ b/gshadow/Makefile @@ -26,7 +26,7 @@ headers = gshadow.h routines = getsgent getsgnam sgetsgent fgetsgent putsgent \ getsgent_r getsgnam_r sgetsgent_r fgetsgent_r -tests = tst-gshadow tst-putsgent tst-fgetsgent_r +tests = tst-gshadow tst-putsgent tst-fgetsgent_r tst-sgetsgent CFLAGS-getsgent_r.c += -fexceptions CFLAGS-getsgent.c += -fexceptions diff --git a/gshadow/sgetsgent_r.c b/gshadow/sgetsgent_r.c index ea085e91d7..c75624e1f7 100644 --- a/gshadow/sgetsgent_r.c +++ b/gshadow/sgetsgent_r.c @@ -61,7 +61,10 @@ __sgetsgent_r (const char *string, struct sgrp *resbuf, char *buffer, buffer[buflen - 1] = '\0'; sp = strncpy (buffer, string, buflen); if (buffer[buflen - 1] != '\0') - return ERANGE; + { + __set_errno (ERANGE); + return ERANGE; + } } else sp = (char *) string; diff --git a/gshadow/tst-sgetsgent.c b/gshadow/tst-sgetsgent.c new file mode 100644 index 0000000000..0370c10fd0 --- /dev/null +++ b/gshadow/tst-sgetsgent.c @@ -0,0 +1,69 @@ +/* Test large input for sgetsgent (bug 30151). + 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 + <https://www.gnu.org/licenses/>. */ + +#include <gshadow.h> +#include <stddef.h> +#include <support/check.h> +#include <support/support.h> +#include <support/xmemstream.h> +#include <stdlib.h> + +static int +do_test (void) +{ + /* Create a shadow group with 1000 members. */ + struct xmemstream mem; + xopen_memstream (&mem); + const char *passwd = "k+zD0nucwfxAo3sw1NXUj6K5vt5M16+X0TVGdE1uFvq5R8V7efJ"; + fprintf (mem.out, "group-name:%s::m0", passwd); + for (int i = 1; i < 1000; ++i) + fprintf (mem.out, ",m%d", i); + xfclose_memstream (&mem); + + /* Call sgetsgent. */ + char *input = mem.buffer; + struct sgrp *e = sgetsgent (input); + TEST_VERIFY_EXIT (e != NULL); + TEST_COMPARE_STRING (e->sg_namp, "group-name"); + TEST_COMPARE_STRING (e->sg_passwd, passwd); + /* No administrators. */ + TEST_COMPARE_STRING (e->sg_adm[0], NULL); + /* Check the members list. */ + for (int i = 0; i < 1000; ++i) + { + char *member = xasprintf ("m%d", i); + TEST_COMPARE_STRING (e->sg_mem[i], member); + free (member); + } + TEST_COMPARE_STRING (e->sg_mem[1000], NULL); + + /* Check that putsgent brings back the input string. */ + xopen_memstream (&mem); + TEST_COMPARE (putsgent (e, mem.out), 0); + xfclose_memstream (&mem); + /* Compare without the trailing '\n' that putsgent added. */ + TEST_COMPARE (mem.buffer[mem.length - 1], '\n'); + mem.buffer[mem.length - 1] = '\0'; + TEST_COMPARE_STRING (mem.buffer, input); + + free (mem.buffer); + free (input); + return 0; +} + +#include <support/test-driver.c> -- 2.41.0 ++++++ powerpc64-fcntl-lock.patch ++++++ >From 5f828ff824e3b7cd133ef905b8ae25ab8a8f3d66 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella <[email protected]> Date: Tue, 30 May 2023 16:40:38 -0300 Subject: [PATCH] io: Fix F_GETLK, F_SETLK, and F_SETLKW for powerpc64 Different than other 64 bit architectures, powerpc64 defines the LFS POSIX lock constants with values similar to 32 ABI, which are meant to be used with fcntl64 syscall. Since powerpc64 kABI does not have fcntl, the constants are adjusted with the FCNTL_ADJUST_CMD macro. The 4d0fe291aed3a476a changed the logic of generic constants LFS value are equal to the default values; which is now wrong for powerpc64. Fix the value by explicit define the previous glibc constants (powerpc64 does not need to use the 32 kABI value, but it simplifies the FCNTL_ADJUST_CMD which should be kept as compatibility). Checked on powerpc64-linux-gnu and powerpc-linux-gnu. --- sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h index 0905cd833c..f7615a447e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h +++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h @@ -33,6 +33,12 @@ # define __O_LARGEFILE 0200000 #endif +#if __WORDSIZE == 64 +# define F_GETLK 5 +# define F_SETLK 6 +# define F_SETLKW 7 +#endif + struct flock { short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ -- 2.41.0 ++++++ realloc-limit-chunk-reuse.patch ++++++ >From 0930ff8eb35cb493c945f176c3c9ab320f4d1b86 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar <[email protected]> Date: Thu, 6 Jul 2023 11:09:44 -0400 Subject: [PATCH] realloc: Limit chunk reuse to only growing requests [BZ #30579] The trim_threshold is too aggressive a heuristic to decide if chunk reuse is OK for reallocated memory; for repeated small, shrinking allocations it leads to internal fragmentation and for repeated larger allocations that fragmentation may blow up even worse due to the dynamic nature of the threshold. Limit reuse only when it is within the alignment padding, which is 2 * size_t for heap allocations and a page size for mmapped allocations. There's the added wrinkle of THP, but this fix ignores it for now, pessimizing that case in favor of keeping fragmentation low. This resolves BZ #30579. Signed-off-by: Siddhesh Poyarekar <[email protected]> Reported-by: Nicolas Dusart <[email protected]> Reported-by: Aurelien Jarno <[email protected]> Reviewed-by: Aurelien Jarno <[email protected]> Tested-by: Aurelien Jarno <[email protected]> (cherry picked from commit 2fb12bbd092b0c10f1f2083216e723d2406e21c4) --- malloc/malloc.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/malloc/malloc.c b/malloc/malloc.c index fd8b52bfac..67df9f8c51 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -3398,16 +3398,23 @@ __libc_realloc (void *oldmem, size_t bytes) if (__glibc_unlikely (mtag_enabled)) *(volatile char*) oldmem; - /* Return the chunk as is whenever possible, i.e. there's enough usable space - but not so much that we end up fragmenting the block. We use the trim - threshold as the heuristic to decide the latter. */ - size_t usable = musable (oldmem); - if (bytes <= usable - && (unsigned long) (usable - bytes) <= mp_.trim_threshold) - return oldmem; - /* chunk corresponding to oldmem */ const mchunkptr oldp = mem2chunk (oldmem); + + /* Return the chunk as is if the request grows within usable bytes, typically + into the alignment padding. We want to avoid reusing the block for + shrinkages because it ends up unnecessarily fragmenting the address space. + This is also why the heuristic misses alignment padding for THP for + now. */ + size_t usable = musable (oldmem); + if (bytes <= usable) + { + size_t difference = usable - bytes; + if ((unsigned long) difference < 2 * sizeof (INTERNAL_SIZE_T) + || (chunk_is_mmapped (oldp) && difference <= GLRO (dl_pagesize))) + return oldmem; + } + /* its size */ const INTERNAL_SIZE_T oldsize = chunksize (oldp); -- 2.41.0 ++++++ system-sigchld-block.patch ++++++ >From 436a604b7dc741fc76b5a6704c6cd8bb178518e7 Mon Sep 17 00:00:00 2001 From: Adam Yi <[email protected]> Date: Tue, 7 Mar 2023 07:30:02 -0500 Subject: [PATCH] posix: Fix system blocks SIGCHLD erroneously [BZ #30163] Fix bug that SIGCHLD is erroneously blocked forever in the following scenario: 1. Thread A calls system but hasn't returned yet 2. Thread B calls another system but returns SIGCHLD would be blocked forever in thread B after its system() returns, even after the system() in thread A returns. Although POSIX does not require, glibc system implementation aims to be thread and cancellation safe. This bug was introduced in 5fb7fc96350575c9adb1316833e48ca11553be49 when we moved reverting signal mask to happen when the last concurrently running system returns, despite that signal mask is per thread. This commit reverts this logic and adds a test. Signed-off-by: Adam Yi <[email protected]> Reviewed-by: Adhemerval Zanella <[email protected]> --- stdlib/tst-system.c | 26 +++++++++++++++++++ support/Makefile | 2 ++ support/dtotimespec-time64.c | 27 +++++++++++++++++++ support/dtotimespec.c | 50 ++++++++++++++++++++++++++++++++++++ support/shell-container.c | 28 ++++++++++++++++++++ support/timespec.h | 4 +++ sysdeps/posix/system.c | 6 ++--- 7 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 support/dtotimespec-time64.c create mode 100644 support/dtotimespec.c diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c index 634acfe264..47a0afe6bf 100644 --- a/stdlib/tst-system.c +++ b/stdlib/tst-system.c @@ -25,6 +25,7 @@ #include <support/check.h> #include <support/temp_file.h> #include <support/support.h> +#include <support/xthread.h> #include <support/xunistd.h> static char *tmpdir; @@ -71,6 +72,20 @@ call_system (void *closure) } } +static void * +sleep_and_check_sigchld (void *closure) +{ + double *seconds = (double *) closure; + char cmd[namemax]; + sprintf (cmd, "sleep %lf" , *seconds); + TEST_COMPARE (system (cmd), 0); + + sigset_t blocked = {0}; + TEST_COMPARE (sigprocmask (SIG_BLOCK, NULL, &blocked), 0); + TEST_COMPARE (sigismember (&blocked, SIGCHLD), 0); + return NULL; +} + static int do_test (void) { @@ -154,6 +169,17 @@ do_test (void) xchmod (_PATH_BSHELL, st.st_mode); } + { + pthread_t long_sleep_thread = xpthread_create (NULL, + sleep_and_check_sigchld, + &(double) { 0.2 }); + pthread_t short_sleep_thread = xpthread_create (NULL, + sleep_and_check_sigchld, + &(double) { 0.1 }); + xpthread_join (short_sleep_thread); + xpthread_join (long_sleep_thread); + } + TEST_COMPARE (system (""), 0); return 0; diff --git a/support/Makefile b/support/Makefile index d52c472755..05b31159ea 100644 --- a/support/Makefile +++ b/support/Makefile @@ -32,6 +32,8 @@ libsupport-routines = \ check_hostent \ check_netent \ delayed_exit \ + dtotimespec \ + dtotimespec-time64 \ ignore_stderr \ next_to_fault \ oom_error \ diff --git a/support/dtotimespec-time64.c b/support/dtotimespec-time64.c new file mode 100644 index 0000000000..b3d5e351e3 --- /dev/null +++ b/support/dtotimespec-time64.c @@ -0,0 +1,27 @@ +/* Convert double to timespec. 64-bit time support. + Copyright (C) 2011-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <time.h> + +#if __TIMESIZE != 64 +# define timespec __timespec64 +# define time_t __time64_t +# define dtotimespec dtotimespec_time64 +# include "dtotimespec.c" +#endif diff --git a/support/dtotimespec.c b/support/dtotimespec.c new file mode 100644 index 0000000000..cde5b4d74c --- /dev/null +++ b/support/dtotimespec.c @@ -0,0 +1,50 @@ +/* Convert double to timespec. + Copyright (C) 2011-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library and is also part of gnulib. + Patches to this file should be submitted to both projects. + + 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 + <https://www.gnu.org/licenses/>. */ + +/* Convert the double value SEC to a struct timespec. Round toward + positive infinity. On overflow, return an extremal value. */ + +#include <support/timespec.h> +#include <intprops.h> + +struct timespec +dtotimespec (double sec) +{ + if (sec <= TYPE_MINIMUM (time_t)) + return make_timespec (TYPE_MINIMUM (time_t), 0); + else if (sec >= 1.0 + TYPE_MAXIMUM (time_t)) + return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1); + else + { + time_t s = sec; + double frac = TIMESPEC_HZ * (sec - s); + long ns = frac; + ns += ns < frac; + s += ns / TIMESPEC_HZ; + ns %= TIMESPEC_HZ; + + if (ns < 0) + { + s--; + ns += TIMESPEC_HZ; + } + + return make_timespec (s, ns); + } +} diff --git a/support/shell-container.c b/support/shell-container.c index ffa3378b5e..b1f9e793c1 100644 --- a/support/shell-container.c +++ b/support/shell-container.c @@ -37,6 +37,7 @@ #include <error.h> #include <support/support.h> +#include <support/timespec.h> /* Design considerations @@ -169,6 +170,32 @@ kill_func (char **argv) return 0; } +/* Emulate the "/bin/sleep" command. No suffix support. Options are + ignored. */ +static int +sleep_func (char **argv) +{ + if (argv[0] == NULL) + { + fprintf (stderr, "sleep: missing operand\n"); + return 1; + } + char *endptr = NULL; + double sec = strtod (argv[0], &endptr); + if (endptr == argv[0] || errno == ERANGE || sec < 0) + { + fprintf (stderr, "sleep: invalid time interval '%s'\n", argv[0]); + return 1; + } + struct timespec ts = dtotimespec (sec); + if (nanosleep (&ts, NULL) < 0) + { + fprintf (stderr, "sleep: failed to nanosleep: %s\n", strerror (errno)); + return 1; + } + return 0; +} + /* This is a list of all the built-in commands we understand. */ static struct { const char *name; @@ -179,6 +206,7 @@ static struct { { "cp", copy_func }, { "exit", exit_func }, { "kill", kill_func }, + { "sleep", sleep_func }, { NULL, NULL } }; diff --git a/support/timespec.h b/support/timespec.h index 77b1e4e8d6..9559836d4c 100644 --- a/support/timespec.h +++ b/support/timespec.h @@ -57,6 +57,8 @@ int support_timespec_check_in_range (struct timespec expected, struct timespec observed, double lower_bound, double upper_bound); +struct timespec dtotimespec (double sec) __attribute__((const)); + #else struct timespec __REDIRECT (timespec_add, (struct timespec, struct timespec), timespec_add_time64); @@ -82,6 +84,8 @@ int __REDIRECT (support_timespec_check_in_range, (struct timespec expected, double lower_bound, double upper_bound), support_timespec_check_in_range_time64); + +struct timespec __REDIRECT (dtotimespec, (double sec), dtotimespec_time64); #endif /* Check that the timespec on the left represents a time before the diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c index 2335a99184..d77720a625 100644 --- a/sysdeps/posix/system.c +++ b/sysdeps/posix/system.c @@ -179,16 +179,16 @@ do_system (const char *line) as if the shell had terminated using _exit(127). */ status = W_EXITCODE (127, 0); + /* sigaction can not fail with SIGINT/SIGQUIT used with old + disposition. Same applies for sigprocmask. */ DO_LOCK (); if (SUB_REF () == 0) { - /* sigaction can not fail with SIGINT/SIGQUIT used with old - disposition. Same applies for sigprocmask. */ __sigaction (SIGINT, &intr, NULL); __sigaction (SIGQUIT, &quit, NULL); - __sigprocmask (SIG_SETMASK, &omask, NULL); } DO_UNLOCK (); + __sigprocmask (SIG_SETMASK, &omask, NULL); if (ret != 0) __set_errno (ret); -- 2.41.0
