From d1ee423b109518060e744208947a97cb23d7e902 Mon Sep 17 00:00:00 2001 From: op Date: Thu, 4 Jan 2024 09:34:03 +0000 Subject: [PATCH] fix IPv6 addresses table lookups Rework parse_sockaddr() to not reach inet_pton() with a brace-wrapped IPv6 address. Issue reported by Kirill Miazine. ok millert@ --- usr.sbin/smtpd/table.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/usr.sbin/smtpd/table.c b/usr.sbin/smtpd/table.c index 7328cf5df6e..99db7b0a305 100644 --- a/usr.sbin/smtpd/table.c +++ b/usr.sbin/smtpd/table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: table.c,v 1.50 2021/06/14 17:58:16 eric Exp $ */ +/* $OpenBSD: table.c,v 1.51 2024/01/04 09:34:03 op Exp $ */ /* * Copyright (c) 2013 Eric Faurot @@ -628,7 +628,8 @@ parse_sockaddr(struct sockaddr *sa, int family, const char *str) struct in6_addr in6a; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; - char *cp, *str2; + char *cp; + char addr[NI_MAXHOST]; const char *errstr; switch (family) { @@ -649,21 +650,19 @@ parse_sockaddr(struct sockaddr *sa, int family, const char *str) return (0); case PF_INET6: - if (strncasecmp("ipv6:", str, 5) == 0) + if (*str == '[') + str++; + if (!strncasecmp("ipv6:", str, 5)) str += 5; - cp = strchr(str, SCOPE_DELIMITER); - if (cp) { - str2 = strdup(str); - if (str2 == NULL) - return (-1); - str2[cp - str] = '\0'; - if (inet_pton(PF_INET6, str2, &in6a) != 1) { - free(str2); - return (-1); - } - cp++; - free(str2); - } else if (inet_pton(PF_INET6, str, &in6a) != 1) + + if (strlcpy(addr, str, sizeof(addr)) >= sizeof(addr)) + return (-1); + if ((cp = strchr(addr, ']')) != NULL) + *cp = '\0'; + if ((cp = strchr(addr, SCOPE_DELIMITER)) != NULL) + *cp++ = '\0'; + + if (inet_pton(PF_INET6, addr, &in6a) != 1) return (-1); sin6 = (struct sockaddr_in6 *)sa; -- 2.20.1