Libc getnameinfo length requirement

Hiroki Sato hrs at FreeBSD.org
Fri Mar 2 02:37:07 UTC 2018


Hi,

Christophe Beauval <christophebeauval at hotmail.com> wrote
  in <VI1PR0402MB371177DFA52E8CC936FCDD00A2C60 at VI1PR0402MB3711.eurprd04.prod.outlook.com>:

ch> Hello all
ch>
ch> This message after having presented the problem below in the freenode
ch> #freebsd and EFNet #bsdcode channels and being advised (amongst others)
ch> to use this mailing list.
ch>
ch> When I got strange errors (EAI_FAIL) from getnameinfo-calls in a private
ch> project, I investigated the freebsd/libc/net/getnameinfo.c source code
ch> and stumbled upon the requirement (in the switch-statement at line 127)
ch> that the "socklen_t salen" argument needs to be the exact same number as
ch> "sizeof(struct sockaddr_in)" for the PF_INET protocol family and
ch> "sizeof(struct sockaddr_in6)" for the PF_INET6 protocol family. This
ch> fails when using a "sockaddr_storage" struct as first argument and tied
ch> to this a "sizeof(struct sockaddr_storage)" as second argument, as can
ch> be found as example in RFC 4038 on page 21 paragraph 6.2.3. For the
ch> PF_LOCAL protocol family a larger "salen" than it's used struct is also
ch> not allowed in that switch.
ch>
ch> A less strict requirement either allowing any larger size (like in
ch> glibc's implementation) or at least the size of "struct
ch> sockaddr_storage" (as suggested by hrs) would solve this problem.

 I have a patch to change getnameinfo() to accept a longer salen
 (attached).  I do not think there is a bad side-effect or impact for
 backward compatibility.  You can try test_getnameinfo.c to test the
 difference.

 While I'm here, I changed the return value on error because SUSv4
 says EAI_FAMILY should be returned when the address length was
 invalid.

-- Hiroki
-------------- next part --------------
A non-text attachment was scrubbed...
Name: getnameinfo.c.20180302-1.diff
Type: text/x-patch
Size: 1126 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-standards/attachments/20180302/ef6cbc77/attachment.bin>
-------------- next part --------------
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(void)
{
	struct sockaddr_storage ss;
	struct sockaddr *sa = (struct sockaddr *)&ss;
	struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
	char hbuf[NI_MAXHOST];
	int error;

	memset(&ss, 0, sizeof(ss));
	sin->sin_family = AF_INET;
	sin->sin_len = sizeof(*sin);

	/* salen == sa->sa_len */
	error = getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf),
	    NULL, 0, NI_NUMERICHOST);
	if (error)
		printf("salen == sa->sa_len: error: %s\n", gai_strerror(error));
	else
		printf("salen == sa->sa_len: hbuf = %s\n", hbuf);

	/* salen > sa->sa_len */
	error = getnameinfo(sa, sizeof(ss), hbuf, sizeof(hbuf),
	    NULL, 0, NI_NUMERICHOST);
	if (error)
		printf("salen > sa->sa_len: error: %s\n", gai_strerror(error));
	else
		printf("salen > sa->sa_len: hbuf = %s\n", hbuf);

	return (EXIT_SUCCESS);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 163 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-standards/attachments/20180302/ef6cbc77/attachment.sig>


More information about the freebsd-standards mailing list