2009-07-22 gcc -fno-delete-null-pointer-checks
http://slashdot.jp/linux/article.pl?sid=09/07/22/0121226 http://isc.sans.org/diary.html?storyid=6820 http://tamo.tdiary.net/20090718.html
知らなかった。恐いなぁ。
テスト。
#include <stdio.h> struct xxx { struct xxx *xxx; }; void test(struct xxx *p) { struct xxx *pp = p->xxx; if (p == NULL) return; printf("HERE pp=%p\n", pp); }
# cc -fdelete-null-pointer-checks -O -S test.c .file "test.c" .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "HERE pp=%p\n" .text .globl test .type test, @function test: pushl %ebp movl %esp, %ebp subl $16, %esp movl 8(%ebp), %eax pushl (%eax) // pp = p->xxx pushl $.LC0 call printf // printf(...) addl $16, %esp leave ret .size test, .-test .ident "GCC: (GNU) 4.1.3 20080704 prerelease (NetBSD nb2 20081120)"
無条件にprintfが呼ばれてる。まじか…
# cc -fno-delete-null-pointer-checks -O -S test.c .file "test.c" .section .rodata.str1.1,"aMS",@progbits,1 .LC0: .string "HERE pp=%p\n" .text .globl test .type test, @function test: pushl %ebp movl %esp, %ebp subl $8, %esp movl 8(%ebp), %eax movl (%eax), %edx // pp = p->xxx testl %eax, %eax // if (p == NULL) je .L4 // return; subl $8, %esp pushl %edx pushl $.LC0 call printf // printf(...) addl $16, %esp .L4: leave ret .size test, .-test .ident "GCC: (GNU) 4.1.3 20080704 prerelease (NetBSD nb2 20081120)"
このように -fno-delete-null-pointer-checks を付けると大丈夫なのだが、-fdelete-null-pointer-checks は -O2 で enable になるので、
zero page触ってfaultしないkernelとか組込みでは -fno-delete-null-pointer-checks 付けとくのが無難。
つーかそれよりも zero page 触ると panic するようにしとくのが一番いい。
EOF