From 39e2f1229562e1195169905607bc12290d21f021 Mon Sep 17 00:00:00 2001 From: "millert@openbsd.org" Date: Sun, 1 Mar 2015 15:44:40 +0000 Subject: [PATCH] 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@ --- canohost.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/canohost.c b/canohost.c index a3e3bbff8..223964ea3 100644 --- a/canohost.c +++ b/canohost.c @@ -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 * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -260,24 +260,29 @@ get_socket_address(int sock, int remote, int flags) } /* Work around Linux IPv6 weirdness */ - if (addr.ss_family == AF_INET6) + if (addr.ss_family == AF_INET6) { addrlen = sizeof(struct sockaddr_in6); + ipv64_normalise_mapped(&addr, &addrlen); + } - if (addr.ss_family == AF_UNIX) { + switch (addr.ss_family) { + case AF_INET: + case AF_INET6: + /* Get the address in ascii. */ + if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, + sizeof(ntop), NULL, 0, flags)) != 0) { + error("get_socket_address: getnameinfo %d failed: %s", + flags, ssh_gai_strerror(r)); + return NULL; + } + return xstrdup(ntop); + case AF_UNIX: /* Get the Unix domain socket path. */ return xstrdup(((struct sockaddr_un *)&addr)->sun_path); - } - - ipv64_normalise_mapped(&addr, &addrlen); - - /* Get the address in ascii. */ - if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, - sizeof(ntop), NULL, 0, flags)) != 0) { - error("get_socket_address: getnameinfo %d failed: %s", flags, - ssh_gai_strerror(r)); + default: + /* We can't look up remote Unix domain sockets. */ return NULL; } - return xstrdup(ntop); } char * @@ -390,8 +395,8 @@ get_sock_port(int sock, int local) if (from.ss_family == AF_INET6) fromlen = sizeof(struct sockaddr_in6); - /* Unix domain sockets don't have a port number. */ - if (from.ss_family == AF_UNIX) + /* Non-inet sockets don't have a port number. */ + if (from.ss_family != AF_INET && from.ss_family != AF_INET6) return 0; /* Return port number. */