Debugging memmove
debug_memmove.c
#include <stdlib.h> #include <stdio.h> /* Version of memmove which aborts if a copy overruns the start of the frame * Based on the OpenSolaris implementation */ void * memmove(void *s, const void *s0, size_t n) { /*abort();*/ if (n != 0) { char *s1 = s; const char *s2 = s0; /* Don't overwrite the frame */ char * frame = (char*) __builtin_frame_address (1); if (s1 < frame && s1 + n >= frame) { fprintf(stderr, "memmove(): attempt to overwrite the frame\n"); abort(); } if (s1 <= s2) { do { *s1++ = *s2++; } while (--n != 0); } else { s2 += n; s1 += n; do { *--s1 = *--s2; } while (--n != 0); } } return (s); }
test.c
#include <string.h> #include <stdio.h> int main(int argc, char** argv) { char buffer1[100]; char buffer2[100]; printf("move 1... "); memmove(buffer1, buffer2, 50); printf("ok\n"); memmove(buffer1, buffer2, 100000); printf("move 2... "); printf("ok\n"); return 0; }
Output
[0740][tstarling@zwinger:~/debug_memmove]$ gcc -c test.c [0740][tstarling@zwinger:~/debug_memmove]$ gcc test.o debug_memmove.o -lc -o protected [0740][tstarling@zwinger:~/debug_memmove]$ gcc test.c -o unprotected [0740][tstarling@zwinger:~/debug_memmove]$ ./unprotected move 1... ok Segmentation fault [0740][tstarling@zwinger:~/debug_memmove]$ ./protected move 1... ok memmove(): attempt to overwrite the frame Aborted
Sample
Compiled -shared and LD_PRELOAD to load it into apache+php...
Program received signal SIGABRT, Aborted. [Switching to Thread 46912497225344 (LWP 21075)] 0x0000003a5782e37d in raise () from /lib64/tls/libc.so.6 (gdb) bt #0 0x0000003a5782e37d in raise () from /lib64/tls/libc.so.6 #1 0x0000003a5782faae in abort () from /lib64/tls/libc.so.6 #2 0x00002aaaaaaac7bb in memmove () from /usr/local/lib/debug/debug_memmove.x86_64.so #3 0x00002aaaaadbf0f7 in zif_str_repeat () from /usr/local/apache/libexec/libphp5.so #4 0x00002aaaaae5c84c in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #5 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #6 0x00002aaaaae5c430 in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #7 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #8 0x00002aaaaae5c430 in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #9 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #10 0x00002aaaaae5c430 in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #11 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #12 0x00002aaaaae5c430 in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #13 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #14 0x00002aaaaae5c430 in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #15 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #16 0x00002aaaaae5c430 in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #17 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #18 0x00002aaaaae5c430 in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #19 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #20 0x00002aaaaae5c430 in zend_do_fcall_common_helper_SPEC () from /usr/local/apache/libexec/libphp5.so #21 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #22 0x00002aaaaae71ead in ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER () from /usr/local/apache/libexec/libphp5.so #23 0x00002aaaaae5c1a2 in execute () from /usr/local/apache/libexec/libphp5.so #24 0x00002aaaaae3de67 in zend_execute_scripts () from /usr/local/apache/libexec/libphp5.so #25 0x00002aaaaadfeecf in php_execute_script () from /usr/local/apache/libexec/libphp5.so ---Type <return> to continue, or q <return> to quit--- #26 0x00002aaaaaeb4a7f in apache_php_module_main () from /usr/local/apache/libexec/libphp5.so #27 0x00002aaaaaeb547f in send_php () from /usr/local/apache/libexec/libphp5.so #28 0x00002aaaaaeb572f in send_parsed_php () from /usr/local/apache/libexec/libphp5.so #29 0x00000000004315d4 in ap_invoke_handler (r=0x759a00) at http_config.c:475 #30 0x0000000000448ad6 in process_request_internal (r=0x759a00) at http_request.c:1298 #31 0x0000000000448b2b in ap_process_request (r=0x759a00) at http_request.c:1314 #32 0x000000000043f191 in child_main (child_num_arg=12) at http_main.c:4786 #33 0x000000000043f460 in make_child (s=0x5b10b0, slot=12, now=1140162878) at http_main.c:4956 #34 0x000000000043f80d in perform_idle_server_maintenance () at http_main.c:5141 #35 0x000000000043fe32 in standalone_main (argc=2, argv=0x7fffffe3e718) at http_main.c:5404 #36 0x0000000000440412 in main (argc=2, argv=0x7fffffe3e718) at http_main.c:5657 (gdb)