Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Dec 2007 03:53:16 -0500
From:      David Schultz <das@FreeBSD.ORG>
To:        Yuriy Tsibizov <Yuriy.Tsibizov@gfk.com>
Cc:        freebsd-current@FreeBSD.ORG
Subject:   Re: story about lost %ebx (stack corruption in inet_aton ?)
Message-ID:  <20071218085316.GB24316@VARK.MIT.EDU>
In-Reply-To: <78664C02FF341B4FAC63E561846E3BCC0EEA56@ex.hhp.local>
References:  <78664C02FF341B4FAC63E561846E3BCC0EEA52@ex.hhp.local> <78664C02FF341B4FAC63E561846E3BCC0EEA56@ex.hhp.local>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Dec 18, 2007, Yuriy Tsibizov wrote:
> > 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()
> 
> mistyped, it is inet_network() that fails...
> 
> testcase:
> 
> #include <sys/cdefs.h>
> #include <sys/types.h>
> #include <netinet/in.h>
> #include <arpa/inet.h>
> #include <ctype.h>
> 
> int main(){
> int val;
> char s[]="10.10.0.10.0/12"; // four dots here!
> char *q;
> 
>         q = strchr(s,'/');
>         if (q) {
>                 *q = '\0';
>                 if ((val = inet_network(s)) != INADDR_NONE) {
>                         printf("OK\n");
>                         return (0);
>                 }
>                 printf("q= %08x\n", q);
>                 *q = '/';
>         }
> }
> 
> 
> (should be built with -O1 or -O2 to expose that bug)

This isn't the compiler's fault. It looks like an off-by-one error
in BIND 9.4.1 that's clobbering the saved %ebx on the stack.
Try this:

Index: lib/libc/inet/inet_network.c
===================================================================
RCS file: /usr/cvs/src/lib/libc/inet/inet_network.c,v
retrieving revision 1.4
diff -u -r1.4 inet_network.c
--- lib/libc/inet/inet_network.c	3 Jun 2007 17:20:26 -0000	1.4
+++ lib/libc/inet/inet_network.c	18 Dec 2007 08:50:08 -0000
@@ -83,7 +83,7 @@
 	if (!digit)
 		return (INADDR_NONE);
 	if (*cp == '.') {
-		if (pp >= parts + 4 || val > 0xffU)
+		if (pp >= parts + 3 || val > 0xffU)
 			return (INADDR_NONE);
 		*pp++ = val, cp++;
 		goto again;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20071218085316.GB24316>