From patchwork Fri Mar 15 12:28:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Petr_=C5=A0tetiar?= X-Patchwork-Id: 1056981 X-Patchwork-Delegate: ynezz@true.cz Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.openwrt.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=true.cz Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="IpIAI8/C"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44LPyj3xCpz9s3l for ; Fri, 15 Mar 2019 23:29:16 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Subject:MIME-Version:Message-Id:Date:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=IgGWLp/13Q0R4scVZAp5/Ej4l3bB1O4jcX5OF0fHvfM=; b=IpIAI8/CViWCO3 c1uBWgSlu2za48uQc7TMDQCPcYzzDWPfu4Rga71BU28eX2mxo7dyw0qJYAcEfGF1JkcYnUnmYpdvW dIB6wSHqROwlsG4psw8qYjj6uV0x5gK2AnkQHyuqWzB1YzqZYLM+XxNMgNAWm8R1qOSWZeURefi0b KBvIPIQPKi5hyMhQ+p98AnOWX7YsA/7DY6L73Dzus8vVBeK7QsnV1AowdbtMJcPCy4HVTNXjw6E/E dUjjZ3LmPxXxfSrAlQ5xseoni611LaQDZom1NWbIV6FgE4TnANX1P7OUicpkcgNCrwG/j4T8Q5Ckq nRQ54O/j8V4JmgPVExeA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1h4lxK-0006KL-4D; Fri, 15 Mar 2019 12:28:58 +0000 Received: from smtp-out.xnet.cz ([178.217.244.18]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1h4lxD-0006Jd-Q3 for openwrt-devel@lists.openwrt.org; Fri, 15 Mar 2019 12:28:54 +0000 Received: from meh.true.cz (meh.true.cz [108.61.167.218]) (Authenticated sender: petr@true.cz) by smtp-out.xnet.cz (Postfix) with ESMTPSA id E7CD437B1; Fri, 15 Mar 2019 13:28:46 +0100 (CET) Received: by meh.true.cz (OpenSMTPD) with ESMTP id df0f1412; Fri, 15 Mar 2019 13:28:44 +0100 (CET) From: =?utf-8?q?Petr_=C5=A0tetiar?= To: openwrt-devel@lists.openwrt.org Date: Fri, 15 Mar 2019 13:28:39 +0100 Message-Id: <1552652920-10686-1-git-send-email-ynezz@true.cz> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190315_052851_998286_66F8B547 X-CRM114-Status: GOOD ( 18.36 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [178.217.244.18 listed in list.dnswl.org] Subject: [OpenWrt-Devel] [PATCH] openssl: Fix longer booting times by unblocking getrandom X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Petr_=C5=A0tetiar?= Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org While testing simple firmware image for x86/64 in QEMU I've discovered some weird behavior today. This image contains simple package with simple init script to bootstrap the device UCI configuration from network server. This init script uses uclient-fetch and libustream-openssl. This image was booting fine until today, usually finished booting under 10s, but today it was booting much slowly, boot times were in range from 60s to a few minutes. I was also unable to power off the QEMU with poweroff command. I've found out, that it's all happening because of uclient-fetch being blocked in getrandom syscall, leading for example to following: root@OpenWrt:~# time uclient-fetch ^CCommand terminated by signal 2 real 8m 31.08s The problem passes away after `random: crng init done` hits the system log, but this step can take ages in some cases (usually when there are more processes calling getrandom in parallel), but I couldn't get it under 60s on my QEMU machine. I've similar weird reports from users on MIPS devices as well. [ 13.786576] random: fast init done ... [ 653.153740] random: crng init done I've bisected the problem down to the following commit (reverting it fixed the problem): # first bad commit: [d872d00b2f] openssl: update to version 1.1.1a So this patch tries to fix this issue by making getrandom syscall nonblocking, and also removes possible usage of getentropy libc call, which in case of musl libc results again in use of getrandom syscall in blocking mode. I've also added new config option just in case someone would prefer to have probably safer but much slower boot times on some devices. Fixes: d872d00b2f ("openssl: update to version 1.1.1a") Reviewed-by: Eneas U de Queiroz Signed-off-by: Petr Štetiar --- package/libs/openssl/Config.in | 12 ++++++ package/libs/openssl/Makefile | 7 +++- .../openssl/patches/150-unblock-getrandom.patch | 45 ++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 package/libs/openssl/patches/150-unblock-getrandom.patch diff --git a/package/libs/openssl/Config.in b/package/libs/openssl/Config.in index ecb9eea..0809afa 100644 --- a/package/libs/openssl/Config.in +++ b/package/libs/openssl/Config.in @@ -70,6 +70,18 @@ config OPENSSL_WITH_ERROR_MESSAGES This option aids debugging, but increases package size and memory usage. +config OPENSSL_BLOCKING_GETRANDOM + bool + prompt "Enable back getrandom in blocking mode" + help + Enable back the default (upstream) blocking behavior. By default, when + reading from the random source, getrandom() blocks if no random bytes are + available, and when reading from the urandom source, it blocks if the entropy + pool has not yet been initialized. + + Please note, that turning this option on may affect the boot time, which can + in some cases take minutes. + comment "Protocol Support" config OPENSSL_WITH_TLS13 diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index 56e95af..6e7a603 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -11,7 +11,7 @@ PKG_NAME:=openssl PKG_BASE:=1.1.1 PKG_BUGFIX:=b PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX) -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_USE_MIPS16:=0 ENGINES_DIR=engines-1.1 @@ -30,6 +30,7 @@ PKG_LICENSE:=OpenSSL PKG_LICENSE_FILES:=LICENSE PKG_CPE_ID:=cpe:/a:openssl:openssl PKG_CONFIG_DEPENDS:= \ + CONFIG_OPENSSL_BLOCKING_GETRANDOM \ CONFIG_OPENSSL_ENGINE \ CONFIG_OPENSSL_ENGINE_BUILTIN \ CONFIG_OPENSSL_ENGINE_BUILTIN_AFALG \ @@ -327,6 +328,10 @@ ifdef CONFIG_i386 endif endif +ifdef CONFIG_OPENSSL_BLOCKING_GETRANDOM + OPENSSL_OPTIONS += -DOPENSSL_BLOCKING_GETRANDOM +endif + OPENSSL_TARGET:=linux-$(call qstrip,$(CONFIG_ARCH))-openwrt STAMP_CONFIGURED := $(STAMP_CONFIGURED)_$(shell echo $(OPENSSL_OPTIONS) | mkhash md5) diff --git a/package/libs/openssl/patches/150-unblock-getrandom.patch b/package/libs/openssl/patches/150-unblock-getrandom.patch new file mode 100644 index 0000000..f74abaa --- /dev/null +++ b/package/libs/openssl/patches/150-unblock-getrandom.patch @@ -0,0 +1,45 @@ +--- a/crypto/rand/rand_unix.c ++++ b/crypto/rand/rand_unix.c +@@ -20,6 +20,7 @@ + #include "internal/dso.h" + #if defined(__linux) + # include ++# include + #endif + #if defined(__FreeBSD__) + # include +@@ -292,7 +293,8 @@ static ssize_t syscall_random(void *buf, + */ + + /* +- * Do runtime detection to find getentropy(). ++ * Do runtime detection to find getentropy(). Please note, that at least ++ * on musl libc (version 1.2.21) getentropy() uses getrandom() in blocking mode. + * + * Known OSs that should support this: + * - Darwin since 16 (OSX 10.12, IOS 10.0). +@@ -301,6 +303,7 @@ static ssize_t syscall_random(void *buf, + * - Linux since 3.17 with glibc 2.25 + * - FreeBSD since 12.0 (1200061) + */ ++# if defined(OPENSSL_BLOCKING_GETRANDOM) + # if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) + extern int getentropy(void *buffer, size_t length) __attribute__((weak)); + +@@ -322,10 +325,15 @@ static ssize_t syscall_random(void *buf, + if (p_getentropy.p != NULL) + return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1; + # endif ++# endif /* defined(OPENSSL_BLOCKING_GETRANDOM) */ + + /* Linux supports this since version 3.17 */ + # if defined(__linux) && defined(SYS_getrandom) +- return syscall(SYS_getrandom, buf, buflen, 0); ++ unsigned int flags = 0; ++# if !defined(OPENSSL_BLOCKING_GETRANDOM) ++ flags = GRND_NONBLOCK; ++# endif ++ return syscall(SYS_getrandom, buf, buflen, flags); + # elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND) + return sysctl_random(buf, buflen); + # else