Bug 406434 - valgrind is unable to intercept the malloc calls in statically linked executables
Summary: valgrind is unable to intercept the malloc calls in statically linked executa...
Status: CONFIRMED
Alias: None
Product: valgrind
Classification: Developer tools
Component: general (other bugs)
Version First Reported In: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-04-11 12:32 UTC by Alexandra Hajkova
Modified: 2019-04-13 07:56 UTC (History)
4 users (show)

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexandra Hajkova 2019-04-11 12:32:10 UTC
SUMMARY
valgrind is unable to intercept the malloc calls in statically linked executables which leads to 
Conditional jump or move depends on uninitialised value(s)
false positives

STEPS TO REPRODUCE
valgrind ldconfig --usage

OBSERVED RESULT
onditional jump or move depends on uninitialised value(s)
==8844==    at 0x12A6F4: _int_free (in /usr/sbin/ldconfig)
==8844==    by 0x19A1B9: _help (in /usr/sbin/ldconfig)
==8844==    by 0x19B047: argp_state_help (in /usr/sbin/ldconfig)
==8844==    by 0x168D78: argp_default_parser (in /usr/sbin/ldconfig)
==8844==    by 0x169FAC: argp_parse (in /usr/sbin/ldconfig)
==8844==    by 0x1115BE: main (in /usr/sbin/ldconfig)

An old dicussion about this issue: https://sourceforge.net/p/valgrind/mailman/message/23078945/

I noticed other statically linked programs with the similar issue:
sln
build-local-archive
busybox
Comment 1 Tom Hughes 2019-04-11 12:46:26 UTC
This is a fundamental, and I believe well documented, limitation.

Because valgrind relies on preloading a shared object to do function interception it can't work for a program that doesn't use the dynamic linker, and intercepting malloc calls (among other things) relies on the function interception system.
Comment 2 Mark Wielaard 2019-04-11 23:59:12 UTC
(In reply to Tom Hughes from comment #1)
> This is a fundamental, and I believe well documented, limitation.
> 
> Because valgrind relies on preloading a shared object to do function
> interception it can't work for a program that doesn't use the dynamic
> linker, and intercepting malloc calls (among other things) relies on the
> function interception system.

I don't believe that this is well documented.
It would at least be helpful if valgrind clearly warned about this.
For example if there is no PT_INTERP for the executable, but the wrapper does use LD_PRELOAD for a vgpreload library.

valgrind doesn't have to do normal ELF symbol interposition. It can intercept anything with a symbol name/address. The documentation of --soname-synonyms even implies that this would work for statically linked code/executables:

           ·   Replacements in a statically linked library are done by using
               the NONE pattern. For example, if you link with libtcmalloc.a,
               and only want to intercept the malloc related functions in the
               executable (and standard libraries) themselves, but not any
               other shared libraries, you can give the option
               --soname-synonyms=somalloc=NONE. Note that a NONE pattern will
               match the main executable and any shared library having no
               soname.

But this doesn't work in this case because even if it can see and find the malloc related functions in the executable the vgpreload libraries with the replacement/interception functions isn't loaded.

In theory we can get the replacements wired in differently like we do with add_hardwired_spec () for ld.so. But that would require some way to compile in the replacement functions into the tools themselves instead of relying on LD_PRELOAD.
Comment 3 Philippe Waroquiers 2019-04-13 07:56:36 UTC
(In reply to Mark Wielaard from comment #2)
> (In reply to Tom Hughes from comment #1)
> > This is a fundamental, and I believe well documented, limitation.
> > 
> > Because valgrind relies on preloading a shared object to do function
> > interception it can't work for a program that doesn't use the dynamic
> > linker, and intercepting malloc calls (among other things) relies on the
> > function interception system.
> 
> I don't believe that this is well documented.
> It would at least be helpful if valgrind clearly warned about this.
> For example if there is no PT_INTERP for the executable, but the wrapper
> does use LD_PRELOAD for a vgpreload library.
> 
> valgrind doesn't have to do normal ELF symbol interposition. It can
> intercept anything with a symbol name/address. The documentation of
> --soname-synonyms even implies that this would work for statically linked
> code/executables:
> 
>            ·   Replacements in a statically linked library are done by using
>                the NONE pattern. For example, if you link with libtcmalloc.a,
>                and only want to intercept the malloc related functions in the
>                executable (and standard libraries) themselves, but not any
>                other shared libraries, you can give the option
>                --soname-synonyms=somalloc=NONE. Note that a NONE pattern will
>                match the main executable and any shared library having no
>                soname.
> 
> But this doesn't work in this case because even if it can see and find the
> malloc related functions in the executable the vgpreload libraries with the
> replacement/interception functions isn't loaded.
> 
> In theory we can get the replacements wired in differently like we do with
> add_hardwired_spec () for ld.so. But that would require some way to compile
> in the replacement functions into the tools themselves instead of relying on
> LD_PRELOAD.

Some years ago, I looked at having replacement functions in the tool,
and not as LD_PRELOAD.  I think the (only?) (main?) reason why the replacement
functions are in a .so is that they must run in guest mode, and there is
some protection that forbids to run some 'valgrind tool' code in guest mode.
IIRC, if we could separate the 'pages' where we have the 'real valgrind'
code from the 'tool code that must run in client mode', we could have
the same protection but not depend on LD_PRELOAD.