Blame SOURCES/0001-Automatically-disable-inet6-transport-if-ipv6-is-dis.patch

5ade7d
From 8302f576f8b41f9aa95b091a9ef001ab5ddc2ef5 Mon Sep 17 00:00:00 2001
5ade7d
From: Ray Strode <rstrode@redhat.com>
5ade7d
Date: Fri, 6 May 2022 14:23:59 -0400
5ade7d
Subject: [PATCH] Automatically disable inet6 transport if ipv6 is disabled on
5ade7d
 machine
5ade7d
5ade7d
If a machine is booted with ipv6.disable=1, trying to bind to an
5ade7d
AF_INET6 socket will fail with AFNOSUPPORT.
5ade7d
5ade7d
The tcp transport automatically falls back to ipv4 in this case, but
5ade7d
the more specific inet6 transport just fails.
5ade7d
5ade7d
This failure leads to MakeAllCOTSServerListeners returning a partial
5ade7d
success.
5ade7d
5ade7d
Unfortunately, the X server can't really contiue with partial successes
5ade7d
from this function if -displayfd is in use, since that would, in other
5ade7d
cases, potentially lead to the -displayfd electing a display number that
5ade7d
is potentially partially in use by a rogue program.
5ade7d
5ade7d
This commit addresses the issue by automatically disabling transports
5ade7d
when they fail with AFNOSUPPORT, leading them to get ignored, rather than
5ade7d
proceeding and ultimately returning from MakeAllCOTSServerListerns with
5ade7d
partial=TRUE.
5ade7d
---
5ade7d
 Xtranssock.c | 15 +++++++++++----
5ade7d
 1 file changed, 11 insertions(+), 4 deletions(-)
5ade7d
5ade7d
diff --git a/Xtranssock.c b/Xtranssock.c
5ade7d
index 632c1b5..2c80a5c 100644
5ade7d
--- a/Xtranssock.c
5ade7d
+++ b/Xtranssock.c
5ade7d
@@ -584,66 +584,73 @@ TRANS(SocketOpenCOTSClient) (Xtransport *thistrans, const char *protocol,
5ade7d
 			     const char *host, const char *port)
5ade7d
 {
5ade7d
     return TRANS(SocketOpenCOTSClientBase)(
5ade7d
 			thistrans->TransName, protocol, host, port, -1);
5ade7d
 }
5ade7d
 
5ade7d
 
5ade7d
 #endif /* TRANS_CLIENT */
5ade7d
 
5ade7d
 
5ade7d
 #ifdef TRANS_SERVER
5ade7d
 
5ade7d
 static XtransConnInfo
5ade7d
 TRANS(SocketOpenCOTSServer) (Xtransport *thistrans, const char *protocol,
5ade7d
 			     const char *host, const char *port)
5ade7d
 
5ade7d
 {
5ade7d
     XtransConnInfo	ciptr;
5ade7d
     int	i = -1;
5ade7d
 
5ade7d
     prmsg (2,"SocketOpenCOTSServer(%s,%s,%s)\n", protocol, host, port);
5ade7d
 
5ade7d
     SocketInitOnce();
5ade7d
 
5ade7d
     while ((i = TRANS(SocketSelectFamily) (i, thistrans->TransName)) >= 0) {
5ade7d
 	if ((ciptr = TRANS(SocketOpen) (
5ade7d
 		 i, Sockettrans2devtab[i].devcotsname)) != NULL)
5ade7d
 	    break;
5ade7d
     }
5ade7d
     if (i < 0) {
5ade7d
-	if (i == -1)
5ade7d
-	    prmsg (1,"SocketOpenCOTSServer: Unable to open socket for %s\n",
5ade7d
-		   thistrans->TransName);
5ade7d
-	else
5ade7d
+	if (i == -1) {
5ade7d
+		if (errno == EAFNOSUPPORT) {
5ade7d
+			thistrans->flags |= TRANS_NOLISTEN;
5ade7d
+			prmsg (1,"SocketOpenCOTSServer: Socket for %s unsupported on this system.\n",
5ade7d
+			       thistrans->TransName);
5ade7d
+		} else {
5ade7d
+			prmsg (1,"SocketOpenCOTSServer: Unable to open socket for %s\n",
5ade7d
+			       thistrans->TransName);
5ade7d
+		}
5ade7d
+	} else {
5ade7d
 	    prmsg (1,"SocketOpenCOTSServer: Unable to determine socket type for %s\n",
5ade7d
 		   thistrans->TransName);
5ade7d
+	}
5ade7d
 	return NULL;
5ade7d
     }
5ade7d
 
5ade7d
     /*
5ade7d
      * Using this prevents the bind() check for an existing server listening
5ade7d
      * on the same port, but it is required for other reasons.
5ade7d
      */
5ade7d
 #ifdef SO_REUSEADDR
5ade7d
 
5ade7d
     /*
5ade7d
      * SO_REUSEADDR only applied to AF_INET && AF_INET6
5ade7d
      */
5ade7d
 
5ade7d
     if (Sockettrans2devtab[i].family == AF_INET
5ade7d
 #if defined(IPv6) && defined(AF_INET6)
5ade7d
       || Sockettrans2devtab[i].family == AF_INET6
5ade7d
 #endif
5ade7d
     )
5ade7d
     {
5ade7d
 	int one = 1;
5ade7d
 	setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR,
5ade7d
 		    (char *) &one, sizeof (int));
5ade7d
     }
5ade7d
 #endif
5ade7d
 #ifdef IPV6_V6ONLY
5ade7d
     if (Sockettrans2devtab[i].family == AF_INET6)
5ade7d
     {
5ade7d
 	int one = 1;
5ade7d
 	setsockopt(ciptr->fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(int));
5ade7d
     }
5ade7d
-- 
5ade7d
2.35.1
5ade7d