diff options
| author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2025-03-27 12:30:48 -0300 |
|---|---|---|
| committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2025-04-02 18:01:55 +0000 |
| commit | c8e73a1492b01b9b0c189d6a5c53a5a697827bae (patch) | |
| tree | 50a812e61c87a41d6001a5de105ecd0fe8a7e90b /stdlib/Makefile | |
| parent | e8514ac7aaf1bd0cf791dbdac0b2584ef3c42e98 (diff) | |
| download | glibc-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 'stdlib/Makefile')
| -rw-r--r-- | stdlib/Makefile | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/stdlib/Makefile b/stdlib/Makefile index c9c8f702a2..513445bcbc 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -300,6 +300,8 @@ tests := \ tst-qsort2 \ tst-qsort3 \ tst-qsort6 \ + tst-qsort7 \ + tst-qsortx7 \ tst-quick_exit \ tst-rand-sequence \ tst-rand48 \ @@ -553,7 +555,19 @@ tests-special += $(objpfx)isomac.out ifeq ($(run-built-tests),yes) tests-special += $(objpfx)tst-fmtmsg.out -endif +ifeq ($(build-shared),yes) +ifneq ($(PERL),no) +generated += \ + tst-qsort7.mtrace \ + tst-qsortx7.mtrace \ + # generated +tests-special += \ + $(objpfx)tst-qsort7-mem.out \ + $(objpfx)tst-qsortx7-mem.out \ + # tests-special +endif # $(build-shared) == yes +endif # $(PERL) == yes +endif # $(run-built-tests) == yes include ../Rules @@ -647,3 +661,19 @@ $(objpfx)tst-getrandom2: $(shared-thread-library) $(objpfx)tst-getenv-signal: $(shared-thread-library) $(objpfx)tst-getenv-thread: $(shared-thread-library) $(objpfx)tst-getenv-unsetenv: $(shared-thread-library) + +CFLAGS-tst-qsort7.c += -fno-exceptions -fno-asynchronous-unwind-tables +LDLIBS-tst-qsort7 = $(shared-thread-library) +tst-qsort7-ENV = MALLOC_TRACE=$(objpfx)tst-qsort7.mtrace \ + LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so +$(objpfx)tst-qsort7-mem.out: $(objpfx)tst-qsort7.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-qsort7.mtrace > $@; \ + $(evaluate-test) + +CFLAGS-tst-qsortx7.c += -fexceptions +LDLIBS-tst-qsortx7 = $(shared-thread-library) +tst-qsortx7-ENV = MALLOC_TRACE=$(objpfx)tst-qsortx7.mtrace \ + LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so +$(objpfx)tst-qsortx7-mem.out: $(objpfx)tst-qsortx7.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-qsortx7.mtrace > $@; \ + $(evaluate-test) |
