Date: Fri, 2 Nov 2001 09:41:51 +0200 (EET) From: Valentin Nechayev <netch@segfault.kiev.ua> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/31704: sin_zero field & bind problems Message-ID: <200111020741.fA27fp502226@iv.nn.kiev.ua>
next in thread | raw e-mail | index | archive | help
>Number: 31704 >Category: kern >Synopsis: sin_zero field & bind problems >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Nov 01 23:50:01 PST 2001 >Closed-Date: >Last-Modified: >Originator: Valentin Nechayev <netch@segfault.kiev.ua> >Release: FreeBSD 4.4-RELEASE-20010922 i386 >Organization: private >Environment: AFAIK, all FreeBSD versions have this problem. >Description: If bind() syscall is called for PF_INET socket with address another than INADDR_ANY, and sin_zero field in addr parameter is not filled with zero (this is common programming problem), bind() will fail. Source of failure is ifa_ifwithaddr() in src/sys/net/if.c, which compares structure contents for all their length (determined from sa_len field). ifa_ifwithaddr() is called by in_pcbbind(), which performs all work of comparing addresses and ports. Stevens' examples performs zero-filling before use. But I never saw an _explicit_ rule to perform such filling in any official manual. (Later, I was pointed to chapter in FreeBSD Developers' Handbook, but I don't know any programmer near me who read this document! - all study on real code, or Stevens, or russian books.) During last month, I saw 4 complaints to opaque and misunderstandable behavior of FreeBSD kernel in this place - 2 from Usenet and 2 from my workmates; in each case, complainer was totally confused: he fills all described fields - sin_family, sin_port and sin_addr - and what hell? ;| The needed fix is too simple, and I supposed it is better to apply it once, than continue to confuse people. That's why I also consider this as software bug, and tagged this report as sw-bug, not change-request. There was a small discussion in freebsd-hackers began by me (at 13-14 Oct 2001). There were quite different opinions, but I support one said by John Polstra and Vladimir Dozen that Posix and Single Unix Specification does not require zero-filling neither in general not for this specific structure. This also leads me to consider this problem as software bug, because porting of applications conformed to SUS meets yet another hard-understood and hard-diagnosed rake. Another occurences found with Google: Letter to freebsd-current from Mike Smith, 11/25/1997 20:31:19, PR kern/9309 by ru@ NetBSD PR kern/2972 >How-To-Repeat: #define FILLER 0xDE #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <err.h> #include <stdio.h> #include <string.h> int main() { int s; struct sockaddr_in sia; s = socket( PF_INET, SOCK_STREAM, 0 ); if( s == -1 ) err( 1, "socket()" ); memset( &sia, FILLER, sizeof sia ); sia.sin_family = AF_INET; sia.sin_port = htons( 4455 ); sia.sin_addr.s_addr = htonl( 0x7f000001 ); if( bind( s, ( struct sockaddr* ) &sia, sizeof sia ) < 0 ) err( 1, "bind()" ); puts( "all ok" ); return 0; } With any FILLER value other than 0, bind() will fail with EADDRNOTAVAIL. Also note than sin_len field is refilled in getsockaddr(), and garbage in it in userland copy does not matter. >Fix: Fill sin_zero before testing of address structure instead interface address list. This fix successfully tested by me. AFAIS it is applicable to all FreeBSD versions. --- src/sys/netinet/in_pcb.c.0 Sat Sep 22 17:41:17 2001 +++ src/sys/netinet/in_pcb.c Sat Sep 22 17:44:59 2001 @@ -198,6 +198,7 @@ sin = (struct sockaddr_in *)nam; if (nam->sa_len != sizeof (*sin)) return (EINVAL); + bzero(&sin->sin_zero, sizeof(sin->sin_zero)); #ifdef notdef /* * We should check the family, but old programs /netch >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200111020741.fA27fp502226>