aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/htl
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2025-03-27 12:30:48 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2025-04-02 18:01:55 +0000
commitc8e73a1492b01b9b0c189d6a5c53a5a697827bae (patch)
tree50a812e61c87a41d6001a5de105ecd0fe8a7e90b /sysdeps/htl
parente8514ac7aaf1bd0cf791dbdac0b2584ef3c42e98 (diff)
downloadglibc-c8e73a1492b01b9b0c189d6a5c53a5a697827bae.tar.xz
glibc-c8e73a1492b01b9b0c189d6a5c53a5a697827bae.zip
stdlib: Fix qsort memory leak if callback throws (BZ 32058)
If the input buffer exceeds the stack auxiliary buffer, qsort will malloc a temporary one to call mergesort. Since C++ standard does allow the callback comparison function to throw [1], the glibc implementation can potentially leak memory. The fixes uses a pthread_cleanup_combined_push and pthread_cleanup_combined_pop, so it can work with and without exception enables. The qsort code path that calls malloc now requires some extra setup and a call to __pthread_cleanup_push anmd __pthread_cleanup_pop (which should be ok since they just setup some buffer state). Checked on x86_64-linux-gnu. [1] https://timsong-cpp.github.io/cppwp/n4950/alg.c.library#4 Reviewed-by: DJ Delorie <dj@redhat.com>
Diffstat (limited to 'sysdeps/htl')
-rw-r--r--sysdeps/htl/pthreadP.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
index 78ef4e7674..535deeb89f 100644
--- a/sysdeps/htl/pthreadP.h
+++ b/sysdeps/htl/pthreadP.h
@@ -23,6 +23,7 @@
#include <pthread.h>
#include <link.h>
+#include <bits/cancelation.h>
/* Attribute to indicate thread creation was issued from C11 thrd_create. */
#define ATTR_C11_THREAD ((void*)(uintptr_t)-1)
@@ -233,4 +234,18 @@ weak_extern (__pthread_exit)
_Static_assert (sizeof (type) == size, \
"sizeof (" #type ") != " #size)
+ /* Special cleanup macros which register cleanup both using
+ __pthread_cleanup_{push,pop} and using cleanup attribute. This is needed
+ for qsort, so that it supports both throwing exceptions from the caller
+ sort function callback (only cleanup attribute works there) and
+ cancellation of the thread running the callback if the callback or some
+ routines it calls don't have unwind information.
+ TODO: add support for cleanup routines. */
+#ifndef pthread_cleanup_combined_push
+# define pthread_cleanup_combined_push __pthread_cleanup_push
+#endif
+#ifndef pthread_cleanup_combined_pop
+# define pthread_cleanup_combined_pop __pthread_cleanup_pop
+#endif
+
#endif /* pthreadP.h */