MALLOC_CHECK_ overview
MALLOC_CHECK_ a glibc tool that can be used to find memory errors in linux user space C/C++ applications.To understand the type of memory errors, I used the same tests I used to explore Valgrind's memcheck. I will also provide details of errors MALLOC_CHECK_ catches in "Usage Example" section below.
MALLOC_CHECK_ Usage
- Step1: Modify the program with the following code snippet:
if (mallopt(M_CHECK_ACTION, 7) != 1) {
fprintf(stderr, "mallopt()
failed");
return(-1);
}
The
number 7 n mallopt argument indicates response level. Different response
levels:
0
Ignore error conditions; continue execution (with undefined results).
1
Print a detailed error message and continue
execution.
2
Abort the program.
3
Print detailed error message, stack trace, and memory mappings, and abort the
program.
5
Print a simple error message and continue execution.
7
Print simple error message, stack trace, and memory mappings, and abort the
program.
- Step1: Recompile the program enabling gdb & turning off compiler optimizations:
gcc -g prog.c -o <prog_name>
- Step2: Run the program in with MALLOC_CHECK_ environment variable set:
MALLOC_CHECK_=<response_level> <prog_name> <prog_args>
From my experiments, I found that the response level provided in source code overrides the response level provided here. Despite this overriding, this environment variable had to be passed at command line for source code change to show the impact. However, when I provided 0 here, this overrode the source code response level.
From my experiments, I found that the response level provided in source code overrides the response level provided here. Despite this overriding, this environment variable had to be passed at command line for source code change to show the impact. However, when I provided 0 here, this overrode the source code response level.
I used the code at https://github.com/babuneelam/malloc_check_tests/blob/master/mc_tests.c to explore 10 of the 11 tests:
- uninitialized use
- Read/Write after free
- buffer overrun
- Read/Write bad stack location (underrun)
- Memory Leak
- c++related test (ignore this)
- Overlapping memcpy
- double free
- pass unaddressable memory to system call
- Read/Write invalid stack location (overrun)
- Read/Write invalid global data location (overrun)
root@babu-VirtualBox:~/tools/malloc_check#
gcc -g mc_tests.c -o mc_tests
root@babu-VirtualBox:~/tools/malloc_check#
MALLOC_CHECK_=7 ./mc_tests 1
10
*num =
0
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 2
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 3
i[-1] =
49
free():
invalid pointer
=======
Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767f1)[0xb75b57f1]
/lib/i386-linux-gnu/libc.so.6(cfree+0x9b)[0xb75b914b]
./mc_tests[0x8048676]
./mc_tests[0x8048878]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb7558905]
./mc_tests[0x80484e1]
=======
Memory map: ========
08048000-08049000
r-xp 00000000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
08049000-0804a000
r--p 00000000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
0804a000-0804b000
rw-p 00001000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
09852000-09873000
rw-p 00000000 00:00 0 [heap]
b750a000-b7525000
r-xp 00000000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
b7525000-b7526000
r--p 0001a000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
b7526000-b7527000
rw-p 0001b000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
b753e000-b753f000
rw-p 00000000 00:00 0
b753f000-b76ed000
r-xp 00000000 08:01 263093 /lib/i386-linux-gnu/libc-2.17.so
b76ed000-b76ef000
r--p 001ae000 08:01 263093 /lib/i386-linux-gnu/libc-2.17.so
b76ef000-b76f0000
rw-p 001b0000 08:01 263093 /lib/i386-linux-gnu/libc-2.17.so
b76f0000-b76f3000
rw-p 00000000 00:00 0
b7708000-b770c000
rw-p 00000000 00:00 0
b770c000-b770d000
r-xp 00000000 00:00 0 [vdso]
b770d000-b772d000
r-xp 00000000 08:01 263069 /lib/i386-linux-gnu/ld-2.17.so
b772d000-b772e000
r--p 0001f000 08:01 263069 /lib/i386-linux-gnu/ld-2.17.so
b772e000-b772f000
rw-p 00020000 08:01 263069 /lib/i386-linux-gnu/ld-2.17.so
bfd17000-bfd38000
rw-p 00000000 00:00 0 [stack]
Aborted
(core dumped)
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 4
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 5
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 7
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 8
Segmentation
fault (core dumped)
free(): invalid pointer
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767f1)[0xb75f47f1]
/lib/i386-linux-gnu/libc.so.6(cfree+0x9b)[0xb75f814b]
./mc_tests[0x8048800]
./mc_tests[0x8048963]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb7597905]
./mc_tests[0x8048561]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
08049000-0804a000 r--p 00000000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
0804a000-0804b000 rw-p 00001000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
08418000-08439000 rw-p 00000000 00:00 0 [heap]
b7549000-b7564000 r-xp 00000000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
b7564000-b7565000 r--p 0001a000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
b7565000-b7566000 rw-p 0001b000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
free(): invalid pointer
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x767f1)[0xb75f47f1]
/lib/i386-linux-gnu/libc.so.6(cfree+0x9b)[0xb75f814b]
./mc_tests[0x8048800]
./mc_tests[0x8048963]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0xb7597905]
./mc_tests[0x8048561]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
08049000-0804a000 r--p 00000000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
0804a000-0804b000 rw-p 00001000 08:01 1076878 /home/babu/tools/malloc_check/mc_tests
08418000-08439000 rw-p 00000000 00:00 0 [heap]
b7549000-b7564000 r-xp 00000000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
b7564000-b7565000 r--p 0001a000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
b7565000-b7566000 rw-p 0001b000 08:01 262149 /lib/i386-linux-gnu/libgcc_s.so.1
b757d000-b757e000 rw-p 00000000 00:00 0
b757e000-b772c000 r-xp 00000000 08:01 263093 /lib/i386-linux-gnu/libc-2.17.so
b772c000-b772e000 r--p 001ae000 08:01 263093 /lib/i386-linux-gnu/libc-2.17.so
b772e000-b772f000 rw-p 001b0000 08:01 263093 /lib/i386-linux-gnu/libc-2.17.so
b772f000-b7732000 rw-p 00000000 00:00 0
b7748000-b774b000 rw-p 00000000 00:00 0
b774b000-b774c000 r-xp 00000000 00:00 0 [vdso]
b774c000-b776c000 r-xp 00000000 08:01 263069 /lib/i386-linux-gnu/ld-2.17.so
b776c000-b776d000 r--p 0001f000 08:01 263069 /lib/i386-linux-gnu/ld-2.17.so
b776d000-b776e000 rw-p 00020000 08:01 263069 /lib/i386-linux-gnu/ld-2.17.so
bfd64000-bfd85000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 9
Please type a bunch of characters and hit enter.
wer
root@babu-VirtualBox:~/tools/malloc_check#
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 10
root@babu-VirtualBox:~/tools/malloc_check#
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 11
root@babu-VirtualBox:~/tools/malloc_check#
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 10
root@babu-VirtualBox:~/tools/malloc_check#
root@babu-VirtualBox:~/tools/malloc_check# MALLOC_CHECK_=7 ./mc_tests 11
root@babu-VirtualBox:~/tools/malloc_check#
As we can see, MALLOC_CHECK_ caught only buffer overrun and double free.
Reference:
http://man7.org/linux/man-pages/man3/mallopt.3.html
No comments:
Post a Comment