cdown / rpms / util-linux

Forked from rpms/util-linux 2 years ago
Clone

Blame SOURCES/0135-login-use-IPv4-on-IPv4-mapping-to-IPv6.patch

05ad79
From 7a1a825c7b77785f256e05b1e3ac7676c7485a5c Mon Sep 17 00:00:00 2001
05ad79
From: Karel Zak <kzak@redhat.com>
05ad79
Date: Tue, 4 Jul 2017 12:50:39 +0200
05ad79
Subject: [PATCH 135/135] login: use IPv4 on IPv4-mapping-to-IPv6
05ad79
05ad79
It seems that on some systems (e.g. RHEL7) the libc function
05ad79
getaddrinfo() is not able to translate ::ffff: address to IPv4. The
05ad79
result is 0.0.0.0 host address in the last(1) and utmpdump(1) output.
05ad79
05ad79
 /sbin/login -h "::ffff:192.168.1.7"
05ad79
05ad79
utmpdump:
05ad79
05ad79
  [7] [03926] [1   ] [user1   ] [pts/1       ] [::ffff:192.168.1.7  ] [0.0.0.0        ] [Thu May 12 17:49:50 2016    ]
05ad79
05ad79
Not sure if this is about order of the getaddrinfo() results, system
05ad79
configuration or libc version. It's irrelevant for login(1). We have
05ad79
to be robust enough to write usable address to log files everywhere.
05ad79
05ad79
The solution is to detect IPv4-mapping-to-IPv6 and use IPv4 for utmp.
05ad79
05ad79
Upstream: http://github.com/karelzak/util-linux/commit/1c8792f1ae7fa38cf1d4418ad99c207f65dfdb1a
05ad79
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1296233
05ad79
Signed-off-by: Karel Zak <kzak@redhat.com>
05ad79
---
05ad79
 login-utils/login.c | 9 ++++++++-
05ad79
 1 file changed, 8 insertions(+), 1 deletion(-)
05ad79
05ad79
diff --git a/login-utils/login.c b/login-utils/login.c
05ad79
index e0e960f88..5c36953ef 100644
05ad79
--- a/login-utils/login.c
05ad79
+++ b/login-utils/login.c
05ad79
@@ -1101,8 +1101,15 @@ static void init_remote_info(struct login_context *cxt, char *remotehost)
05ad79
 		} else if (info->ai_family == AF_INET6) {
05ad79
 			struct sockaddr_in6 *sa =
05ad79
 				     (struct sockaddr_in6 *) info->ai_addr;
05ad79
+#ifdef IN6_IS_ADDR_V4MAPPED
05ad79
+			if (IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr)) {
05ad79
+				const uint8_t *bytes = sa->sin6_addr.s6_addr;
05ad79
+				struct in_addr addr = { *(const in_addr_t *) (bytes + 12) };
05ad79
 
05ad79
-			memcpy(cxt->hostaddress, &(sa->sin6_addr), sizeof(sa->sin6_addr));
05ad79
+				memcpy(cxt->hostaddress, &addr, sizeof(struct in_addr));
05ad79
+			} else
05ad79
+#endif
05ad79
+				memcpy(cxt->hostaddress, &(sa->sin6_addr), sizeof(sa->sin6_addr));
05ad79
 		}
05ad79
 		freeaddrinfo(info);
05ad79
 	}
05ad79
-- 
05ad79
2.13.6
05ad79