大家好!
我有这样一个程序(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/