c - LD_PRELOAD 库和子进程

标签 c linux process fork 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;
}

如您所见,存在导致内存溢出的差一错误。我想在运行时检测此类错误。 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);
}

我使用这个命令运行带有库的主程序:

LD_PRELOAD=./libhijack.so ./usemalloc

然后如果有访问到红色区域的内存,我会检测到它们并认为它们是内存溢出错误。

当主进程包含对 malloc 的调用时,此 LD_PRELOAD 解决方案运行良好,但当 fork 子进程执行此操作时失败。

例如,我们将“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;
}

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

所以我的问题是:如何使用 LD_PRELOADed 库检测子进程中的溢出错误?那(使用 LD_PRELOADed 库)可能吗?如果没有,还有其他选择吗? 任何建议都非常感谢!!!

最佳答案

我希望我指出 libhijack 代码实际上没有分配任何内存,这不是吹毛求疵? pthread_mutex_lock 需要一个 pthread_mutex_t * 参数,并返回一个整数,表示互斥锁是否成功?

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

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

关于c - LD_PRELOAD 库和子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14111056/

相关文章:

c - PIL 逊系数计算数组

c - 套接字和缓冲区

c++ - 如何通过编程方式杀掉audiodg.exe进程?

c - IO重定向和缓冲区问题,fflush和c

来自 native 代码的 Android 唯一设备 ID

python - 如何从 Nmap 输出扫描中省略某些行?

c - Linux 头文件给出语法错误

C 程序(编译为 fcgi)给出 500 内部错误

c - 在 Linux 上使用 C 中的 2 个管道进行双向父子通信

.net - 在 .NET 中,同一台机器上的两个进程进行通信的最佳方式是什么?