Debugging memmove
Appearance
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)