@@ -33,6 +33,7 @@ tests := \
tst-interpose-nothread \
tst-interpose-thread \
tst-malloc \
+ tst-malloc-alternate-path \
tst-malloc-backtrace \
tst-malloc-check \
tst-malloc-fork-deadlock \
@@ -195,6 +196,7 @@ extra-libs-others = $(extra-libs)
extra-test-objs += \
tst-interpose-aux-nothread.o \
tst-interpose-aux-thread.o \
+ tst-mmap-obstruction-lib.so \
# extra-test-objs
test-extras = \
@@ -202,6 +204,9 @@ test-extras = \
tst-interpose-aux-thread \
# test-extras
+modules-names = \
+ tst-mmap-obstruction-lib
+
libmemusage-routines = memusage
libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
@@ -408,3 +413,7 @@ tst-mallocstate-malloc-check-ENV = LD_PRELOAD=$(objpfx)libc_malloc_debug.so
# libc_malloc_debug.so.
$(objpfx)tst-mallocstate: $(objpfx)libc_malloc_debug.so
$(objpfx)tst-mallocstate-malloc-check: $(objpfx)libc_malloc_debug.so
+
+
+$(objpfx)tst-malloc-alternate-path.out: $(objpfx)tst-mmap-obstruction-lib.so
+tst-malloc-alternate-path-ENV = LD_PRELOAD=$(objpfx)tst-mmap-obstruction-lib.so
new file mode 100755
GIT binary patch
literal 17000
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
D=p+U7
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,69 @@
+/* Test malloc that uses mmap when sbrk or brk fails.
+ This code returns success when there is an obstruction setup
+ and sbrk() fails to grow the heap size forcing malloc to use mmap().
+ 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/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#define LARGE_SIZE (10 * (1 << 20)) // 10 MB
+
+static int
+do_test (void)
+{
+ /* Get current program break */
+ void *current_brk = sbrk (0);
+
+ /* Try to extend the heap beyond the obstruction using sbrk */
+ int *ptr = (int *) sbrk (sizeof (int));
+ if (ptr != (void *) -1)
+ {
+ fprintf (stderr, "memory allocation can be done using sbrk.\n");
+ free (ptr);
+ return 1;
+ }
+
+ /* Attempt to allocate memory using malloc */
+ void *memptr = malloc (LARGE_SIZE);
+ if (memptr == NULL)
+ {
+ perror ("malloc");
+ return 1;
+ }
+
+ printf ("malloc used alternate path to allocate memory\n");
+
+ /* Get program break after malloc */
+ void *new_brk = sbrk (0);
+
+ /* Check if malloc changed program break */
+ if (current_brk != new_brk)
+ {
+ fprintf (stderr, "malloc changed program break\n");
+ free (memptr);
+ return 1;
+ }
+
+ free (memptr);
+ return 0;
+}
+
+#include <support/test-driver.c>
new file mode 100644
@@ -0,0 +1,74 @@
+/* Module used for creating a memory obstruction using mmap
+ Copyright (C) 2024 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; see the file COPYING.LIB. If
+ not, see <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libc-pointer-arith.h>
+
+static void *obstruction_addr = NULL;
+static long page_size;
+
+/* ELF constructor to set up the obstruction */
+static void obstruction_setup (void) __attribute__ ((constructor));
+
+/* ELF destructor to teardown the obstruction */
+static void obstruction_teardown (void) __attribute__ ((destructor));
+
+static void
+obstruction_setup (void)
+{
+ /* Get the runtime page size */
+ page_size = sysconf (_SC_PAGESIZE);
+
+ /* Get current program break */
+ void *current_brk = sbrk (0);
+
+ /* Round up to the next page boundary */
+ void *next_page_boundary = PTR_ALIGN_UP (current_brk, page_size);
+
+ /* Place a mapping using mmap at the next page boundary */
+ obstruction_addr
+ = mmap (next_page_boundary, page_size, PROT_WRITE | PROT_READ,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ if (obstruction_addr == MAP_FAILED)
+ {
+ perror ("mmap");
+ obstruction_addr = NULL;
+ }
+
+ if (obstruction_addr != next_page_boundary)
+ {
+ fprintf (stderr, "memory obstruction not setup correctly!");
+ }
+}
+
+/* Function to teardown the obstruction mapping */
+static void
+obstruction_teardown (void)
+{
+ /* Free the obstruction mapping */
+ if (obstruction_addr && munmap (obstruction_addr, page_size) == -1)
+ {
+ perror ("munmap");
+ }
+}
From: Sayan Paul <paul.sayan@gmail.com> The test aims to ensure that malloc uses the alternate path to allocate memory when sbrk() or brk() fails.To achieve this, tst-mmap-obstruction-lib creates an obstruction at the current program break, which when loaded using LD_PRELOAD ensures that sbrk() will fail to allocate any additional memory.However the test script:tst-malloc-alternate-path checks if malloc is still returning a valid ptr and we can theb infer that malloc() used mmap() instead of brk() or sbrk() to allocate the memory. --- malloc/Makefile | 9 ++++ malloc/tst-malloc-alternate-path | Bin 0 -> 17000 bytes malloc/tst-malloc-alternate-path.c | 69 +++++++++++++++++++++++++++ malloc/tst-mmap-obstruction-lib.c | 74 +++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100755 malloc/tst-malloc-alternate-path create mode 100644 malloc/tst-malloc-alternate-path.c create mode 100644 malloc/tst-mmap-obstruction-lib.c