From patchwork Mon Jan 1 09:27:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 3542 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7301:2791:b0:100:d2e5:60d with SMTP id hm17csp1401036dyb; Mon, 1 Jan 2024 01:27:56 -0800 (PST) X-Google-Smtp-Source: AGHT+IFu5A6RY/tsYtKmUERBygOvd9lOAjAIJcpayfAqjef10IGsxL2uqcMa6TGjlnJUjYJycvhd X-Received: by 2002:a05:6a20:3207:b0:197:1c10:aa3 with SMTP id hl7-20020a056a20320700b001971c100aa3mr934308pzc.2.1704101276706; Mon, 01 Jan 2024 01:27:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704101276; cv=none; d=google.com; s=arc-20160816; b=fWp6S+Fkj89i+SBpxuyLTHK1suzKND/xVKIYQGZAVV9FNn2sac51aFx/M8ueaq6F3O B+tPxqtrnup30FCngvIV0dBOQAJSjhMr5o0tgWSNXLdDfaXStpoAW0/i30bxgWrn1yac hsXezPjfDUUP+XVRFin7r2Yj0BlqQ9Yr/HygglWv0pthCE7RbXTVBckUCfrUvTSdN0h8 btBAErymy2f8QasbiSn+DVIv+57t6kqEm1z6ORYB4Ms46tfnRAt06zPWKm1TrZqFsSbm 9dS68yvJL51YH3NrcJWnOqXjswKgIsUmR5YnXYYINvlKASGn4zNlgJiw5axKB6fisRHZ FTrw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:message-id:date:to:from:dkim-signature:dkim-signature; bh=xZ38IyBffcK8NSLNpX9lc0OwBxxaW/VpcM31gQ/Zc+Y=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=PfSJ0Ok93Wn7k2ZFLjBf2R0A22lxKRNRIHwdVj7tc+rUAgcGky5Ab/7RGIt8GG+UQN 9xedrFSiUd/hBqs/c/EneoZ7OPir9Yuo/fLE4HPUKBwLrSd6lAsjCuw3DJ6TSeiJ3kb4 JwHsl1Oe/imz7PIgWitSiYXtvgiiSWS8yfpPJkHZVvJ+MUuH3Z8IILjCit8LM+Ggjkpp U+3V3u80heyCUQE4cqwvSJDKWOtvYb72H9XsTZSxBZFy3fp5f1T0jmNROkN3DZC1JUXx mtvxcrwpnZ79SEoO91Uo6oVlSnvFOZJpxjDATAyVbdnhffS74TDQD6ZIzj2kpL/Mr+lp X/8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Me9zNgH4; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=SBQe7jrd; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id d2-20020aa78682000000b006d9bb450d75si11864418pfo.84.2024.01.01.01.27.56 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Jan 2024 01:27:56 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Me9zNgH4; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=SBQe7jrd; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1rKEa1-0008MR-RY; Mon, 01 Jan 2024 09:27:30 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1rKEZz-0008MK-Ov for openvpn-devel@lists.sourceforge.net; Mon, 01 Jan 2024 09:27:28 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-Id: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=V3Qir7E95SRUYLQQ7WVJMW0qDNj9x+iUJ2KlUYySt6s=; b=Me9zNgH4dJTIHV2UMcqjGdXyrm 4KIL4hUlgnri4D+wNM2iTVxlTe/CNwQFAboy//bolmO+Y3a089ppQs/w9yYzCqh1uxVo/+2EF4MgU VjKvi4Iu5agPOPdZmbWhJi+U3NgtGaT+wW0jS1zfPc89++H6+fiC9LLQP+myfGFKkrPA=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:To:From: Sender:Reply-To:Cc:Content-Type:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=V3Qir7E95SRUYLQQ7WVJMW0qDNj9x+iUJ2KlUYySt6s=; b=S BQe7jrdtIBNmf9IJw7SpiT6deRPmPiJKIJZn/sI1sVFW5NUb5JPgeEfJAAFhufEd4nUJZCHxixRLK vFA11RB9BWHCMkCM2RYYZx+njSaK51s3RYpxUfhO7Y4vvtMu3aIngCd3yfgUs+aI9rtK1SrPqdMJp b8fwHlITOxojRgk0=; Received: from vmail1.greenie.net ([195.30.8.66]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1rKEZw-0006lM-L4 for openvpn-devel@lists.sourceforge.net; Mon, 01 Jan 2024 09:27:26 +0000 Received: from oi2019.ov.greenie.net (oi2019.ov.greenie.net [IPv6:2001:608:0:814:0:0:f000:20]) by vmail1.greenie.net (8.17.2/8.16.1) with ESMTPS id 4019RFQd094807 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 1 Jan 2024 10:27:15 +0100 (CET) Received: from oi2019.ov.greenie.net (oi2019 [127.0.0.1]) by oi2019.ov.greenie.net (8.15.2+Sun/8.15.2) with ESMTP id 4019RE0o019037 for ; Mon, 1 Jan 2024 10:27:14 +0100 (CET) Received: (from gert@localhost) by oi2019.ov.greenie.net (8.15.2+Sun/8.15.2/Submit) id 4019RErP019036 for openvpn-devel@lists.sourceforge.net; Mon, 1 Jan 2024 10:27:14 +0100 (CET) From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Mon, 1 Jan 2024 10:27:14 +0100 Message-Id: <20240101092714.18992-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.23.0 MIME-Version: 1.0 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.4 (vmail1.greenie.net [IPv6:2001:608:1:995a:20c:29ff:feb8:10eb]); Mon, 01 Jan 2024 10:27:15 +0100 (CET) X-Spam-Score: -2.1 (--) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: commit f13331005d5a7 (gerrit/454) most painfully works around the limitations of the SIOCGIFCONF API, with struct member access on an unaligned buffer, possibly overrunning sockaddr structures, etc. - [...] Content analysis details: (-2.1 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [195.30.8.66 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1rKEZw-0006lM-L4 Subject: [Openvpn-devel] [PATCH] get_default_gateway() HWADDR overhaul X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1786879700554689183?= X-GMAIL-MSGID: =?utf-8?q?1786879700554689183?= commit f13331005d5a7 (gerrit/454) most painfully works around the limitations of the SIOCGIFCONF API, with struct member access on an unaligned buffer, possibly overrunning sockaddr structures, etc. - and the result still did not work on OpenSolaris and OpenBSD (no AF_LINK in the returned elements). Reading through OpenBSD "ifconfig" source, I found getifaddrs(3), which is exactly what we want here - it works on FreeBSD, NetBSD, OpenBSD and MacOS, and all returned pointers are properly aligned, so the code gets shorter, easier to read, and UBSAN is still happy. OpenSolaris does have getifaddrs(3), but (surprise) it does not work, as in "it does not return AF_LINK addresses". It does have SIOCGIFHWADDR, instead, and "man if_tcp" claims "should behave in a manner compatible with Linux" - so TARGET_SOLARIS gets a copy of the Linux code now (works). Signed-off-by: Gert Doering Acked-By: Arne Schwabe --- src/openvpn/route.c | 97 +++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 65 deletions(-) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 0e6667f7..f75199c6 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -3445,6 +3445,9 @@ get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, #include #include #include +#if !defined(TARGET_SOLARIS) +#include +#endif struct rtmsg { struct rt_msghdr m_rtm; @@ -3641,19 +3644,11 @@ get_default_gateway(struct route_gateway_info *rgi, openvpn_net_ctx_t *ctx) rgi->flags |= RGI_NETMASK_DEFINED; } -#if !defined(TARGET_SOLARIS) - /* Illumos/Solaris does not provide AF_LINK entries when calling the - * SIOCGIFCONF API, so there is little sense to trying to figure out a - * MAC address from an API that does not provide that information */ - /* try to read MAC addr associated with interface that owns default gateway */ if (rgi->flags & RGI_IFACE_DEFINED) { - struct ifconf ifc; - const int bufsize = 4096; - char *buffer; - - buffer = (char *) gc_malloc(bufsize, true, &gc); +#if defined(TARGET_SOLARIS) + /* OpenSolaris has a getifaddr() call, but it does not return AF_LINK */ sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { @@ -3661,71 +3656,43 @@ get_default_gateway(struct route_gateway_info *rgi, openvpn_net_ctx_t *ctx) goto done; } - ifc.ifc_len = bufsize; - ifc.ifc_buf = buffer; + struct ifreq ifreq = { 0 }; + + /* now get the hardware address. */ + strncpynt(ifreq.ifr_name, rgi->iface, sizeof(ifreq.ifr_name)); + if (ioctl(sockfd, SIOCGIFHWADDR, &ifreq) < 0) + { + msg(M_WARN, "GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name); + } + else + { + memcpy(rgi->hwaddr, &ifreq.ifr_addr.sa_data, 6); + rgi->flags |= RGI_HWADDR_DEFINED; + } +#else /* if defined(TARGET_SOLARIS) */ + struct ifaddrs *ifap, *ifa; - if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0) + if (getifaddrs(&ifap) != 0) { - msg(M_WARN, "GDG: ioctl #2 failed"); + msg(M_WARN|M_ERRNO, "GDG: getifaddrs() failed"); goto done; } - close(sockfd); - sockfd = -1; - for (cp = buffer; cp <= buffer + ifc.ifc_len - sizeof(struct ifreq); ) + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - struct ifreq ifr = { 0 }; - /* this is not always using an 8 byte alignment that struct ifr - * requires. Need to memcpy() to a strict ifr to force 8-byte - * alignment required for member access */ - memcpy(&ifr, cp, sizeof(struct ifreq)); - const size_t len = sizeof(ifr.ifr_name) + max(sizeof(ifr.ifr_addr), ifr.ifr_addr.sa_len); - - if (!ifr.ifr_addr.sa_family) - { - break; - } - if (!strncmp(ifr.ifr_name, rgi->iface, IFNAMSIZ)) + if (ifa->ifa_addr != NULL + && ifa->ifa_addr->sa_family == AF_LINK + && !strncmp(ifa->ifa_name, rgi->iface, IFNAMSIZ) ) { - if (ifr.ifr_addr.sa_family == AF_LINK) - { - /* This is a confusing member access on multiple levels. - * - * struct sockaddr_dl is 20 bytes (on macOS and NetBSD, - * larger on other BSDs) in size and has - * 12 bytes space for the Ethernet interface name - * (max 16 bytes) and hw address (6 bytes) - * - * So if the interface name is more than 6 byte, the - * location of hwaddr extends beyond the struct. - * - * This struct is embedded into ifreq that has - * 16 bytes for a sockaddr and also expects this - * struct to potentially extend beyond the bounds of - * the struct. - * - * We only copied 32 bytes (size of ifr at least on macOS - * might differ on other platforms again) from cp to ifr. - * - * But as hwaddr might extend but sdl might extend beyond - * ifr's. So we need recalculate how large the actual size - * of the embedded dl_sock actually is and then also need - * to copy it since it also most likely does not have the - * proper alignment required to access the struct. - */ - const size_t sock_dl_len = max_int((int) (sizeof(struct sockaddr_dl)), - (int) (ifr.ifr_addr.sa_len)); - - struct sockaddr_dl *sdl = gc_malloc(sock_dl_len, true, &gc); - memcpy(sdl, cp + offsetof(struct ifreq, ifr_addr), sock_dl_len); - memcpy(rgi->hwaddr, LLADDR(sdl), 6); - rgi->flags |= RGI_HWADDR_DEFINED; - } + struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr; + memcpy(rgi->hwaddr, LLADDR(sdl), 6); + rgi->flags |= RGI_HWADDR_DEFINED; } - cp += len; } + + freeifaddrs(ifap); +#endif /* if defined(TARGET_SOLARIS) */ } -#endif /* if !defined(TARGET_SOLARIS) */ done: if (sockfd >= 0)