LD_PRELOADed库和子进程

振 禹*_*振 禹 5 c linux fork process ld-preload

大家!

我有这样一个程序(usemalloc)的图像:

#include <stdio.h>
#include <stdlib.h>

#define USER_BYTES_SIZE 100

int main(void){
    char* userbytes = (char*)malloc(USER_BYTES_SIZE*sizeof(char));
    if(!userbytes)
        return 1;

    for(int i = 0; i <= USER_BYTES_SIZE; i++){ // "i <= USER_BYTES_SIZE" leads to an off-by-one memory overrun.
        userbytes[i] = 0;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如你所见,有一个一个一个错误导致内存溢出.我想在运行时检测到这样的错误.LD_PRELOADed库适合我的工作.我已经制作了一个名为libhijack.so的库来劫持对真正的malloc的调用,并将其替换为我自己定制的malloc的调用,它调用真正的malloc并在真正的malloc分配的内存条末端添加红色区域.libhijack.so的代码如下:

void* (*real_malloc) (size_t size);
void* malloc(size_t size){
    real_malloc = ((void*)(*)(size_t))dlsym(RTLD_NEXT, "malloc");
    void* allocbytes = (void*)real_malloc(size + 4); //put 2 bytes at each end, call them red zones
    return (allocbytes + 2);
}
Run Code Online (Sandbox Code Playgroud)

我使用这个命令在库中运行主程序:

LD_PRELOAD=./libhijack.so ./usemalloc
Run Code Online (Sandbox Code Playgroud)

然后,如果可以访问红色区域中的内存,我将检测它们并将它们视为内存溢出错误.

当主进程包含对malloc的调用但是当forked子进程执行此操作时失败,此LD_PRELOAD解决方案很有效.

例如,我们更改"usemalloc"如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // +

#define USER_BYTES_SIZE 100

int main(void){
    pid_t child = fork();
    if(child < 0)
        exit(1);

    if(child == 0){ //child process
        char* userbytes = (char*)malloc(USER_BYTES_SIZE*sizeof(char));
        if(!userbytes)
            return 1;

        for(int i = 0; i <= USER_BYTES_SIZE; i++){ // "i <= USER_BYTES_SIZE" leads to an off-by-one memory overrun.
            userbytes[i] = 0;
        }
    }
    else { //the current process
        wait(NULL);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

LD_PRELOADed库不会检测子进程中发生的溢出错误.

所以我的问题是:如何使用LD_PRELOADed库检测子进程中的溢出错误?是(使用LD_PRELOADed库)可能吗?如果没有,任何替代方案?任何建议都得到了认可!

小智 0

我希望我没有挑剔地指出 libhijack 代码实际上没有分配任何内存?pthread_mutex_lock 需要 pthread_mutex_t * 参数,并返回一个整数,以表明互斥锁是否成功?

另外,您正在 fork() 一个子进程,这与创建线程有点不同,因此 pthread 函数可能不是您真正想要的......?

另一个技巧是,虽然已经演示了导致问题的代码,但您如何检查“红色区域”?也许检测怪癖在于检测代码?