On Wed, 7 Aug 2024 11:16:04 +0200 Vincent Lefevre <vinc...@vinc17.net> wrote:
Package: libc6
Version: 2.39-6
Severity: normal

The following program

#include <mcheck.h>
#include <stdio.h>

int main (void)
{
  int r;

  r = mcheck (NULL);
  printf ("%d\n", r);
  return 0;
}

outputs -1, which is incorrect. It should have been 0.

The glibc manual says

  It is too late to begin allocation checking once you have allocated
  anything with ‘malloc’.  So ‘mcheck’ does nothing in that case.
  The function returns ‘-1’ if you call it too late, and ‘0’
  otherwise (when it is successful).

Since there hasn't been any malloc yet, 0 should have been output.

Similarly, the example given in the mcheck(3) man page fails
unexpectedly.




Hello,
I did a series [1] of tests and found this seems to worked last in Buster.

With Bullseye it fails because there is a malloc before main is reached,
somewhere inside the dynamic loader [2].
Maybe this would work with a static build.

In Bookworm and Trixie [3] the function mcheck always returns -1,
because "IS_IN (libc)" seems to be true at compile time.

Reading the upstream commit comment [4] it looks like mcheck should
just work when using libc_malloc_debug.so.

And indeed following also prints 0 in Trixie:
  LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libc_malloc_debug.so.0 ./mcheck-test

Kind regards,
Bernhard



[1]
glibc-2.28: prints 0    (10 Buster/oldoldstable)
glibc-2.31: prints -1   (11 Bullseye/oldstable)
glibc-2.36: prints -1   (12 Bookworm/stable)
glibc-2.40: prints -1   (13 Trixie/testing)




[2] Bullseye: malloc before main is reached.
(rr) bt
#0  ptmalloc_init () at arena.c:400
#1  0x00007f63d8948101 in ptmalloc_init () at arena.c:291
#2  malloc_hook_ini (sz=32, caller=<optimized out>) at hooks.c:31
#3  0x00007f63d8948d5a in __libc_calloc (n=<optimized out>, elem_size=<optimized 
out>) at malloc.c:3387
#4  0x00007f63d88bdb18 in _dlerror_run (operate=operate@entry=0x7f63d88bd3a0 
<dlsym_doit>, args=args@entry=0x7ffd28cf5d10) at dlerror.c:148
#5  0x00007f63d88bd41c in __dlsym (handle=<optimized out>, name=<optimized 
out>) at dlsym.c:70
#6  0x00007f63d8a9e1c6 in init_process () at ./src/preload/syscallbuf.c:778
#7  0x00007f63d8ac0fe2 in call_init (l=<optimized out>, argc=argc@entry=1, 
argv=argv@entry=0x7ffd28cf5fc8, env=env@entry=0x7ffd28cf5fd8) at dl-init.c:72
#8  0x00007f63d8ac10e9 in call_init (env=0x7ffd28cf5fd8, argv=0x7ffd28cf5fc8, argc=1, 
l=<optimized out>) at dl-init.c:30
#9  _dl_init (main_map=0x7f63d8add180, argc=1, argv=0x7ffd28cf5fc8, 
env=0x7ffd28cf5fd8) at dl-init.c:119
#10 0x00007f63d8ab20ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#11 0x0000000000000001 in ?? ()



[3] Bookworm, Trixie:
(rr) list
32
33      int
34      mcheck (void (*func) (enum mcheck_status))
35      {
36      #if IS_IN (libc)
37        return -1;
38      #else
39        return __mcheck_initialize (func, false);
40      #endif
41      }
(rr) disassemble mcheck
Dump of assembler code for function mcheck:
=> 0x00007f290d5bd290 <+0>:     mov    $0xffffffff,%eax
   0x00007f290d5bd295 <+5>:     ret
End of assembler dump.



[4] 
https://sourceware.org/git/?p=glibc.git;a=commit;f=malloc/mcheck.c;h=c142eb253f3814f46527e9b37484041dd85702cf

Reply via email to