From owner-freebsd-current@FreeBSD.ORG Tue Dec 18 06:35:10 2007 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4D22C16A419 for ; Tue, 18 Dec 2007 06:35:10 +0000 (UTC) (envelope-from Yuriy.Tsibizov@gfk.com) Received: from mx2.gfk.ru (mx2.gfk.ru [84.21.231.139]) by mx1.freebsd.org (Postfix) with ESMTP id AD65A13C46A for ; Tue, 18 Dec 2007 06:35:09 +0000 (UTC) (envelope-from Yuriy.Tsibizov@gfk.com) Received: from ex.hhp.local by mx2.gfk.ru (MDaemon PRO v9.6.0) with ESMTP id md50000727977.msg for ; Tue, 18 Dec 2007 09:35:55 +0300 X-MimeOLE: Produced By Microsoft Exchange V6.5 Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Date: Tue, 18 Dec 2007 09:35:51 +0300 Message-ID: <78664C02FF341B4FAC63E561846E3BCC0EEA52@ex.hhp.local> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: story about lost %ebx (stack corruption in inet_aton ?) thread-index: AchA1XTzC+2gKXXYRPmGbS9V4nLlUAAaYhZQ From: "Yuriy Tsibizov" To: X-Spam-Processed: mx2.gfk.ru, Tue, 18 Dec 2007 09:35:55 +0300 (not processed: message from valid local sender) X-MDRemoteIP: 10.0.0.30 X-Return-Path: Yuriy.Tsibizov@gfk.com X-Envelope-From: Yuriy.Tsibizov@gfk.com X-MDaemon-Deliver-To: freebsd-current@freebsd.org X-MDAV-Processed: mx2.gfk.ru, Tue, 18 Dec 2007 09:35:56 +0300 Subject: story about lost %ebx (stack corruption in inet_aton ?) X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Dec 2007 06:35:10 -0000 (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.