assert: Improve POSIX conformance of allocation failure path (RHEL-65359)
Resolves: RHEL-65359
This commit is contained in:
parent
919ea1fa70
commit
595519af87
54
glibc-RHEL-65359-1.patch
Normal file
54
glibc-RHEL-65359-1.patch
Normal file
@ -0,0 +1,54 @@
|
||||
commit ebd928224a138d4560dc0be3ef162162d62a9e43
|
||||
Author: Carlos O'Donell <carlos@redhat.com>
|
||||
Date: Thu May 18 12:56:45 2023 -0400
|
||||
|
||||
assert: Reformat Makefile.
|
||||
|
||||
Reflow all long lines adding comment terminators.
|
||||
Sort all reflowed text using scripts/sort-makefile-lines.py.
|
||||
|
||||
No code generation changes observed in binary artifacts.
|
||||
No regressions on x86_64 and i686.
|
||||
|
||||
diff --git a/assert/Makefile b/assert/Makefile
|
||||
index 2bc9e2214e3e9a8b..24a9bdb96306ca08 100644
|
||||
--- a/assert/Makefile
|
||||
+++ b/assert/Makefile
|
||||
@@ -22,7 +22,9 @@ subdir := assert
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
-headers := assert.h
|
||||
+headers := \
|
||||
+ assert.h
|
||||
+ # headers
|
||||
|
||||
routines := \
|
||||
__assert \
|
||||
@@ -30,7 +32,13 @@ routines := \
|
||||
assert \
|
||||
assert-perr \
|
||||
# routines
|
||||
-tests := test-assert test-assert-perr tst-assert-c++ tst-assert-g++
|
||||
+
|
||||
+tests := \
|
||||
+ test-assert \
|
||||
+ test-assert-perr \
|
||||
+ tst-assert-c++ \
|
||||
+ tst-assert-g++ \
|
||||
+ # tests
|
||||
|
||||
ifeq ($(have-cxx-thread_local),yes)
|
||||
CFLAGS-tst-assert-c++.o = -std=c++11
|
||||
@@ -38,7 +46,10 @@ LDLIBS-tst-assert-c++ = -lstdc++
|
||||
CFLAGS-tst-assert-g++.o = -std=gnu++11
|
||||
LDLIBS-tst-assert-g++ = -lstdc++
|
||||
else
|
||||
-tests-unsupported += tst-assert-c++ tst-assert-g++
|
||||
+tests-unsupported += \
|
||||
+ tst-assert-c++ \
|
||||
+ tst-assert-g++ \
|
||||
+ # tests-unsupported
|
||||
endif
|
||||
|
||||
include ../Rules
|
255
glibc-RHEL-65359-2.patch
Normal file
255
glibc-RHEL-65359-2.patch
Normal file
@ -0,0 +1,255 @@
|
||||
commit e79e5c4899e82eff1032b1f8e530234c8fcbd8b9
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Thu Nov 14 15:12:57 2024 -0500
|
||||
|
||||
assert: ensure posix compliance, add tests for such
|
||||
|
||||
Fix assert.c so that even the fallback
|
||||
case conforms to POSIX, although not exactly the same as
|
||||
the default case so a test can tell the difference.
|
||||
|
||||
Add a test that verifies that abort is called, and that the
|
||||
message printed to stderr has all the info that POSIX requires.
|
||||
Verify this even when malloc isn't usable.
|
||||
|
||||
Reviewed-by: Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Conflicts:
|
||||
assert/assert.c
|
||||
(no <setvmaname.h> downstream)
|
||||
|
||||
diff --git a/assert/Makefile b/assert/Makefile
|
||||
index 24a9bdb96306ca08..85358fad51367b49 100644
|
||||
--- a/assert/Makefile
|
||||
+++ b/assert/Makefile
|
||||
@@ -38,6 +38,7 @@ tests := \
|
||||
test-assert-perr \
|
||||
tst-assert-c++ \
|
||||
tst-assert-g++ \
|
||||
+ test-assert-2 \
|
||||
# tests
|
||||
|
||||
ifeq ($(have-cxx-thread_local),yes)
|
||||
diff --git a/assert/assert.c b/assert/assert.c
|
||||
index 989126c7e5b6b265..6002cc953cdb2d39 100644
|
||||
--- a/assert/assert.c
|
||||
+++ b/assert/assert.c
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <sysdep.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
+#include <sys/uio.h>
|
||||
+#include <intprops.h>
|
||||
|
||||
|
||||
extern const char *__progname;
|
||||
@@ -85,8 +87,35 @@ __assert_fail_base (const char *fmt, const char *assertion, const char *file,
|
||||
else
|
||||
{
|
||||
/* At least print a minimal message. */
|
||||
- static const char errstr[] = "Unexpected error.\n";
|
||||
- __libc_write (STDERR_FILENO, errstr, sizeof (errstr) - 1);
|
||||
+ char linebuf[INT_STRLEN_BOUND (int) + sizeof ":: "];
|
||||
+ struct iovec v[9];
|
||||
+ int i = 0;
|
||||
+
|
||||
+#define WS(s) (v[i].iov_len = strlen (v[i].iov_base = (void *) (s)), i++)
|
||||
+
|
||||
+ if (__progname)
|
||||
+ {
|
||||
+ WS (__progname);
|
||||
+ WS (": ");
|
||||
+ }
|
||||
+
|
||||
+ WS (file);
|
||||
+ v[i++] = (struct iovec) {.iov_base = linebuf,
|
||||
+ .iov_len = sprintf (linebuf, ":%d: ", line)};
|
||||
+
|
||||
+ if (function)
|
||||
+ {
|
||||
+ WS (function);
|
||||
+ WS (": ");
|
||||
+ }
|
||||
+
|
||||
+ WS ("Assertion `");
|
||||
+ WS (assertion);
|
||||
+ /* We omit the '.' here so that the assert tests can tell when
|
||||
+ this code path is taken. */
|
||||
+ WS ("' failed\n");
|
||||
+
|
||||
+ (void) writev (STDERR_FILENO, v, i);
|
||||
}
|
||||
|
||||
abort ();
|
||||
diff --git a/assert/test-assert-2.c b/assert/test-assert-2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..99f8f683e87a0c64
|
||||
--- /dev/null
|
||||
+++ b/assert/test-assert-2.c
|
||||
@@ -0,0 +1,166 @@
|
||||
+/* Test assert's compliance with POSIX requirements.
|
||||
+ Copyright (C) 2024 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/>. */
|
||||
+
|
||||
+/* This test verifies that a failed assertion acts in accordance with
|
||||
+ the POSIX requirements, despite any internal failures. We do so by
|
||||
+ calling test routines via fork() and monitoring their exit codes
|
||||
+ and stderr, while possibly forcing internal functions (malloc) to
|
||||
+ fail. */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <dlfcn.h>
|
||||
+#include <string.h>
|
||||
+#include <signal.h>
|
||||
+
|
||||
+#undef NDEBUG
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/capture_subprocess.h>
|
||||
+#include <support/xstdio.h>
|
||||
+
|
||||
+/* We need to be able to make malloc() "fail" so that __asprintf
|
||||
+ fails. */
|
||||
+
|
||||
+void * (*next_malloc)(size_t sz) = 0;
|
||||
+static volatile bool fail_malloc = 0;
|
||||
+
|
||||
+void *
|
||||
+malloc (size_t sz)
|
||||
+{
|
||||
+ if (fail_malloc)
|
||||
+ return NULL;
|
||||
+ if (next_malloc == 0)
|
||||
+ next_malloc = dlsym (RTLD_NEXT, "malloc");
|
||||
+ if (next_malloc == 0)
|
||||
+ return NULL;
|
||||
+ return next_malloc (sz);
|
||||
+}
|
||||
+
|
||||
+/* We can tell if abort() is called by looking for the custom return
|
||||
+ value. */
|
||||
+
|
||||
+void
|
||||
+abort_handler(int s)
|
||||
+{
|
||||
+ _exit(5);
|
||||
+}
|
||||
+
|
||||
+static int do_lineno;
|
||||
+static const char *do_funcname;
|
||||
+
|
||||
+/* Hack to get the line of the assert. */
|
||||
+#define GET_INFO_1(l) \
|
||||
+ if (closure != NULL) \
|
||||
+ { \
|
||||
+ do_lineno = l; \
|
||||
+ do_funcname = __func__; \
|
||||
+ return; \
|
||||
+ }
|
||||
+#define GET_INFO() GET_INFO_1(__LINE__+1)
|
||||
+
|
||||
+/* These are the two test cases. */
|
||||
+
|
||||
+static void
|
||||
+test_assert_normal (void *closure)
|
||||
+{
|
||||
+ if (closure == NULL)
|
||||
+ signal (SIGABRT, abort_handler);
|
||||
+
|
||||
+ GET_INFO ();
|
||||
+ assert (1 == 2);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
+test_assert_nomalloc (void *closure)
|
||||
+{
|
||||
+ if (closure == NULL)
|
||||
+ {
|
||||
+ signal (SIGABRT, abort_handler);
|
||||
+ fail_malloc = 1;
|
||||
+ }
|
||||
+
|
||||
+ GET_INFO ();
|
||||
+ assert (1 == 2);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+check_posix (const char *buf, int rv, int line,
|
||||
+ const char *funcname, const char *testarg)
|
||||
+{
|
||||
+ /* POSIX requires that a failed assertion write a diagnostic to
|
||||
+ stderr and call abort. The diagnostic must include the filename,
|
||||
+ line number, and function where the assertion failed, along with
|
||||
+ the text of the assert() argument.
|
||||
+ */
|
||||
+ char linestr[100];
|
||||
+
|
||||
+ sprintf (linestr, "%d", line);
|
||||
+
|
||||
+ /* If abort is called, our handler will return 5. */
|
||||
+ TEST_VERIFY (rv == 5);
|
||||
+
|
||||
+ TEST_VERIFY (strstr (buf, __FILE__) != NULL);
|
||||
+ TEST_VERIFY (strstr (buf, linestr) != NULL);
|
||||
+ TEST_VERIFY (strstr (buf, funcname) != NULL);
|
||||
+ TEST_VERIFY (strstr (buf, testarg) != NULL);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+one_test (void (*func)(void *), int which_path)
|
||||
+{
|
||||
+ struct support_capture_subprocess sp;
|
||||
+ int rv;
|
||||
+
|
||||
+ func (&do_lineno);
|
||||
+ printf("running test for %s, line %d\n", do_funcname, do_lineno);
|
||||
+
|
||||
+ sp = support_capture_subprocess (func, NULL);
|
||||
+ rv = WEXITSTATUS (sp.status);
|
||||
+
|
||||
+ check_posix (sp.err.buffer, rv, do_lineno, do_funcname, "1 == 2");
|
||||
+
|
||||
+ /* Look for intentional subtle differences in messages to verify
|
||||
+ that the intended code path was taken. */
|
||||
+ switch (which_path)
|
||||
+ {
|
||||
+ case 0:
|
||||
+ TEST_VERIFY (strstr (sp.err.buffer, "failed.\n") != NULL);
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ TEST_VERIFY (strstr (sp.err.buffer, "failed\n") != NULL);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ support_capture_subprocess_free (&sp);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test(void)
|
||||
+{
|
||||
+ one_test (test_assert_normal, 0);
|
||||
+ one_test (test_assert_nomalloc, 1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
23
glibc-RHEL-65359-3.patch
Normal file
23
glibc-RHEL-65359-3.patch
Normal file
@ -0,0 +1,23 @@
|
||||
commit 3fb895ac88e99201573352b1abc18db4340ecede
|
||||
Author: DJ Delorie <dj@redhat.com>
|
||||
Date: Sat Dec 21 23:12:41 2024 -0500
|
||||
|
||||
assert: Use __writev in assert.c [BZ #32492]
|
||||
|
||||
Replace writev with __writev in assert/assert.c. This fixes [BZ #32492].
|
||||
|
||||
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
diff --git a/assert/assert.c b/assert/assert.c
|
||||
index 6002cc953cdb2d39..1e9683cf0707b0d3 100644
|
||||
--- a/assert/assert.c
|
||||
+++ b/assert/assert.c
|
||||
@@ -115,7 +115,7 @@ __assert_fail_base (const char *fmt, const char *assertion, const char *file,
|
||||
this code path is taken. */
|
||||
WS ("' failed\n");
|
||||
|
||||
- (void) writev (STDERR_FILENO, v, i);
|
||||
+ (void) __writev (STDERR_FILENO, v, i);
|
||||
}
|
||||
|
||||
abort ();
|
20
glibc-RHEL-65359-4.patch
Normal file
20
glibc-RHEL-65359-4.patch
Normal file
@ -0,0 +1,20 @@
|
||||
commit fd30525eadff6a4b2ac9478bdd6490d0c9c116d9
|
||||
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
|
||||
Date: Sun Dec 22 23:33:27 2024 +0100
|
||||
|
||||
assert/test-assert-2.c: Include <unistd.h>
|
||||
|
||||
For _exit declaration.
|
||||
|
||||
diff --git a/assert/test-assert-2.c b/assert/test-assert-2.c
|
||||
index 99f8f683e87a0c64..3288609ab28701ed 100644
|
||||
--- a/assert/test-assert-2.c
|
||||
+++ b/assert/test-assert-2.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
@ -157,7 +157,7 @@ end \
|
||||
Summary: The GNU libc libraries
|
||||
Name: glibc
|
||||
Version: %{glibcversion}
|
||||
Release: 155%{?dist}
|
||||
Release: 156%{?dist}
|
||||
|
||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||
# libraries.
|
||||
@ -1081,6 +1081,10 @@ Patch773: glibc-RHEL-61559-2.patch
|
||||
Patch774: glibc-RHEL-61559-3.patch
|
||||
Patch775: glibc-RHEL-61559-4.patch
|
||||
Patch776: glibc-RHEL-50550.patch
|
||||
Patch777: glibc-RHEL-65359-1.patch
|
||||
Patch778: glibc-RHEL-65359-2.patch
|
||||
Patch779: glibc-RHEL-65359-3.patch
|
||||
Patch780: glibc-RHEL-65359-4.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -3074,6 +3078,9 @@ update_gconv_modules_cache ()
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Jan 23 2025 Florian Weimer <fweimer@redhat.com> - 2.34-156
|
||||
- Additional test for assert (RHEL-65359)
|
||||
|
||||
* Thu Jan 23 2025 Florian Weimer <fweimer@redhat.com> - 2.34-155
|
||||
- Change utimensat to accept NULL pathname arguments (RHEL-50550)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user