upstream commit

Make sure we only call getnameinfo() for AF_INET or AF_INET6
 sockets. getpeername() of a Unix domain socket may return without error on
 some systems without actually setting ss_family so getnameinfo() was getting
 called with ss_family set to AF_UNSPEC.  OK djm@
This commit is contained in:
millert@openbsd.org 2015-03-01 15:44:40 +00:00 committed by Damien Miller
parent e47536ba96
commit 39e2f12295
1 changed files with 20 additions and 15 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: canohost.c,v 1.71 2014/07/15 15:54:14 millert Exp $ */ /* $OpenBSD: canohost.c,v 1.72 2015/03/01 15:44:40 millert Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -260,24 +260,29 @@ get_socket_address(int sock, int remote, int flags)
} }
/* Work around Linux IPv6 weirdness */ /* Work around Linux IPv6 weirdness */
if (addr.ss_family == AF_INET6) if (addr.ss_family == AF_INET6) {
addrlen = sizeof(struct sockaddr_in6); addrlen = sizeof(struct sockaddr_in6);
ipv64_normalise_mapped(&addr, &addrlen);
if (addr.ss_family == AF_UNIX) {
/* Get the Unix domain socket path. */
return xstrdup(((struct sockaddr_un *)&addr)->sun_path);
} }
ipv64_normalise_mapped(&addr, &addrlen); switch (addr.ss_family) {
case AF_INET:
case AF_INET6:
/* Get the address in ascii. */ /* Get the address in ascii. */
if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
sizeof(ntop), NULL, 0, flags)) != 0) { sizeof(ntop), NULL, 0, flags)) != 0) {
error("get_socket_address: getnameinfo %d failed: %s", flags, error("get_socket_address: getnameinfo %d failed: %s",
ssh_gai_strerror(r)); flags, ssh_gai_strerror(r));
return NULL; return NULL;
} }
return xstrdup(ntop); return xstrdup(ntop);
case AF_UNIX:
/* Get the Unix domain socket path. */
return xstrdup(((struct sockaddr_un *)&addr)->sun_path);
default:
/* We can't look up remote Unix domain sockets. */
return NULL;
}
} }
char * char *
@ -390,8 +395,8 @@ get_sock_port(int sock, int local)
if (from.ss_family == AF_INET6) if (from.ss_family == AF_INET6)
fromlen = sizeof(struct sockaddr_in6); fromlen = sizeof(struct sockaddr_in6);
/* Unix domain sockets don't have a port number. */ /* Non-inet sockets don't have a port number. */
if (from.ss_family == AF_UNIX) if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
return 0; return 0;
/* Return port number. */ /* Return port number. */