Date: Wed, 09 Sep 2015 05:30:03 +0900 (JST) From: Hiroki Sato <hrs@FreeBSD.org> To: net@FreeBSD.org Subject: PF_LOCAL support in getaddrinfo/getnameinfo Message-ID: <20150909.053003.1234482271945809368.hrs@allbsd.org>
next in thread | raw e-mail | index | archive | help
----Security_Multipart0(Wed_Sep__9_05_30_03_2015_796)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Wed_Sep__9_05_30_03_2015_346)--" Content-Transfer-Encoding: 7bit ----Next_Part(Wed_Sep__9_05_30_03_2015_346)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi, Is there any problem with adding PF_LOCAL support into getaddrinfo() and getnameinfo()? It was not standardized but can be implemented in a straight forward way (attached). Some old posts in mailing list archives (not for FreeBSD) said it was removed in glibc due to a security issue that getaddrinfo() call with PF_UNSPEC could create /tmp/<hostname> unintentionally when no hostname was resolved. IIRC KAME's original implementation included this functionality, but I am not sure of why it was removed. Does anyone know the reason, or other potential problems? In the attached patch PF_LOCAL is not used when getaddrinfo() is called with PF_UNSPEC, and only an absolute pathname is accepted. This should not have a bad side-effect for the existing programs which use them. -- Hiroki ----Next_Part(Wed_Sep__9_05_30_03_2015_346)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="getaddrinfo_unix.20150909-1.diff" Index: lib/libc/net/getaddrinfo.c =================================================================== --- lib/libc/net/getaddrinfo.c (revision 287348) +++ lib/libc/net/getaddrinfo.c (working copy) @@ -137,13 +137,19 @@ offsetof(struct sockaddr_in6, sin6_addr), in6_addrany, in6_loopback, 1}, #define N_INET 1 +#define N_LOCAL 2 #else #define N_INET 0 +#define N_LOCAL 1 #endif {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), offsetof(struct sockaddr_in, sin_addr), in_addrany, in_loopback, 0}, + {PF_LOCAL, sizeof(char[104]), + sizeof(struct sockaddr_un), + offsetof(struct sockaddr_un, sun_path), + NULL, NULL, 0}, {0, 0, 0, 0, NULL, NULL, 0}, }; @@ -158,9 +164,9 @@ }; static const struct explore explore[] = { -#if 0 - { PF_LOCAL, ANY, ANY, 0x01 }, -#endif + { PF_LOCAL, SOCK_DGRAM, ANY, 0x04 }, + { PF_LOCAL, SOCK_STREAM, ANY, 0x04 }, + { PF_LOCAL, SOCK_SEQPACKET, ANY, 0x04 }, #ifdef INET6 { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, 0x07 }, { PF_INET6, SOCK_STREAM, IPPROTO_TCP, 0x07 }, @@ -408,6 +414,7 @@ ERR(EAI_BADFLAGS); switch (hints->ai_family) { case PF_UNSPEC: + case PF_LOCAL: case PF_INET: #ifdef INET6 case PF_INET6: @@ -1130,6 +1137,9 @@ *res = NULL; ai = NULL; + if (pai->ai_family == PF_LOCAL) + return (0); + /* * filter out AFs that are not supported by the kernel * XXX errno? @@ -1172,7 +1182,7 @@ const struct afd *afd; struct addrinfo *ai; int error; - char pton[PTON_MAX]; + char pton[PTON_MAX], path[PATH_MAX], *p; *res = NULL; ai = NULL; @@ -1182,6 +1192,15 @@ return 0; switch (afd->a_af) { + case AF_LOCAL: + if (hostname[0] != '/') + ERR(EAI_FAIL); + if (strlen(hostname) > afd->a_addrlen) + ERR(EAI_MEMORY); + /* NUL-termination does not need to be guaranteed. */ + strncpy(path, hostname, afd->a_addrlen); + p = &path[0]; + break; case AF_INET: /* * RFC3493 requires getaddrinfo() to accept AF_INET formats @@ -1192,15 +1211,17 @@ */ if (inet_aton(hostname, (struct in_addr *)pton) != 1) return 0; + p = pton; break; default: if (inet_pton(afd->a_af, hostname, pton) != 1) return 0; + p = pton; break; } if (pai->ai_family == afd->a_af) { - GET_AI(ai, afd, pton); + GET_AI(ai, afd, p); GET_PORT(ai, servname); if ((pai->ai_flags & AI_CANONNAME)) { /* @@ -1320,6 +1341,12 @@ memset(ai->ai_addr, 0, (size_t)afd->a_socklen); ai->ai_addr->sa_len = afd->a_socklen; ai->ai_addrlen = afd->a_socklen; + if (ai->ai_family == PF_LOCAL) { + size_t n = strlen(addr); + + ai->ai_addrlen -= afd->a_addrlen - n; + ai->ai_addr->sa_len -= afd->a_addrlen - n; + } ai->ai_addr->sa_family = ai->ai_family = afd->a_af; p = (char *)(void *)(ai->ai_addr); memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen); Index: lib/libc/net/getnameinfo.c =================================================================== --- lib/libc/net/getnameinfo.c (revision 287404) +++ lib/libc/net/getnameinfo.c (working copy) @@ -49,6 +49,7 @@ #include <sys/types.h> #include <sys/socket.h> +#include <sys/un.h> #include <net/if.h> #include <net/if_dl.h> #include <net/if_types.h> @@ -72,6 +73,8 @@ static int getnameinfo_link(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int); static int hexname(const u_int8_t *, size_t, char *, size_t); +static int getnameinfo_un(const struct sockaddr *, socklen_t, char *, + size_t, char *, size_t, int); int getnameinfo(const struct sockaddr *sa, socklen_t salen, @@ -89,6 +92,9 @@ case AF_LINK: return getnameinfo_link(sa, salen, host, hostlen, serv, servlen, flags); + case AF_LOCAL: + return getnameinfo_un(sa, salen, host, hostlen, serv, + servlen, flags); default: return EAI_FAMILY; } @@ -106,6 +112,8 @@ #endif {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), offsetof(struct sockaddr_in, sin_addr)}, + {PF_LOCAL, sizeof(char[104]), sizeof(struct sockaddr_un), + offsetof(struct sockaddr_un, sun_path)}, {0, 0, 0}, }; @@ -469,3 +477,39 @@ } return 0; } + +/* + * getnameinfo_un(): + * Format a pathname of UNIX IPC domain socket. + */ +/* ARGSUSED */ +static int +getnameinfo_un(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, char *serv, size_t servlen, int flags) +{ + const struct afd *afd; + size_t pathlen; + const char *addr; + + for (afd = &afdl[0]; afd != NULL; afd++) { + if (afd->a_af == AF_LOCAL) + break; + } + if (afd == NULL) + return (EAI_FAIL); + + if (serv != NULL && servlen > 0) + *serv = '\0'; + + pathlen = sa->sa_len - afd->a_off; + addr = (const char *)sa + afd->a_off; + + if (pathlen + 1 > hostlen) { + *host = '\0'; + return (EAI_MEMORY); + } + memcpy(host, addr, pathlen); + host[pathlen] = '\0'; + + return (0); +} ----Next_Part(Wed_Sep__9_05_30_03_2015_346)---- ----Security_Multipart0(Wed_Sep__9_05_30_03_2015_796)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlXvRUsACgkQTyzT2CeTzy1ntwCfVVjKrge/tit8wG8mxSzi6slf +nEAn1qhOGKsve8Zx7xz8rDKeNsyEZQZ =bzYI -----END PGP SIGNATURE----- ----Security_Multipart0(Wed_Sep__9_05_30_03_2015_796)----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150909.053003.1234482271945809368.hrs>