Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bug#1050208: libc6: double free detected in tcache 2, then abort

53 views
Skip to first unread message

Paul Szabo

unread,
Aug 22, 2023, 1:00:05 AM8/22/23
to
Package: libc6
Version: 2.36-9+deb12u1
Severity: important

Dear Maintainer,

I noticed an issue with malloc() or free(). I only noticed this
recently, with libc6 version 2.36-9+deb12u1; reverting to previous
2.36-9 did not seem to help.

The issue: sending SIGHUP to the inetd process (from package
openbsd-inetd version 0.20221205-1) should cause it to re-load its
configuration, but instead it elicits

free(): double free detected in tcache 2

and an abort. This is easiest seen (after "systemctl stop inetd") with

root# inetd -d -i & sleep 1; kill -HUP $!; sleep 1; jobs
[1] 2431
ADD: ident proto=tcp4, wait.max=1.256 user:group=identd:(default) builtin=0 server=/usr/sbin/identd
free(): double free detected in tcache 2
[1]+ Aborted inetd -d -i
root#

I believe that this "double free" is spurious, as there are no errors
(but inetd reloads as expected) when using e.g.

root# LD_PRELOAD=libc_malloc_debug.so MALLOC_CHECK_=1 inetd -d -i & sleep 1; kill -HUP $!; sleep 1; jobs; kill $!; sleep 1; jobs
[1] 2437
ADD: ident proto=tcp4, wait.max=1.256 user:group=identd:(default) builtin=0 server=/usr/sbin/identd
REDO: ident proto=tcp4, wait.max=1.256 user:group=identd:(default) builtin=0 server=/usr/sbin/identd
[1]+ Running LD_PRELOAD=libc_malloc_debug.so MALLOC_CHECK_=0 inetd -d -i &
[1]+ Done LD_PRELOAD=libc_malloc_debug.so MALLOC_CHECK_=0 inetd -d -i
root#

No errors are shown with any value of MALLOC_CHECK_ from 0 to 20, or
even without any MALLOC_CHECK_ but with just LD_PRELOAD so with

root# LD_PRELOAD=libc_malloc_debug.so inetd -d -i & sleep 1; kill -HUP $!; sleep 1; jobs; kill $!; sleep 1; jobs

Instead of LD_PRELOAD, some glibc tunables can also help to avoid the
"double free" error. The settings that I found to help were:

GLIBC_TUNABLES=glibc.malloc.tcache_count=0
GLIBC_TUNABLES=glibc.malloc.tcache_count=1

whereas none of the following helped:

GLIBC_TUNABLES=glibc.malloc.tcache_count=2 # or 3, 4, ...
GLIBC_TUNABLES=glibc.cpu.hwcaps=-avx
GLIBC_TUNABLES=glibc.cpu.hwcaps=-sse
GLIBC_TUNABLES=glibc.cpu.hwcap_mask=1099511627775

The issue is present on all of my machines that boot from "disk", with
amd64 or i386 architectures (both using an amd64 kernel, custom-built
from linux-source version 6.1.38-4); some of these are VMs inside
VirtualBox. I hope that the issue can be reproduced elsewhere.
Curiously, the issue does not seem present on same machines when booting
PXE and then NFS-mounted root (similar to LTSP), though the contents of
/usr/lib seem identical whether booting from disk or PXE; the PXE boot
sequence uses sysvinit, not systemd.

Thanks Aurelien for suggesting the glibc tunables (in bug #1041836).
Did not try gdb since I am not proficient with it, would not know what
to look for. Please suggest anything else I should try.

Thanks, Paul
--
Paul Szabo p...@maths.usyd.edu.au www.maths.usyd.edu.au/u/psz
School of Mathematics and Statistics University of Sydney Australia



-- System Information:
Debian Release: 12.1
APT prefers stable-security
APT policy: (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 6.1+pk12.06 (SMP w/12 CPU threads; PREEMPT)
Locale: LANG=C.UTF-8, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages libc6 depends on:
ii libgcc-s1 12.2.0-14

Versions of packages libc6 recommends:
ii libidn2-0 2.3.3-1+b1

Versions of packages libc6 suggests:
ii debconf [debconf-2.0] 1.5.82
ii glibc-doc 2.36-9+deb12u1
ii libc-l10n 2.36-9+deb12u1
ii libnss-nis 3.1-4
ii libnss-nisplus 1.3-4
ii locales 2.36-9+deb12u1

-- debconf information:
glibc/restart-failed:
* glibc/upgrade: true
glibc/kernel-not-supported:
glibc/disable-screensaver:
* libraries/restart-without-asking: true
glibc/kernel-too-old:
glibc/restart-services:

Aurelien Jarno

unread,
Aug 22, 2023, 11:10:04 AM8/22/23
to
control: reassign -1 openbsd-inetd
control: retitle -1 openbsd-inetd: double free detected in tcache 2, then abort
control: found -1 openbsd-inetd/0.20221205-1

Hi,

On 2023-08-22 14:32, Paul Szabo wrote:
> Package: libc6
> Version: 2.36-9+deb12u1
> Severity: important
>
> Dear Maintainer,
>
> I noticed an issue with malloc() or free(). I only noticed this
> recently, with libc6 version 2.36-9+deb12u1; reverting to previous
> 2.36-9 did not seem to help.
>
> The issue: sending SIGHUP to the inetd process (from package
> openbsd-inetd version 0.20221205-1) should cause it to re-load its
> configuration, but instead it elicits
>
> free(): double free detected in tcache 2
>
> and an abort. This is easiest seen (after "systemctl stop inetd") with
>
> root# inetd -d -i & sleep 1; kill -HUP $!; sleep 1; jobs
> [1] 2431
> ADD: ident proto=tcp4, wait.max=1.256 user:group=identd:(default) builtin=0 server=/usr/sbin/identd
> free(): double free detected in tcache 2
> [1]+ Aborted inetd -d -i
> root#
>
> I believe that this "double free" is spurious, as there are no errors
> (but inetd reloads as expected) when using e.g.

It is not, it is also reported by valgrind:

==9356== Invalid free() / delete / delete[] / realloc()
==9356== at 0x484317B: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9356== by 0x10DB69: getconfigent (inetd.c:1176)
==9356== by 0x10EFFE: config (inetd.c:651)
==9356== by 0x48A0401: event_signal_closure (event.c:1369)
==9356== by 0x48A0401: event_process_active_single_queue (event.c:1678)
==9356== by 0x48A0C1E: event_process_active (event.c:1783)
==9356== by 0x48A0C1E: event_base_loop (event.c:2006)
==9356== by 0x10B9E2: main (inetd.c:475)
==9356== Address 0x50747e0 is 0 bytes inside a block of size 1 free'd
==9356== at 0x484317B: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9356== by 0x10DB69: getconfigent (inetd.c:1176)
==9356== by 0x10EFFE: config (inetd.c:651)
==9356== by 0x10B8C3: main (inetd.c:438)
==9356== Block was alloc'd at
==9356== at 0x48407B4: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9356== by 0x4A82539: strdup (strdup.c:42)
==9356== by 0x10DBE7: newstr (inetd.c:1597)
==9356== by 0x10DBE7: getconfigent (inetd.c:1186)
==9356== by 0x10EFFE: config (inetd.c:651)
==9356== by 0x10B8C3: main (inetd.c:438)

It appears that is has been introduced in the latest upload of
openbsd-inetd in the default_v4v6 patch. The following patch seems to
fix the issue, but I haven't spent time to verify it is correct:

--- openbsd-inetd-0.20221205.orig/inetd.c
+++ openbsd-inetd-0.20221205/inetd.c
@@ -1172,8 +1172,10 @@ more:
cp = saved_cp;
saved_cp = NULL;
} else {
- if (saved_cp)
+ if (saved_cp) {
free(saved_cp);
+ saved_cp = NULL;
+ }

while ((cp = nextline(fconfig)) && *cp == '#')
;

I am therefore reassigning the bug to openbsd-inetd.

Regards
Aurelien

--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aure...@aurel32.net http://aurel32.net

Marco d'Itri

unread,
Aug 23, 2023, 9:10:05 AM8/23/23
to
In one or two weeks I will also do a stable upload.

--
ciao,
Marco
signature.asc
0 new messages