From nobody@FreeBSD.org  Tue Feb 23 14:25:04 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 3F22B106566C
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 23 Feb 2010 14:25:04 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 2E1498FC12
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 23 Feb 2010 14:25:04 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o1NEP3ab077939
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 23 Feb 2010 14:25:03 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o1NEP3wQ077938;
	Tue, 23 Feb 2010 14:25:03 GMT
	(envelope-from nobody)
Message-Id: <201002231425.o1NEP3wQ077938@www.freebsd.org>
Date: Tue, 23 Feb 2010 14:25:03 GMT
From: Axel Drfler <axeld@pinc-software.de>
To: freebsd-gnats-submit@FreeBSD.org
Subject: bind/connect/sendto too strict about sockaddr length
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         144231
>Category:       kern
>Synopsis:       bind/connect/sendto too strict about sockaddr length
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-net
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 23 14:30:01 UTC 2010
>Closed-Date:    
>Last-Modified:  Thu Feb 17 10:50:36 UTC 2011
>Originator:     Axel Drfler
>Release:        8.0-RELEASE
>Organization:
>Environment:
i386
>Description:
bind(), connect(), and sendto() all have a socklen_t argument specifying the size of the sockaddr buffer passed in.

However, with IPv4 at least, passing any other value than 16 (sizeof(sockaddr)) will result in EINVAL.

There is no reason why this restriction is there, and it's quite unhandy when dealing with the sockaddr_storage structure.

(I have not compiled the test program, but it should be able to reproduce the problem)

>How-To-Repeat:
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>

int
main()
{
  sockaddr_storage buffer;
  ((sockaddr_in*)&buffer)->sa_family = AF_INET;
  ((sockaddr_in*)&buffer)->sa_addr.s_addr = INADDR_ANY;
  ((sockaddr_in*)&buffer)->sa_port = 0;

  int fd = socket(AF_INET, SOCK_DGRAM, 0);
  if (bind(fd, &buffer, sizeof(buffer)) != 0)
    perror("bind");

  return 0;
}

>Fix:


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-standards->freebsd-net 
Responsible-Changed-By: brucec 
Responsible-Changed-When: Thu Feb 17 10:48:57 UTC 2011 
Responsible-Changed-Why:  
Not a standards issue: POSIX says EINVAL is returned if address_len is not a 
valid length for the address family, so FreeBSD's implementation would appear to 
be correct. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=144231 
>Unformatted:
