Author: hrs
Date: Thu Mar 15 13:46:28 2018
New Revision: 331000
URL: https://svnweb.freebsd.org/changeset/base/331000

Log:
  Make getnameinfo(3) salen requirement less strict and
  document details of salen in getnameinfo(3) manual page.
  
  getnameinfo(3) returned EAI_FAIL when salen was not equal to
  the length corresponding to the value specified by sa->sa_family.
  However, POSIX or RFC 3493 does not require it and RFC 4038
  Sec.6.2.3 shows an example passing sizeof(struct sockaddr_storage)
  to salen.
  
  This change makes the requirement less strict by accepting
  salen up to sizeof(struct sockaddr_storage).  It also includes
  two more changes: one is to fix return values because both SUSv4
  and RFC 3493 require EAI_FAMILY when the address length is invalid,
  another is to fix sa_len dependency in PF_LOCAL.
  
  Pointed out by:       Christophe Beauval
  Reviewed by:  ae
  Differential Revision:        https://reviews.freebsd.org/D14585

Modified:
  head/lib/libc/net/getnameinfo.3
  head/lib/libc/net/getnameinfo.c

Modified: head/lib/libc/net/getnameinfo.3
==============================================================================
--- head/lib/libc/net/getnameinfo.3     Thu Mar 15 13:07:15 2018        
(r330999)
+++ head/lib/libc/net/getnameinfo.3     Thu Mar 15 13:46:28 2018        
(r331000)
@@ -18,7 +18,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 28, 2016
+.Dd March 15, 2018
 .Dt GETNAMEINFO 3
 .Os
 .Sh NAME
@@ -80,6 +80,20 @@ or UNIX-domain respectively
 that is
 .Fa salen
 bytes long.
+If
+.Fa salen
+is shorter than the length corresponding to the specified
+address family or longer than
+.Fn sizeof "struct sockaddr_storage" ,
+it returns
+.Er EAI_FAMILY .
+Note that
+.Va sa->sa_len
+should be consistent with
+.Fa salen
+though the value of
+.Va sa->sa_len
+is not directly used in this function.
 .Pp
 The host and service names associated with
 .Fa sa

Modified: head/lib/libc/net/getnameinfo.c
==============================================================================
--- head/lib/libc/net/getnameinfo.c     Thu Mar 15 13:07:15 2018        
(r330999)
+++ head/lib/libc/net/getnameinfo.c     Thu Mar 15 13:46:28 2018        
(r331000)
@@ -124,26 +124,36 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen
        afd = find_afd(sa->sa_family);
        if (afd == NULL)
                return (EAI_FAMILY);
+       /*
+        * getnameinfo() accepts an salen of sizeof(struct sockaddr_storage)
+        * at maximum as shown in RFC 4038 Sec.6.2.3.
+        */
+       if (salen > sizeof(struct sockaddr_storage))
+               return (EAI_FAMILY);
+
        switch (sa->sa_family) {
        case PF_LOCAL:
                /*
-                * PF_LOCAL uses variable sa->sa_len depending on the
+                * PF_LOCAL uses variable salen depending on the
                 * content length of sun_path.  Require 1 byte in
                 * sun_path at least.
                 */
-               if (salen > afd->a_socklen ||
-                   salen <= afd->a_socklen -
+               if (salen <= afd->a_socklen -
                        sizeofmember(struct sockaddr_un, sun_path))
-                       return (EAI_FAIL);
+                       return (EAI_FAMILY);
+               else if (salen > afd->a_socklen)
+                       salen = afd->a_socklen;
                break;
        case PF_LINK:
                if (salen <= afd->a_socklen -
                        sizeofmember(struct sockaddr_dl, sdl_data))
-                       return (EAI_FAIL);
+                       return (EAI_FAMILY);
                break;
        default:
-               if (salen != afd->a_socklen)
-                       return (EAI_FAIL);
+               if (salen < afd->a_socklen)
+                       return (EAI_FAMILY);
+               else
+                       salen = afd->a_socklen;
                break;
        }
 
@@ -517,7 +527,7 @@ getnameinfo_un(const struct afd *afd,
        if (serv != NULL && servlen > 0)
                *serv = '\0';
        if (host != NULL && hostlen > 0) {
-               pathlen = sa->sa_len - afd->a_off;
+               pathlen = salen - afd->a_off;
 
                if (pathlen + 1 > hostlen) {
                        *host = '\0';
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to