From patchwork Wed Mar 10 01:48:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 1614 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.28.255.1]) by backend30.mail.ord1d.rsapps.net with LMTP id 0E12G2TASGDFWQAAIUCqbw (envelope-from ) for ; Wed, 10 Mar 2021 07:49:40 -0500 Received: from proxy9.mail.ord1c.rsapps.net ([172.28.255.1]) by director8.mail.ord1d.rsapps.net with LMTP id QDJAG2TASGAFTQAAfY0hYg (envelope-from ) for ; Wed, 10 Mar 2021 07:49:40 -0500 Received: from smtp39.gate.ord1c ([172.28.255.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy9.mail.ord1c.rsapps.net with LMTPS id 2Pj/GmTASGB3AwAAgxtkuw (envelope-from ) for ; Wed, 10 Mar 2021 07:49:40 -0500 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: smtp39.gate.ord1c.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; dmarc=none (p=nil; dis=none) header.from=greenie.muc.de X-Suspicious-Flag: YES X-Classification-ID: 13845a32-819f-11eb-9e7f-5452006c005a-1-1 Received: from [216.105.38.7] ([216.105.38.7:60178] helo=lists.sourceforge.net) by smtp39.gate.ord1c.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id E9/96-08570-360C8406; Wed, 10 Mar 2021 07:49:39 -0500 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.90_1) (envelope-from ) id 1lJyGP-00062b-Sq; Wed, 10 Mar 2021 12:48:33 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lJyGO-00062Q-BQ for openvpn-devel@lists.sourceforge.net; Wed, 10 Mar 2021 12:48:32 +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:References: In-Reply-To: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:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=92LOCKfFiRDh3+0aWJNgiSowzHHDmaN25nVFogTFYDk=; b=Ot61ZVLXAmSe324gp+FtvLtxES nYS/HTFXOrryMr1qR52C+s294QD0scatMnhUmydEgI9PA21DAVrrJEoabMaC3I1uatlmAuj8omM1P VrE6FB6nQWQvfOZbsnfOY+DI07WPJBxv5+UO+nk8qtcYOgt3FyHRn6yPWzmJX9tR1VlE=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: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:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=92LOCKfFiRDh3+0aWJNgiSowzHHDmaN25nVFogTFYDk=; b=FcjTzqvAPD7/x8JXTl2hMGmBrQ dR4QSfC8e1EVo9cG3QI1yPAMyQwUu+wqCnGBGnSy8zcXzOo7kZqc6bXdg5NuojFS9kvHxapa+V3av ARuepvMJmIe6JqF0wSPxv0Grjx0bLmlNxtkT8mmB4qYJYjFktIDOApbJ72/j9159ceds=; Received: from dhcp-174.greenie.muc.de ([193.149.48.174] helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) id 1lJyGB-0007Hu-Fr for openvpn-devel@lists.sourceforge.net; Wed, 10 Mar 2021 12:48:30 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.15.2/8.14.9) with ESMTP id 12ACm9WE014794 for ; Wed, 10 Mar 2021 13:48:09 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.15.2/8.14.9/Submit) id 12ACm9Ur014793 for openvpn-devel@lists.sourceforge.net; Wed, 10 Mar 2021 13:48:09 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Wed, 10 Mar 2021 13:48:08 +0100 Message-Id: <20210310124808.14741-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308071023.18269-1-gert@greenie.muc.de> References: <20210308071023.18269-1-gert@greenie.muc.de> MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: configure.ac] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1lJyGB-0007Hu-Fr Subject: [Openvpn-devel] [PATCH v3] Require at least 100MB of mlock()-able memory if --mlock is used. 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 If --mlock is used, the amount of memory OpenVPN can use is guarded by the RLIMIT_MEMLOCK value (see mlockall(2)). The OS default for this is usually 64 Kbyte, which is enough for OpenVPN to initialize, but as soon as the first TLS handshake comes it, OpenVPN will crash due to "ouf of memory", and might even end up in a crash loop. Steady-state OpenVPN requires between 8 MB and 30-50 MB (servers with many concurrent clients) of memory. TLS renegotiation with EC keys requires up to 90 MB of transient memory. So: with this patch, we check if getrlimit() is available, and if yes, log the amount of mlock'able memory. If the amount is below 100 MB, which is an arbitrary value "large enough for most smaller deployments", we try to increase the limits to 100 MB, and abort if this fails. v2: change arbitrary number to 100 MB, introduce #define for it not only check but also increase with setrlimit() uncrustify fixes v3: OpenSolaris has mlockall() and getrlimit(), but no RLIMIT_MEMLOCK - make code conditional on HAVE_GETRLIMIT *and* RLIMIT_MEMLOCK add Changes.rst entry Trac: #1390 Signed-off-by: Gert Doering --- Changes.rst | 5 +++++ configure.ac | 2 +- doc/man-sections/generic-options.rst | 7 +++++++ src/openvpn/platform.c | 29 ++++++++++++++++++++++++++++ src/openvpn/platform.h | 4 ++++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/Changes.rst b/Changes.rst index 62008e8d..d6be1050 100644 --- a/Changes.rst +++ b/Changes.rst @@ -15,6 +15,11 @@ Compatibility with OpenSSL in FIPS mode requirements/recommendation of FIPS 140-2. This just allows OpenVPN to be run on a system that be configured OpenSSL in FIPS mode. +``mlock`` will now check if enough memlock-able memory has been reserved, + and if less than 100MB RAM are available, use setrlimit() to upgrade + the limit. See Trac #1390. Not available on OpenSolaris. + + Deprecated features ------------------- ``inetd`` has been removed diff --git a/configure.ac b/configure.ac index 1ab8fe59..c65df3e2 100644 --- a/configure.ac +++ b/configure.ac @@ -645,7 +645,7 @@ AC_FUNC_FORK AC_CHECK_FUNCS([ \ daemon chroot getpwnam setuid nice system getpid dup dup2 \ - getpass syslog openlog mlockall getgrnam setgid \ + getpass syslog openlog mlockall getrlimit getgrnam setgid \ setgroups stat flock readv writev time gettimeofday \ ctime memset vsnprintf strdup \ setsid chdir putenv getpeername unlink \ diff --git a/doc/man-sections/generic-options.rst b/doc/man-sections/generic-options.rst index d5f08839..c026529e 100644 --- a/doc/man-sections/generic-options.rst +++ b/doc/man-sections/generic-options.rst @@ -237,6 +237,13 @@ which mode OpenVPN is configured as. likely fail. The limit can be increased using ulimit or systemd directives depending on how OpenVPN is started. + If the platform has the getrlimit(2) system call, OpenVPN will check + for the amount of mlock-able memory before calling mlockall(2), and + tries to increase the limit to 100 MB if less than this is configured. + 100 Mb is somewhat arbitrary - it is enough for a moderately-sized + OpenVPN deployment, but the memory usage might go beyond that if the + number of concurrent clients is high. + --nice n Change process priority after initialization (``n`` greater than 0 is lower priority, ``n`` less than zero is higher priority). diff --git a/src/openvpn/platform.c b/src/openvpn/platform.c index ef688c23..3bf95f84 100644 --- a/src/openvpn/platform.c +++ b/src/openvpn/platform.c @@ -193,6 +193,35 @@ void platform_mlockall(bool print_msg) { #ifdef HAVE_MLOCKALL + +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_MEMLOCK) +#define MIN_LOCKED_MEM_MB 100 + struct rlimit rl; + if (getrlimit(RLIMIT_MEMLOCK, &rl) < 0) + { + msg(M_WARN | M_ERRNO, "WARNING: getrlimit(RLIMIT_MEMLOCK) failed"); + } + else + { + msg(M_INFO, "mlock: MEMLOCK limit: soft=%ld KB, hard=%ld KB", + ((long int) rl.rlim_cur) / 1024, ((long int) rl.rlim_max) / 1024); + if (rl.rlim_cur < MIN_LOCKED_MEM_MB*1024*1024) + { + msg(M_INFO, "mlock: RLIMIT_MEMLOCK < %d MB, increase limit", + MIN_LOCKED_MEM_MB); + rl.rlim_cur = MIN_LOCKED_MEM_MB*1024*1024; + if (rl.rlim_max < rl.rlim_cur) + { + rl.rlim_max = rl.rlim_cur; + } + if (setrlimit(RLIMIT_MEMLOCK, &rl) < 0) + { + msg(M_FATAL | M_ERRNO, "ERROR: setrlimit() failed"); + } + } + } +#endif + if (mlockall(MCL_CURRENT | MCL_FUTURE)) { msg(M_WARN | M_ERRNO, "WARNING: mlockall call failed"); diff --git a/src/openvpn/platform.h b/src/openvpn/platform.h index 01f3200c..02c23e38 100644 --- a/src/openvpn/platform.h +++ b/src/openvpn/platform.h @@ -48,6 +48,10 @@ #include #endif +#ifdef HAVE_GETRLIMIT +#include +#endif + #include "basic.h" #include "buffer.h"