From owner-freebsd-net@freebsd.org Tue Sep 8 20:31:02 2015 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F1282A004B7 for ; Tue, 8 Sep 2015 20:31:02 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from mailman.ysv.freebsd.org (mailman.ysv.freebsd.org [IPv6:2001:1900:2254:206a::50:5]) by mx1.freebsd.org (Postfix) with ESMTP id CBDA91516 for ; Tue, 8 Sep 2015 20:31:02 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: by mailman.ysv.freebsd.org (Postfix) id C91EBA004B6; Tue, 8 Sep 2015 20:31:02 +0000 (UTC) Delivered-To: net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C8AA9A004B5 for ; Tue, 8 Sep 2015 20:31:02 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from mail.allbsd.org (gatekeeper.allbsd.org [IPv6:2001:2f0:104:e001::32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.allbsd.org", Issuer "RapidSSL CA" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 8138F1508 for ; Tue, 8 Sep 2015 20:31:01 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from alph.d.allbsd.org (alph.d.allbsd.org [IPv6:2001:2f0:104:e010:862b:2bff:febc:8956] (may be forged)) (authenticated bits=56) by mail.allbsd.org (8.14.9/8.14.9) with ESMTP id t88KUl7I064860 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 9 Sep 2015 05:30:47 +0900 (JST) (envelope-from hrs@FreeBSD.org) Received: from localhost (localhost [IPv6:::1]) (authenticated bits=0) by alph.d.allbsd.org (8.14.9/8.14.9) with ESMTP id t88KUjM0049739 for ; Wed, 9 Sep 2015 05:30:47 +0900 (JST) (envelope-from hrs@FreeBSD.org) Date: Wed, 09 Sep 2015 05:30:03 +0900 (JST) Message-Id: <20150909.053003.1234482271945809368.hrs@allbsd.org> To: net@FreeBSD.org Subject: PF_LOCAL support in getaddrinfo/getnameinfo From: Hiroki Sato X-PGPkey-fingerprint: BDB3 443F A5DD B3D0 A530 FFD7 4F2C D3D8 2793 CF2D X-Mailer: Mew version 6.7 on Emacs 24.5 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="--Security_Multipart0(Wed_Sep__9_05_30_03_2015_796)--" Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.98.6 at gatekeeper.allbsd.org X-Virus-Status: Clean X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.4.3 (mail.allbsd.org [IPv6:2001:2f0:104:e001::32]); Wed, 09 Sep 2015 05:30:53 +0900 (JST) X-Spam-Status: No, score=-98.0 required=13.0 tests=CONTENT_TYPE_PRESENT, RCVD_IN_AHBL, RCVD_IN_AHBL_PROXY, RCVD_IN_AHBL_SPAM, RDNS_NONE, USER_IN_WHITELIST autolearn=no autolearn_force=no version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on gatekeeper.allbsd.org X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Sep 2015 20:31:03 -0000 ----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/ 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 #include +#include #include #include #include @@ -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)----