From ba493d37d418b126d7357df553bd065cbc99384e Mon Sep 17 00:00:00 2001
From: Guy Harris <gharris@sonic.net>
Date: Sun, 31 Jul 2022 11:30:43 -0700
Subject: [PATCH] rpcap: improve error messages for host and port resolution
 errors.

If we don't want a particular port nuber in a sock_initaddress() call,
pass NULL rather than "0".  If the service name parameter passsed to
sock_initaddress() is NULL, pass "0" as the service name parameter to
getaddrinfo().

Have get_gai_errstring() precede the host/port name information with an
indication as to whethe it's a host name, port name, or host name and
port name.  Don't say "host name" for EAI_NONAME; rely on the
description get_gai_errstring() provides.  If there's only a port
number, don't preceded it with ":" in get_gai_errstring().

This makes the error message reported if a host and port are provided
not say that the host name couldn't be resolved, because it could be a
problem with the port name (sadly, getaddinfo() doesn't indicate which
is the one with the problem).

It also makes the error message reported if only a port is provided not
say that it's a problem with the host name or show the "host name" as
":<port>".

(cherry picked from commit 33cf6fb70a13a982d70f6a5e5e63aa765073c8e8)

Upstream-Status: Backport [https://github.com/the-tcpdump-group/libpcap/commit/ba493d37d418b126d7357df553bd065cbc99384e]
CVE: CVE-2023-7256 #Dependency Patch2
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
 pcap-rpcap.c    |  6 +++---
 rpcapd/daemon.c |  4 ++--
 sockutils.c     | 19 ++++++++++++++-----
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/pcap-rpcap.c b/pcap-rpcap.c
index 889ade32f6..b68af65d52 100644
--- a/pcap-rpcap.c
+++ b/pcap-rpcap.c
@@ -1020,7 +1020,7 @@ rpcap_remoteact_getsock(const char *host, int *error, char *errbuf)
 	hints.ai_family = PF_UNSPEC;
 	hints.ai_socktype = SOCK_STREAM;
 
-	retval = sock_initaddress(host, "0", &hints, &addrinfo, errbuf,
+	retval = sock_initaddress(host, NULL, &hints, &addrinfo, errbuf,
 	    PCAP_ERRBUF_SIZE);
 	if (retval != 0)
 	{
@@ -1172,7 +1172,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
 		hints.ai_flags = AI_PASSIVE;	/* Data connection is opened by the server toward the client */
 
 		/* Let's the server pick up a free network port for us */
-		if (sock_initaddress(NULL, "0", &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
+		if (sock_initaddress(NULL, NULL, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
 			goto error_nodiscard;
 
 		if ((sockdata = sock_open(addrinfo, SOCKOPEN_SERVER,
@@ -3024,7 +3024,7 @@ int pcap_remoteact_close(const char *host, char *errbuf)
 	hints.ai_family = PF_UNSPEC;
 	hints.ai_socktype = SOCK_STREAM;
 
-	retval = sock_initaddress(host, "0", &hints, &addrinfo, errbuf,
+	retval = sock_initaddress(host, NULL, &hints, &addrinfo, errbuf,
 	    PCAP_ERRBUF_SIZE);
 	if (retval != 0)
 	{
diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c
index 362f4b9bb0..4b91a43242 100644
--- a/rpcapd/daemon.c
+++ b/rpcapd/daemon.c
@@ -2085,8 +2085,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
 	{
 		hints.ai_flags = AI_PASSIVE;
 
-		// Let's the server socket pick up a free network port for us
-		if (sock_initaddress(NULL, "0", &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+		// Make the server socket pick up a free network port for us
+		if (sock_initaddress(NULL, NULL, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
 			goto error;
 
 		if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
diff --git a/sockutils.c b/sockutils.c
index a34f0d1738..ca5b683720 100644
--- a/sockutils.c
+++ b/sockutils.c
@@ -548,13 +548,13 @@ get_gai_errstring(char *errbuf, int errbuflen, const char *prefix, int err,
 	char hostport[PCAP_ERRBUF_SIZE];
 
 	if (hostname != NULL && portname != NULL)
-		snprintf(hostport, PCAP_ERRBUF_SIZE, "%s:%s",
+		snprintf(hostport, PCAP_ERRBUF_SIZE, "host and port %s:%s",
 		    hostname, portname);
 	else if (hostname != NULL)
-		snprintf(hostport, PCAP_ERRBUF_SIZE, "%s",
+		snprintf(hostport, PCAP_ERRBUF_SIZE, "host %s",
 		    hostname);
 	else if (portname != NULL)
-		snprintf(hostport, PCAP_ERRBUF_SIZE, ":%s",
+		snprintf(hostport, PCAP_ERRBUF_SIZE, "port %s",
 		    portname);
 	else
 		snprintf(hostport, PCAP_ERRBUF_SIZE, "<no host or port!>");
@@ -618,7 +618,7 @@ get_gai_errstring(char *errbuf, int errbuflen, const char *prefix, int err,
 
 		case EAI_NONAME:
 			snprintf(errbuf, errbuflen,
-			    "%sThe host name %s couldn't be resolved",
+			    "%sThe %s couldn't be resolved",
 			    prefix, hostport);
 			break;
 
@@ -720,7 +720,16 @@ int sock_initaddress(const char *host, const char *port,
 {
 	int retval;
 
-	retval = getaddrinfo(host, port, hints, addrinfo);
+	/*
+	 * We allow both the host and port to be null, but getaddrinfo()
+	 * is not guaranteed to do so; to handle that, if port is null,
+	 * we provide "0" as the port number.
+	 *
+	 * This results in better error messages from get_gai_errstring(),
+	 * as those messages won't talk about a problem with the port if
+	 * no port was specified.
+	 */
+	retval = getaddrinfo(host, port == NULL ? "0" : port, hints, addrinfo);
 	if (retval != 0)
 	{
 		if (errbuf)
