Bug 28028 - malloc: tcache shutdown sequence does not work if the thread never allocated anything
Summary: malloc: tcache shutdown sequence does not work if the thread never allocated ...
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: malloc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: 2.34
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-06-30 07:53 UTC by Florian Weimer
Modified: 2021-07-02 15:56 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Florian Weimer 2021-06-30 07:53:24 UTC
Originally reported as bug 22111 comment 12:

Comment 12 JeffyChen 2020-10-10 07:23:03 UTC

Hi guys,

It seems this this issue is still exist in some cases, for example i can repro it with this test in glibc 2.29:

#include <pthread.h>
void *noop() { pthread_detach(pthread_self()); return NULL; }
void main() {
        pthread_t id;
        while(1) pthread_create(&id, NULL, noop, 0);
}

There's also another report at:
https://sourceware.org/ml/glibc-bugs/2018-01/msg00171.html

So it looks like the tcache_shutting_down is still not early enough, when we detach a thread with no tcache allocated(like the above test), the tcache_shutting_down would still be false:
static void
tcache_thread_shutdown (void)
{
  int i;
  tcache_perthread_struct *tcache_tmp = tcache;

  if (!tcache)
    return; <--- returned here

  /* Disable the tcache and prevent it from being reinitialized.  */
  tcache = NULL;
  tcache_shutting_down = true; <--- unreachable


And the tcache might be reinitialized later(breakpoint at later MAYBE_INIT_TCACHE):
Thread 2 (Thread 0x7f993c61e0 (LWP 8920)):
#0  0x0000007f9d444f7c in free () from /lib/libc.so.6
#1  0x0000007f9d57a3e4 in _dl_deallocate_tls () from /lib/ld-linux-aarch64.so.1
#2  0x0000007f9d541490 in free_stacks () from /lib/libpthread.so.0
#3  0x0000007f9d541a4c in __deallocate_stack () from /lib/libpthread.so.0
#4  0x0000007f9d542984 in start_thread () from /lib/libpthread.so.0
#5  0x0000007f9d49b1fc in thread_start () from /lib/libc.so.6



This works:
+++ b/malloc/malloc.c
@@ -2958,13 +2958,14 @@ tcache_thread_shutdown (void)
 {
   int i;
   tcache_perthread_struct *tcache_tmp = tcache;

+  tcache_shutting_down = true;

   if (!tcache)
     return;

   /* Disable the tcache and prevent it from being reinitialized.  */
   tcache = NULL;
-  tcache_shutting_down = true;
Comment 1 Florian Weimer 2021-07-02 15:56:19 UTC
Fixed for 2.34 via:

commit dfec225ee1972488bb48a8b67a2c4a13010c334a
Author: JeffyChen <jeffy.chen@rock-chips.com>
Date:   Fri Jul 2 17:39:24 2021 +0200

    malloc: Initiate tcache shutdown even without allocations [BZ #28028]
    
    After commit 1e26d35193efbb29239c710a4c46a64708643320 ("malloc: Fix
    tcache leak after thread destruction [BZ #22111]"),
    tcache_shutting_down is still not early enough.  When we detach a
    thread with no tcache allocated, tcache_shutting_down would still be
    false.
    
    Reviewed-by: DJ Delorie <dj@redhat.com>