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
This commit is contained in:
parent
e4101f8332
commit
e95204c39d
@ -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
|
||||
|
@ -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';
|
||||
|
Loading…
x
Reference in New Issue
Block a user