From patchwork Tue May 3 23:13:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lev Stipakov X-Patchwork-Id: 2430 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director14.mail.ord1d.rsapps.net ([172.31.255.6]) by backend41.mail.ord1d.rsapps.net with LMTP id oFftFb9DcmKdFgAAqwncew (envelope-from ) for ; Wed, 04 May 2022 05:13:35 -0400 Received: from proxy15.mail.iad3b.rsapps.net ([172.31.255.6]) by director14.mail.ord1d.rsapps.net with LMTP id oLc7ML9DcmKWUwAAeJ7fFg (envelope-from ) for ; Wed, 04 May 2022 05:13:35 -0400 Received: from smtp4.gate.iad3b ([172.31.255.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy15.mail.iad3b.rsapps.net with LMTPS id uH+7Kr9DcmLGOQAAhyf7VQ (envelope-from ) for ; Wed, 04 May 2022 05:13:35 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp4.gate.iad3b.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=gmail.com; dmarc=fail (p=none; dis=none) header.from=gmail.com X-Suspicious-Flag: YES X-Classification-ID: 7987a682-cb8a-11ec-bd1a-525400789c6c-1-1 Received: from [216.105.38.7] ([216.105.38.7:48374] helo=lists.sourceforge.net) by smtp4.gate.iad3b.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id C9/37-26666-FB342726; Wed, 04 May 2022 05:13:35 -0400 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1nmB3h-0004xF-Dh; Wed, 04 May 2022 09:12:33 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1nmB3g-0004x9-P7 for openvpn-devel@lists.sourceforge.net; Wed, 04 May 2022 09:12:33 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: MIME-Version:Content-Type:Content-Transfer-Encoding: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=sGtefKMdTFuWTYR7j+H/Pux4bDPFyN+9GvmlAPstNTI=; b=knIoBV9zXLUnLlcTBD7N/FVvnH adXdYsQ9P5u5QTtqU5qOAYUzrrsGz1EZOIvK4ZEcaZ9CRIMYi2lXCjP9f19wslsNdAmeJabBlgSY1 QAIzXuU7KDDaSD0RLI2m2Dxdlx2jipZyAUCZYvUJ41E7Qcn0yZjm54sy3e0xXGfsyRWE=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:MIME-Version: Content-Type:Content-Transfer-Encoding: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=sGtefKMdTFuWTYR7j+H/Pux4bDPFyN+9GvmlAPstNTI=; b=kOZl77Dju2v2EN9CL1yORbmvCd /JHoMbRNeVZq2blLNHUeTXwxuFQbnIVs+yjNYO9Y19/YkEr8W6nwIEYIAfEdqqr2pSWrvLrv8+edo jHIubbnxCNx6ybc6qiAXsIw48OhkZ+KSJypne5ttPddEsKS/M9/zwX8j0kIwIDVH1+ro=; Received: from mail-wr1-f50.google.com ([209.85.221.50]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.94.2) id 1nmB3g-0006uZ-7g for openvpn-devel@lists.sourceforge.net; Wed, 04 May 2022 09:12:32 +0000 Received: by mail-wr1-f50.google.com with SMTP id t6so1121971wra.4 for ; Wed, 04 May 2022 02:12:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id; bh=sGtefKMdTFuWTYR7j+H/Pux4bDPFyN+9GvmlAPstNTI=; b=FMz85x0Vf0f8UZ1GIyzpA+s8I/CCVvs7fuGXr9DvDjxmOJYm/dJkz8dGNc8d7dHcqM uMriyreAukyegoN8zs+QTMGVILfjxIiaKxnfTYOqV+UwPAtgky8rYUGPsVDAUKBA+N0W IG2V9uxq7zv6sbEaESXRMmaGqQtjXXkAyMX5+NpbmihpDRIfhZG2twDMjA6FW42vlCLt 23bX1bFSMgkLRvrShnfQtaOnwtvifuJDhLELmbVFFji7DwNVc5wziNJf9kH5f3G37z3q uVhkpdww7hnOBmOeXWZ8h2BNeE5egmmeNagwaXRvPNmqRCoF45bGNKRec4k+iA0rDNER goSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=sGtefKMdTFuWTYR7j+H/Pux4bDPFyN+9GvmlAPstNTI=; b=KploIjFgpSoIRo3tdb+EorMdbWIVsUYw0NXalsvaw56nQ0TmpiZcm67azaLGOVsEdU PRkT8jnx7nNhtvGFpHpPDvl+CoUWqZo7AL+EarbFjivKOyf0H0nfzLSxYQfamRWdrnQ1 ZYi1uIRgg5yAj8QGo9qbc/k0Wdpv30czl97cEdfPolOLq1YFqHJVOxSN+FkKEU0jjydd 7FrEKBblOlUEqz8jN2nC43r8UbhgSXuqZpio7XidsIRftNU+tl7hhcauTbPxJ1HFB9RS xcb6VoczyyVvc0RW3JGDkzNYDC+af8f/AYsxYbOEkxj2XJVcl0MT0yNDZ0+9BHRuS/PT zUKQ== X-Gm-Message-State: AOAM533ZIKTxxJzFiHWAZXl+rsk1SgqiyVJgKkVl7u3oc3RJwj/mzcNv +HOWnIaOe5gFgdiUWoOdd39fnwez8HM= X-Google-Smtp-Source: ABdhPJwcvA2ji5ahDTBdwkKhduUJe3qXySmvviS39maaObm8BJDYD6bYkic4gw9w2IKudC1YLTETbQ== X-Received: by 2002:adf:fc52:0:b0:20a:e296:6e8a with SMTP id e18-20020adffc52000000b0020ae2966e8amr15246779wrs.432.1651655545323; Wed, 04 May 2022 02:12:25 -0700 (PDT) Received: from LAPTOP-4L3N7KFS.localdomain (nat2.panoulu.net. [185.38.2.2]) by smtp.gmail.com with ESMTPSA id n124-20020a1c2782000000b0039447beb28asm4209736wmn.23.2022.05.04.02.12.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 May 2022 02:12:24 -0700 (PDT) From: Lev Stipakov To: openvpn-devel@lists.sourceforge.net Date: Wed, 4 May 2022 12:13:05 +0300 Message-Id: <20220504091305.434-1-lstipakov@gmail.com> X-Mailer: git-send-email 2.17.1 X-Spam-Report: Spam detection software, running on the system "util-spamd-2.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: From: Lev Stipakov We use M_ERRNO flag in logging to display error code and error message. This has been broken on Windows, where we use error code from GetLastError() and error description from strerror(). strerror() e [...] Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.221.50 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [lstipakov[at]gmail.com] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.221.50 listed in wl.mailspike.net] -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1nmB3g-0006uZ-7g Subject: [Openvpn-devel] [PATCH release/2.5] Fix M_ERRNO behavior on Windows 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: , Cc: Lev Stipakov MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Lev Stipakov We use M_ERRNO flag in logging to display error code and error message. This has been broken on Windows, where we use error code from GetLastError() and error description from strerror(). strerror() expects C runtime error code, which is quite different from last error code from WinAPI call. As a result, we got incorrect error description. The ultimate fix would be introducing another flag for WinAPI errors, like M_WINERR and use either that or M_ERRNO depends on context. However, the change would be quite intrusive and in some cases it is hard to say which one to use without looking into internals. Instead we stick to M_ERRNO and in Windows case we first try to obtain error code from GetLastError() and if it returns ERROR_SUCCESS (which is 0), we assume that we have C runtime error and use errno. To get error description we use strerror_win32() with GetLastError() and strerror() with errno. strerror_win32() uses FormatMessage() internally, which is the right way to get WinAPI error description. Acked-by: Selva Nair --- This is a backport of patch acked for master (https://patchwork.openvpn.net/patch/2429/) with a conflict resolved in x_check_status() in error.c. src/openvpn/error.c | 32 +++++++++++++++++++++++++------- src/openvpn/error.h | 39 +++++++++++++++++++++++++++++---------- src/openvpn/forward.c | 9 ++++++++- src/openvpn/manage.c | 5 +++-- src/openvpn/platform.c | 2 +- src/openvpn/tun.h | 4 ++-- 6 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/openvpn/error.c b/src/openvpn/error.c index 54796d03..7fbda844 100644 --- a/src/openvpn/error.c +++ b/src/openvpn/error.c @@ -220,6 +220,18 @@ x_msg(const unsigned int flags, const char *format, ...) va_end(arglist); } +static const char* +openvpn_strerror(int err, bool crt_error, struct gc_arena *gc) +{ +#ifdef _WIN32 + if (!crt_error) + { + return strerror_win32(err, gc); + } +#endif + return strerror(err); +} + void x_msg_va(const unsigned int flags, const char *format, va_list arglist) { @@ -244,7 +256,8 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist) } #endif - e = openvpn_errno(); + bool crt_error = false; + e = openvpn_errno_maybe_crt(&crt_error); /* * Apply muting filter. @@ -268,7 +281,7 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist) if ((flags & M_ERRNO) && e) { openvpn_snprintf(m2, ERR_BUF_SIZE, "%s: %s (errno=%d)", - m1, strerror(e), e); + m1, openvpn_strerror(e, crt_error, &gc), e); SWAP; } @@ -649,7 +662,6 @@ x_check_status(int status, struct link_socket *sock, struct tuntap *tt) { - const int my_errno = openvpn_errno(); const char *extended_msg = NULL; msg(x_cs_verbose_level, "%s %s returned %d", @@ -672,26 +684,32 @@ x_check_status(int status, sock->info.mtu_changed = true; } } -#elif defined(_WIN32) +#endif /* EXTENDED_SOCKET_ERROR_CAPABILITY */ + +#ifdef _WIN32 /* get possible driver error from TAP-Windows driver */ if (tuntap_defined(tt)) { extended_msg = tap_win_getinfo(tt, &gc); } #endif - if (!ignore_sys_error(my_errno)) + + bool crt_error = false; + int my_errno = openvpn_errno_maybe_crt(&crt_error); + + if (!ignore_sys_error(my_errno, crt_error)) { if (extended_msg) { msg(x_cs_info_level, "%s %s [%s]: %s (code=%d)", description, sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", - extended_msg, strerror(my_errno), my_errno); + extended_msg, openvpn_strerror(my_errno, crt_error, &gc), my_errno); } else { msg(x_cs_info_level, "%s %s: %s (code=%d)", description, sock ? proto2ascii(sock->info.proto, sock->info.af, true) : "", - strerror(my_errno), my_errno); + openvpn_strerror(my_errno, crt_error, &gc), my_errno); } if (x_cs_err_delay_ms) diff --git a/src/openvpn/error.h b/src/openvpn/error.h index d2d83c8a..fc878a56 100644 --- a/src/openvpn/error.h +++ b/src/openvpn/error.h @@ -71,13 +71,10 @@ struct gc_arena; /* String and Error functions */ #ifdef _WIN32 -#define openvpn_errno() GetLastError() -#define openvpn_strerror(e, gc) strerror_win32(e, gc) +#define openvpn_errno() GetLastError() const char *strerror_win32(DWORD errnum, struct gc_arena *gc); - #else -#define openvpn_errno() errno -#define openvpn_strerror(x, gc) strerror(x) +#define openvpn_errno() errno #endif /* @@ -363,20 +360,22 @@ msg_get_virtual_output(void) * which can be safely ignored. */ static inline bool -ignore_sys_error(const int err) +ignore_sys_error(const int err, bool crt_error) { - /* I/O operation pending */ #ifdef _WIN32 - if (err == WSAEWOULDBLOCK || err == WSAEINVAL) + if (!crt_error && ((err == WSAEWOULDBLOCK || err == WSAEINVAL))) { return true; } #else - if (err == EAGAIN) + crt_error = true; +#endif + + /* I/O operation pending */ + if (crt_error && (err == EAGAIN)) { return true; } -#endif #if 0 /* if enabled, suppress ENOBUFS errors */ #ifdef ENOBUFS @@ -398,6 +397,26 @@ nonfatal(const unsigned int err) return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err; } +static inline int +openvpn_errno_maybe_crt(bool *crt_error) +{ + int err = 0; + *crt_error = false; +#ifdef _WIN32 + err = GetLastError(); + if (err == ERROR_SUCCESS) + { + /* error is likely C runtime */ + *crt_error = true; + err = errno; + } +#else + *crt_error = true; + err = errno; +#endif + return err; +} + #include "errlevel.h" #endif /* ifndef ERROR_H */ diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 392a5c9f..de80dcff 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -1676,7 +1676,14 @@ process_outgoing_link(struct context *c) } /* for unreachable network and "connecting" state switch to the next host */ - if (size < 0 && ENETUNREACH == error_code && c->c2.tls_multi + + bool unreachable = error_code == +#ifdef _WIN32 + WSAENETUNREACH; +#else + ENETUNREACH; +#endif + if (size < 0 && unreachable && c->c2.tls_multi && !tls_initial_packet_received(c->c2.tls_multi) && c->options.mode == MODE_POINT_TO_POINT) { msg(M_INFO, "Network unreachable, restarting"); diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index a4264056..8d2d9983 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -2082,9 +2082,10 @@ man_process_command(struct management *man, const char *line) static bool man_io_error(struct management *man, const char *prefix) { - const int err = openvpn_errno(); + bool crt_error = false; + int err = openvpn_errno_maybe_crt(&crt_error); - if (!ignore_sys_error(err)) + if (!ignore_sys_error(err, crt_error)) { struct gc_arena gc = gc_new(); msg(D_MANAGEMENT, "MANAGEMENT: TCP %s error: %s", prefix, diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c index 2604c27b..4921f035 100644 --- a/src/openvpn/platform.c +++ b/src/openvpn/platform.c @@ -471,7 +471,7 @@ platform_test_file(const char *filename) } else { - if (openvpn_errno() == EACCES) + if (errno == EACCES) { msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename); } diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h index ea19620d..ae98966b 100644 --- a/src/openvpn/tun.h +++ b/src/openvpn/tun.h @@ -461,7 +461,7 @@ tuntap_stop(int status) */ if (status < 0) { - return openvpn_errno() == ERROR_FILE_NOT_FOUND; + return GetLastError() == ERROR_FILE_NOT_FOUND; } return false; } @@ -474,7 +474,7 @@ tuntap_abort(int status) */ if (status < 0) { - return openvpn_errno() == ERROR_OPERATION_ABORTED; + return GetLastError() == ERROR_OPERATION_ABORTED; } return false; }