Skip site navigation (1)Skip section navigation (2)
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>