[ TOP | Recently ]

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