Date: Sat, 6 Apr 2002 23:29:11 +1000 (EST) From: Joshua Goodall <joshua@roughtrade.ent> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/36813: un-bzero'd sin_zero causes bind() in PF_INET to fail Message-ID: <20020406132911.BFC9D3EAA@green.shallow.net>
next in thread | raw e-mail | index | archive | help
>Number: 36813 >Category: kern >Synopsis: un-bzero'd sin_zero causes bind() in PF_INET to fail >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Apr 06 07:00:05 PST 2002 >Closed-Date: >Last-Modified: >Originator: Joshua Goodall >Release: FreeBSD 4.5-STABLE i386 >Organization: >Environment: System: FreeBSD green.shallow.net 4.5-STABLE FreeBSD 4.5-STABLE #2: Sat Mar 30 12:55:07 EST 2002 joshua@green.shallow.net:/usr/obj/usr/src/sys/GREEN i386 >Description: ifa_ifwithaddr compares rather more than is desirable; that is, the sin_zero struct element is also considered. As a result, bind() to addresses other that INADDR_ANY or multicast addresses fails if the struct was not bzero'd first, which although advisable, is not always the case (particularly in some third-party software). This is fixed in -current but not MFC'd. >How-To-Repeat: On an unfixed -stable kernel, this program only succeeded if invoked as "dobz": #include <stdio.h> #include <errno.h> #include <libgen.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> int main(int ac, char **av) { struct sockaddr_in sin; int on = 1, port = 2345, fd; u_long interface_address = 0x7f000001; if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket()"); exit(1); } sin.sin_family = AF_INET; sin.sin_port = htons(port); sin.sin_addr.s_addr= htonl(interface_address); if (strcmp(basename(*av), "dobz") == 0) bzero(sin.sin_zero, sizeof(sin.sin_zero)); if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1) { fprintf(stderr, "bind() fd %d fam %d port %d addr %s errno %d %s\n", fd, sin.sin_family, (int)ntohs(sin.sin_port), inet_ntoa(sin.sin_addr.s_addr), errno, strerror(errno)); exit(1); } printf("succeeded!\n"); } >Fix: Index: sys/netinet/in_pcb.c =================================================================== RCS file: /cvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.59.2.21 diff -u -r1.59.2.21 in_pcb.c --- sys/netinet/in_pcb.c 26 Feb 2002 18:11:24 -0000 1.59.2.21 +++ sys/netinet/in_pcb.c 6 Apr 2002 12:52:45 -0000 @@ -220,6 +220,7 @@ reuseport = SO_REUSEADDR|SO_REUSEPORT; } else if (sin->sin_addr.s_addr != INADDR_ANY) { sin->sin_port = 0; /* yech... */ + bzero(&sin->sin_zero, sizeof(sin->sin_zero)); if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) return (EADDRNOTAVAIL); } >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?20020406132911.BFC9D3EAA>