From c78c7515ed91e5392e608e5658c56302b8d33a01 Mon Sep 17 00:00:00 2001 From: Patsy Griffin Date: Thu, 13 Feb 2025 15:43:51 -0500 Subject: [PATCH] Correct locking and cancellation cleanup in syslog functions (RHEL-78390) Resolves: RHEL-78390 --- glibc-RHEL-78390.patch | 114 +++++++++++++++++++++++++++++++++++++++++ glibc.spec | 6 ++- 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-78390.patch diff --git a/glibc-RHEL-78390.patch b/glibc-RHEL-78390.patch new file mode 100644 index 0000000..6745d8a --- /dev/null +++ b/glibc-RHEL-78390.patch @@ -0,0 +1,114 @@ +commit c4e4b2e149705559d28b16a9b47ba2f6142d6a6c +Author: Andreas Schwab +Date: Tue Jun 23 12:55:49 2020 +0200 + + Correct locking and cancellation cleanup in syslog functions (bug 26100) + + Properly serialize the access to the global state shared between the + syslog functions, to avoid races in multithreaded processes. Protect a + local allocation in the __vsyslog_internal function from leaking during + cancellation. + +diff --git a/misc/syslog.c b/misc/syslog.c +index fd6537edf6..2cc63ef287 100644 +--- a/misc/syslog.c ++++ b/misc/syslog.c +@@ -91,14 +91,20 @@ struct cleanup_arg + static void + cancel_handler (void *ptr) + { +-#ifndef NO_SIGPIPE + /* Restore the old signal handler. */ + struct cleanup_arg *clarg = (struct cleanup_arg *) ptr; + +- if (clarg != NULL && clarg->oldaction != NULL) +- __sigaction (SIGPIPE, clarg->oldaction, NULL); ++ if (clarg != NULL) ++ { ++#ifndef NO_SIGPIPE ++ if (clarg->oldaction != NULL) ++ __sigaction (SIGPIPE, clarg->oldaction, NULL); + #endif + ++ /* Free the memstream buffer, */ ++ free (clarg->buf); ++ } ++ + /* Free the lock. */ + __libc_lock_unlock (syslog_lock); + } +@@ -169,9 +175,17 @@ __vsyslog_internal(int pri, const char *fmt, va_list ap, + pri &= LOG_PRIMASK|LOG_FACMASK; + } + ++ /* Prepare for multiple users. We have to take care: most ++ syscalls we are using are cancellation points. */ ++ struct cleanup_arg clarg; ++ clarg.buf = NULL; ++ clarg.oldaction = NULL; ++ __libc_cleanup_push (cancel_handler, &clarg); ++ __libc_lock_lock (syslog_lock); ++ + /* Check priority against setlogmask values. */ + if ((LOG_MASK (LOG_PRI (pri)) & LogMask) == 0) +- return; ++ goto out; + + /* Set default facility if none specified. */ + if ((pri & LOG_FACMASK) == 0) +@@ -235,6 +249,9 @@ __vsyslog_internal(int pri, const char *fmt, va_list ap, + /* Close the memory stream; this will finalize the data + into a malloc'd buffer in BUF. */ + fclose (f); ++ ++ /* Tell the cancellation handler to free this buffer. */ ++ clarg.buf = buf; + } + + /* Output to stderr if requested. */ +@@ -252,22 +269,10 @@ __vsyslog_internal(int pri, const char *fmt, va_list ap, + v->iov_len = 1; + } + +- __libc_cleanup_push (free, buf == failbuf ? NULL : buf); +- + /* writev is a cancellation point. */ + (void)__writev(STDERR_FILENO, iov, v - iov + 1); +- +- __libc_cleanup_pop (0); + } + +- /* Prepare for multiple users. We have to take care: open and +- write are cancellation points. */ +- struct cleanup_arg clarg; +- clarg.buf = buf; +- clarg.oldaction = NULL; +- __libc_cleanup_push (cancel_handler, &clarg); +- __libc_lock_lock (syslog_lock); +- + #ifndef NO_SIGPIPE + /* Prepare for a broken connection. */ + memset (&action, 0, sizeof (action)); +@@ -320,6 +325,7 @@ __vsyslog_internal(int pri, const char *fmt, va_list ap, + __sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL); + #endif + ++ out: + /* End of critical section. */ + __libc_cleanup_pop (0); + __libc_lock_unlock (syslog_lock); +@@ -430,8 +436,14 @@ setlogmask (int pmask) + { + int omask; + ++ /* Protect against multiple users. */ ++ __libc_lock_lock (syslog_lock); ++ + omask = LogMask; + if (pmask != 0) + LogMask = pmask; ++ ++ __libc_lock_unlock (syslog_lock); ++ + return (omask); + } diff --git a/glibc.spec b/glibc.spec index 9e6f364..be058f4 100644 --- a/glibc.spec +++ b/glibc.spec @@ -115,7 +115,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: %{glibcrelease}.13 +Release: %{glibcrelease}.14 # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1258,6 +1258,7 @@ Patch1023: glibc-RHEL-8381-7.patch Patch1024: glibc-RHEL-8381-8.patch Patch1025: glibc-RHEL-8381-9.patch Patch1026: glibc-RHEL-8381-10.patch +Patch1027: glibc-RHEL-78390.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2919,6 +2920,9 @@ fi %{_libdir}/libpthread_nonshared.a %changelog +* Tue Feb 11 2025 Patsy Griffin - 2.28-251.14 +- Correct locking and cancellation cleanup in syslog functions (RHEL-78390) + * Fri Feb 7 2025 Carlos O'Donell - 2.28-251.13 - Restore internal ABI to avoid tooling false positives (RHEL-8381)