public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] malloc:New test to check malloc alternate path using memory obstruction
@ 2024-05-21 15:10 sayan paul
  2024-05-22 14:44 ` Zack Weinberg
  0 siblings, 1 reply; 3+ messages in thread
From: sayan paul @ 2024-05-21 15:10 UTC (permalink / raw)
  To: libc-alpha, tools-patches; +Cc: sayan paul, zack

The test aims to ensure that malloc uses the alternate path to
allocate memory when sbrk() or brk() fails.To achieve this,
the test first creates an obstruction at current program break,
tests that obstruction with a failing sbrk(),then checks if malloc
is still returning a valid ptr thus inferring that malloc() used
mmap() instead of brk() or sbrk() to allocate the memory.
---
Changes as suggested by Zack:
* corrected email address
* simplified the approach by creating the obstruction in the test
* programme directly
---
 malloc/Makefile                    |   2 +
 malloc/tst-malloc-alternate-path.c | 100 +++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+)
 create mode 100644 malloc/tst-malloc-alternate-path.c

diff --git a/malloc/Makefile b/malloc/Makefile
index 77ba1a9109..ed666e2132 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -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 \
@@ -408,3 +409,4 @@ 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
+
diff --git a/malloc/tst-malloc-alternate-path.c b/malloc/tst-malloc-alternate-path.c
new file mode 100644
index 0000000000..fdb0ec5a7c
--- /dev/null
+++ b/malloc/tst-malloc-alternate-path.c
@@ -0,0 +1,100 @@
+/* Test that malloc 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 <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libc-pointer-arith.h>
+
+#define LARGE_SIZE (10 * (1 << 20)) // 10 MB
+static long page_size;
+
+static int
+do_test (void)
+{
+  /* Get current program break */
+  void *current_brk = sbrk (0);
+
+  /* Get the runtime page size */
+  page_size = sysconf (_SC_PAGESIZE);
+
+  /* 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 */
+  void *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");
+      return 1;
+    }
+
+  if (obstruction_addr != next_page_boundary)
+    {
+      fprintf (stderr, "memory obstruction not setup correctly!");
+      return 1;
+    }
+
+  /* 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);
+
+  /* Free the obstruction mapping */
+  if (munmap (obstruction_addr, page_size) == -1)
+    {
+      perror ("munmap");
+    }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.45.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-05-22 22:04 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-21 15:10 [PATCH v2] malloc:New test to check malloc alternate path using memory obstruction sayan paul
2024-05-22 14:44 ` Zack Weinberg
2024-05-22 22:04   ` Arjun Shankar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).