Problems with LD_PRELOAD and calloc() interposition for certain executables

Relating to a previous question of mine

I’ve successfully interposed malloc, but calloc seems to be more problematic.

That is with certain hosts, calloc gets stuck in an infinite loop with a possible internal calloc call inside dlsym. However, a basic test host does not exhibit this behaviour, but my system’s “ls” command does.

Here’s my code:

// build with: g++ -O2 -Wall -fPIC -ldl -o libnano.so -shared Main.cc
#include <stdio.h>
#include <dlfcn.h>

bool gNanoUp = false;// global

// Function types
typedef void* (*MallocFn)(size_t size);
typedef void* (*CallocFn)(size_t elements, size_t size);

struct MemoryFunctions {
    MallocFn   mMalloc;
    CallocFn   mCalloc;
};

MemoryFunctions orgMemFuncs;

// Save original methods.
void __attribute__((constructor)) __nano_init(void) {
    fprintf(stderr, "NANO: init()/n");

    // Get address of original functions
    orgMemFuncs.mMalloc = (MallocFn)dlsym(RTLD_NEXT, "malloc");
    orgMemFuncs.mCalloc = (CallocFn)dlsym(RTLD_NEXT, "calloc");

    fprintf(stderr, "NANO: malloc() found @%p/n", orgMemFuncs.mMalloc);
    fprintf(stderr, "NANO: calloc() found @%p/n", orgMemFuncs.mCalloc);

    gNanoUp = true;
}

// replacement functions
extern "C" {
    void *malloc(size_t size) {
        if (!gNanoUp) __nano_init();
        return orgMemFuncs.mMalloc(size);
    }

    void* calloc(size_t elements, size_t size) {
        if (!gNanoUp) __nano_init();
        return orgMemFuncs.mCalloc(elements, size);
    }
}

Now, When I do the following, I get an infinite loop followed by a seg fault, eg:

% setenv LD_PRELOAD "./libnano.so"
% ls
...
NANO: init()
NANO: init()
NANO: init()
Segmentation fault (core dumped)

However if I comment out the calloc interposer, it almost seems to work:

% setenv LD_PRELOAD "./libnano.so"
% ls
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
<directory contents>
...

So somethings up with “ls” that means init() gets called twice.

EDIT Note that the following host program works correctly – init() is only called once, and calloc is successfully interposed, as you can see from the output.

// build with: g++ test.cc -o test
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {

    void* p = malloc(123);
    printf("HOST p=%p/n", p);
    free(p);

    char* c = new char;
    printf("HOST c=%p/n", c);
    delete c;

    void* ca = calloc(10,10);
    printf("HOST ca=%p/n", ca);
    free(ca);
}

% setenv LD_PRELOAD "./libnano.so"
% ./test 
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
HOST p=0x601010
HOST c=0x601010
HOST ca=0x601030

I have problems making a function to handle a matrix using calloc

I want to dynamicly construct a matrix in C from a text document using a function. I ran into problems when making the matrix using calloc and probably when giving the values to the matrice elements,

library interposition with dlsym

I’m writing an interposition library to track the usage of some library functions in libc, such as open(), close(), connect(), etc. It works generally well on most of the applications. However, when I

Why calloc wasn’t intended to assign arbitrary values?

As per why malloc+memset slower than calloc? malloc+memset is slower than calloc under certain conditions. Why wasn’t calloc written in such a way that it can take an extra value argument ( like mems

Function interposition only working for malloc not free

I’ve come across a small problem while monitoring malloc and free trough the use of function interposition. When performing the function interposition for just malloc, it works as exepcted. However,

Function interposition in Linux without dlsym

I’m currently working on a project where I need to track the usage of several system calls and low-level functions like mmap, brk, sbrk. So far, I’ve been doing this using function interposition: I wr

kprobe vs uprobe system call interposition

I want to write a system call interposition by using Utrace. I understood that Utrace project has been abandoned, but part of its code is used on kprobe and uprobe. I haven’t understood really well h

Two arguments to calloc

Why does calloc take two arguments instead of one like malloc? Specifically, since there is no difference between (or is there?) between the following expressions: calloc (a, b); calloc (b, a); calloc

Convert malloc() to calloc()

I would like to convert malloc() to calloc(). I am confused about using calloc() in this example because it takes 2 arguments while malloc() only one. So it’s correct with mine: (byteBuffer)calloc(siz

In CMake, specify all executables target_link_libraries certain libraries

In CMake, is there a way to specify that all my executables links to some library? Basically I want all my executables link to tcmalloc and profiler. Simply specify -ltcmalloc and -lprofiler is not a

preferring malloc over calloc [duplicate]

Possible Duplicate: c difference between malloc and calloc Is there any situation where you would prefer malloc over calloc. i know both malloc and calloc allocate memory dynamically and that calloc

Answers

With regard to __nano_init() being called twice: You’ve declared the function as a constructor, so it’s called when the library is loaded, and it’s called a second time explicitly when your malloc() and calloc() implementations are first called. Pick one.

With regard to the calloc() interposer crashing your application: Some of the functions you’re using, including dlsym() and fprintf(), may themselves be attempting to allocate memory, calling your interposer functions. Consider the consequences, and act accordingly.

Using dlsym based hooking can result in crashes, as dlsym calls back into the memory allocator. Instead use malloc hooks, as I suggested in your prior question; these can be installed without actually invoking dlsym at all.