Date: Tue, 18 Dec 2007 09:35:51 +0300 From: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.com> To: <freebsd-current@freebsd.org> Subject: story about lost %ebx (stack corruption in inet_aton ?) Message-ID: <78664C02FF341B4FAC63E561846E3BCC0EEA52@ex.hhp.local>
next in thread | raw e-mail | index | archive | help
(this is an update to 'story about lost %ebx (gcc bug?)' mail that seems
to wait for moderato approval)
My first impression was that there is a bug in gcc compiler on 7-BETA
and 8-CURRENT (i386 only, and only if optimization is enabled), but it
seems to be incorrect. Most probably source is stack corruption in
inet_aton()
How to reproduce:
1) Get i386 version of 7-BETA or 8-CURRENT (amd64 does not expose this
bug)
2) make shure you build with default options (empty /etc/make.conf)
3) /sbin/route add 172.17.1.0.0/12 10.0.0.1 (yes, network address is
incorrect)
4) get core dump
core dump shows that in route.c q=3D=3DNULL in last assignment of this =
code
block:
--------
q =3D strchr(s,'/');
if (q && which =3D=3D RTA_DST) {
*q =3D '\0';
if ((val =3D inet_network(s)) !=3D INADDR_NONE) {
inet_makenetandmask(
val, &su->sin, strtoul(q+1, 0, 0));
return (0);
}
*q =3D '/';
}
--------
with relevant asm output:
--asm--- (-O1)
movl $47, 4(%esp) #,
movl 12(%ebp), %edx # s,
movl %edx, (%esp) #,
call strchr #
movl %eax, %ebx #, q.583
## %ebx is q.583
testl %eax, %eax # q.583
setne %al #, tmp160
cmpl $1, 8(%ebp) #, which
sete -73(%ebp) #, D.6325
testb %al, -73(%ebp) # tmp160, D.6325
je .L419 #,
movb $0, (%ebx) #,* q.583
movl 12(%ebp), %eax # s,
movl %eax, (%esp) #,
call __inet_network #=20
## %ebx here should be =3D=3D 0, because nothing change it below
movl %eax, %esi #, D.6327
cmpl $-1, %eax #, D.6327
je .L421 #,
leal 1(%ebx), %eax #, D.6328
movl $0, 8(%esp) #,
movl $0, 4(%esp) #,
movl %eax, (%esp) # D.6328,
call strtoul #
movl %eax, 8(%esp) # D.6329,
movl %edi, 4(%esp) # su,
movl %esi, (%esp) # D.6327,
call inet_makenetandmask #
movl $0, %eax #, D.6280=20
jmp .L385 #
.L421:
## null pointer reference here
movb $47, (%ebx) #,* q.583
.L419: =20
-- asm---
My findings so far:
for route.c (and 'broken' libc) :
1) code generated by gcc 4.2.1 for this part of route.c is correct for
-O0 and -O1. You can make it with CFLAGS=3D-save-temps -fverbose-asm and
check yourself.
2) if route is built with -O0 it will work well in any case. (will not
use %ebx)
3) if route is built with -O1 -fno-tree-lrs it will work well (it will
not use %ebx to keep q)
4) if -ftree-lrs is enabled with -O1 (or -O2) it will fail (because it
will use %ebx that seems to be =3D=3D 0 after call to inet_network(s)).
for libc:
1) if libc is built with -O0 any optimization on route.c will work well
(it will not push/pop %ebx in __inet_network in libc)
2) if libc is built with -O1 -fno-tree-lrs route will coredump
(-fno-tree-lrs is only a workaround for route.c)
3) -O1 and -O2 libc will give you coredump
I checked inet_network.s asm output and can't find any obvious compiler
errors there.
The only reason for this (as I see now) is a stack corruption in
inet_aton that leads to old %ebx (pushed into stack) being replaced with
0x0 and then popped on return from inet_network.
Yuriy.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?78664C02FF341B4FAC63E561846E3BCC0EEA52>
