From ccb58cf702596222c8965a50bb483f4eff055c3e Mon Sep 17 00:00:00 2001 From: liqingqing_1229 Date: Wed, 25 Aug 2021 08:57:49 +0800 Subject: [PATCH] fix CVE-2021-38604 (cherry picked from commit 2418652d62c193b291ca04e0fa0fd149c88e4ab1) --- ...-38604-0001-librt-add-test-bug-28213.patch | 146 ++++++++++++++++++ ...x-NULL-pointer-dereference-bug-28213.patch | 39 +++++ glibc.spec | 8 +- 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2021-38604-0001-librt-add-test-bug-28213.patch create mode 100644 backport-CVE-2021-38604-0002-librt-fix-NULL-pointer-dereference-bug-28213.patch diff --git a/backport-CVE-2021-38604-0001-librt-add-test-bug-28213.patch b/backport-CVE-2021-38604-0001-librt-add-test-bug-28213.patch new file mode 100644 index 0000000..c511b66 --- /dev/null +++ b/backport-CVE-2021-38604-0001-librt-add-test-bug-28213.patch @@ -0,0 +1,146 @@ +From 4cc79c217744743077bf7a0ec5e0a4318f1e6641 Mon Sep 17 00:00:00 2001 +From: Nikita Popov +Date: Thu, 12 Aug 2021 16:09:50 +0530 +Subject: [PATCH] librt: add test (bug 28213) + +This test implements following logic: +1) Create POSIX message queue. + Register a notification with mq_notify (using NULL attributes). + Then immediately unregister the notification with mq_notify. + Helper thread in a vulnerable version of glibc + should cause NULL pointer dereference after these steps. +2) Once again, register the same notification. + Try to send a dummy message. + Test is considered successfulif the dummy message + is successfully received by the callback function. + +Signed-off-by: Nikita Popov +Reviewed-by: Siddhesh Poyarekar +--- + rt/Makefile | 1 + + rt/tst-bz28213.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 102 insertions(+) + create mode 100644 rt/tst-bz28213.c + +diff --git a/rt/Makefile b/rt/Makefile +index 113cea03a5..910e775995 100644 +--- a/rt/Makefile ++++ b/rt/Makefile +@@ -74,6 +74,7 @@ tests := tst-shm tst-timer tst-timer2 \ + tst-aio7 tst-aio8 tst-aio9 tst-aio10 \ + tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \ + tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \ ++ tst-bz28213 \ + tst-timer3 tst-timer4 tst-timer5 \ + tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \ + tst-shm-cancel \ +diff --git a/rt/tst-bz28213.c b/rt/tst-bz28213.c +new file mode 100644 +index 0000000000..0c096b5a0a +--- /dev/null ++++ b/rt/tst-bz28213.c +@@ -0,0 +1,101 @@ ++/* Bug 28213: test for NULL pointer dereference in mq_notify. ++ Copyright (C) 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static mqd_t m = -1; ++static const char msg[] = "hello"; ++ ++static void ++check_bz28213_cb (union sigval sv) ++{ ++ char buf[sizeof (msg)]; ++ ++ (void) sv; ++ ++ TEST_VERIFY_EXIT ((size_t) mq_receive (m, buf, sizeof (buf), NULL) ++ == sizeof (buf)); ++ TEST_VERIFY_EXIT (memcmp (buf, msg, sizeof (buf)) == 0); ++ ++ exit (0); ++} ++ ++static void ++check_bz28213 (void) ++{ ++ struct sigevent sev; ++ ++ memset (&sev, '\0', sizeof (sev)); ++ sev.sigev_notify = SIGEV_THREAD; ++ sev.sigev_notify_function = check_bz28213_cb; ++ ++ /* Step 1: Register & unregister notifier. ++ Helper thread should receive NOTIFY_REMOVED notification. ++ In a vulnerable version of glibc, NULL pointer dereference follows. */ ++ TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0); ++ TEST_VERIFY_EXIT (mq_notify (m, NULL) == 0); ++ ++ /* Step 2: Once again, register notification. ++ Try to send one message. ++ Test is considered successful, if the callback does exit (0). */ ++ TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0); ++ TEST_VERIFY_EXIT (mq_send (m, msg, sizeof (msg), 1) == 0); ++ ++ /* Wait... */ ++ pause (); ++} ++ ++static int ++do_test (void) ++{ ++ static const char m_name[] = "/bz28213_queue"; ++ struct mq_attr m_attr; ++ ++ memset (&m_attr, '\0', sizeof (m_attr)); ++ m_attr.mq_maxmsg = 1; ++ m_attr.mq_msgsize = sizeof (msg); ++ ++ m = mq_open (m_name, ++ O_RDWR | O_CREAT | O_EXCL, ++ 0600, ++ &m_attr); ++ ++ if (m < 0) ++ { ++ if (errno == ENOSYS) ++ FAIL_UNSUPPORTED ("POSIX message queues are not implemented\n"); ++ FAIL_EXIT1 ("Failed to create POSIX message queue: %m\n"); ++ } ++ ++ TEST_VERIFY_EXIT (mq_unlink (m_name) == 0); ++ ++ check_bz28213 (); ++ ++ return 0; ++} ++ ++#include +-- +2.27.0 + diff --git a/backport-CVE-2021-38604-0002-librt-fix-NULL-pointer-dereference-bug-28213.patch b/backport-CVE-2021-38604-0002-librt-fix-NULL-pointer-dereference-bug-28213.patch new file mode 100644 index 0000000..3dca8cc --- /dev/null +++ b/backport-CVE-2021-38604-0002-librt-fix-NULL-pointer-dereference-bug-28213.patch @@ -0,0 +1,39 @@ +From b805aebd42364fe696e417808a700fdb9800c9e8 Mon Sep 17 00:00:00 2001 +From: Nikita Popov +Date: Mon, 9 Aug 2021 20:17:34 +0530 +Subject: [PATCH] librt: fix NULL pointer dereference (bug 28213) + +Helper thread frees copied attribute on NOTIFY_REMOVED message +received from the OS kernel. Unfortunately, it fails to check whether +copied attribute actually exists (data.attr != NULL). This worked +earlier because free() checks passed pointer before actually +attempting to release corresponding memory. But +__pthread_attr_destroy assumes pointer is not NULL. + +So passing NULL pointer to __pthread_attr_destroy will result in +segmentation fault. This scenario is possible if +notification->sigev_notify_attributes == NULL (which means default +thread attributes should be used). + +Signed-off-by: Nikita Popov +Reviewed-by: Siddhesh Poyarekar +--- + sysdeps/unix/sysv/linux/mq_notify.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c +index 9799dcdaa4..eccae2e4c6 100644 +--- a/sysdeps/unix/sysv/linux/mq_notify.c ++++ b/sysdeps/unix/sysv/linux/mq_notify.c +@@ -131,7 +131,7 @@ helper_thread (void *arg) + to wait until it is done with it. */ + (void) __pthread_barrier_wait (¬ify_barrier); + } +- else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED) ++ else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED && data.attr != NULL) + { + /* The only state we keep is the copy of the thread attributes. */ + __pthread_attr_destroy (data.attr); +-- +2.27.0 + diff --git a/glibc.spec b/glibc.spec index 6f0b863..3169c40 100644 --- a/glibc.spec +++ b/glibc.spec @@ -60,7 +60,7 @@ ############################################################################## Name: glibc Version: 2.34 -Release: 1 +Release: 2 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -76,6 +76,8 @@ Source7: replace_same_file_to_hard_link.py Patch0: glibc-1070416.patch Patch1: glibc-c-utf8-locale.patch +Patch2: backport-CVE-2021-38604-0001-librt-add-test-bug-28213.patch +Patch3: backport-CVE-2021-38604-0002-librt-fix-NULL-pointer-dereference-bug-28213.patch #Patch9000: turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch @@ -1163,6 +1165,10 @@ fi %doc hesiod/README.hesiod %changelog +* Wed Aug 25 2021 Qingqing Li - 2.34-2 +- fix CVE-2021-38604 + https://sourceware.org/bugzilla/show_bug.cgi?id=28213 + * Thu Aug 5 2021 Qingqing Li - 2.34-1 - upgrade to 2.34. -- Gitee