[PATCH] msort: Get rid of alloca.
Joe Simmons-Talbott
josimmon@redhat.com
Fri Jun 30 17:26:36 GMT 2023
Use a scratch_buffer rather than alloca/malloc to avoid potential stack
overflow.
---
stdlib/msort.c | 94 +++++++++++++++++++++++---------------------------
1 file changed, 43 insertions(+), 51 deletions(-)
diff --git a/stdlib/msort.c b/stdlib/msort.c
index bbaa5e9f82..237dbb444f 100644
--- a/stdlib/msort.c
+++ b/stdlib/msort.c
@@ -24,6 +24,7 @@
#include <memcopy.h>
#include <errno.h>
#include <atomic.h>
+#include <scratch_buffer.h>
struct msort_param
{
@@ -164,71 +165,62 @@ void
__qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
{
size_t size = n * s;
- char *tmp = NULL;
struct msort_param p;
+ struct scratch_buffer buf;
+ scratch_buffer_init (&buf);
/* For large object sizes use indirect sorting. */
if (s > 32)
size = 2 * n * sizeof (void *) + s;
- if (size < 1024)
- /* The temporary array is small, so put it on the stack. */
- p.t = __alloca (size);
- else
- {
- /* We should avoid allocating too much memory since this might
- have to be backed up by swap space. */
- static long int phys_pages;
- static int pagesize;
+ /* We should avoid allocating too much memory since this might
+ have to be backed up by swap space. */
+ static long int phys_pages;
+ static int pagesize;
- if (pagesize == 0)
- {
- phys_pages = __sysconf (_SC_PHYS_PAGES);
+ if (pagesize == 0)
+ {
+ phys_pages = __sysconf (_SC_PHYS_PAGES);
- if (phys_pages == -1)
- /* Error while determining the memory size. So let's
- assume there is enough memory. Otherwise the
- implementer should provide a complete implementation of
- the `sysconf' function. */
- phys_pages = (long int) (~0ul >> 1);
+ if (phys_pages == -1)
+ /* Error while determining the memory size. So let's
+ assume there is enough memory. Otherwise the
+ implementer should provide a complete implementation of
+ the `sysconf' function. */
+ phys_pages = (long int) (~0ul >> 1);
- /* The following determines that we will never use more than
- a quarter of the physical memory. */
- phys_pages /= 4;
+ /* The following determines that we will never use more than
+ a quarter of the physical memory. */
+ phys_pages /= 4;
- /* Make sure phys_pages is written to memory. */
- atomic_write_barrier ();
+ /* Make sure phys_pages is written to memory. */
+ atomic_write_barrier ();
- pagesize = __sysconf (_SC_PAGESIZE);
- }
+ pagesize = __sysconf (_SC_PAGESIZE);
+ }
- /* Just a comment here. We cannot compute
- phys_pages * pagesize
- and compare the needed amount of memory against this value.
- The problem is that some systems might have more physical
- memory then can be represented with a `size_t' value (when
- measured in bytes. */
+ /* Just a comment here. We cannot compute
+ phys_pages * pagesize
+ and compare the needed amount of memory against this value.
+ The problem is that some systems might have more physical
+ memory then can be represented with a `size_t' value (when
+ measured in bytes. */
- /* If the memory requirements are too high don't allocate memory. */
- if (size / pagesize > (size_t) phys_pages)
- {
- _quicksort (b, n, s, cmp, arg);
- return;
- }
+ /* If the memory requirements are too high don't allocate memory. */
+ if (size / pagesize > (size_t) phys_pages)
+ {
+ _quicksort (b, n, s, cmp, arg);
+ return;
+ }
- /* It's somewhat large, so malloc it. */
- int save = errno;
- tmp = malloc (size);
- __set_errno (save);
- if (tmp == NULL)
- {
- /* Couldn't get space, so use the slower algorithm
- that doesn't need a temporary array. */
- _quicksort (b, n, s, cmp, arg);
- return;
- }
- p.t = tmp;
+ if (!scratch_buffer_set_array_size (&buf, 1, size))
+ {
+ /* Couldn't get space, so use the slower algorithm
+ that doesn't need a temporary array. */
+ _quicksort (b, n, s, cmp, arg);
+ return;
}
+ p.t = buf.data;
p.s = s;
p.var = 4;
@@ -295,7 +287,7 @@ __qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
}
msort_with_tmp (&p, b, n);
}
- free (tmp);
+ scratch_buffer_free (&buf);
}
libc_hidden_def (__qsort_r)
weak_alias (__qsort_r, qsort_r)
--
2.39.2
More information about the Libc-alpha
mailing list