From patchwork Thu Jan 12 17:02:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yann Droneaud X-Patchwork-Id: 42684 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp4021130wrt; Thu, 12 Jan 2023 09:56:00 -0800 (PST) X-Google-Smtp-Source: AMrXdXu2+NKMa98LIHiwJkjWs8RwCnFWu2KF0oHVoHqAnHgnRmK/zrot8HZHelcBERA5Hztwb5Yw X-Received: by 2002:a05:6402:528b:b0:499:b672:ee39 with SMTP id en11-20020a056402528b00b00499b672ee39mr13806916edb.11.1673546160260; Thu, 12 Jan 2023 09:56:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673546160; cv=none; d=google.com; s=arc-20160816; b=iF2X32i1CBpnHaDdhHGQNi1wQ8qc+kI28hjStmPlASsvCvAybw167+xjtlwjkqu+6/ Rm7ScBHdcSsuz3w5g4OGQ/9jayABZj7Cw8qleozz9yOT/VD73hn0HLrJD1siFoIBWBwq DqunnCbp40TyHNpsI/4Lr96QyyHfLRmxIopoIsTN475YUIwud+N3WeMNXHhNo6XuJ13a Po69l4HiPmJIj6hLMeHHKYy605fNzS9uLHsQUAIieHS90GQbAzH4nWxEgqQ2yIdvOc7u ktG7WAYZBmydVg2sLEr6ov3X7f7wB2Oui3apn+whEhaW0d7cO+ofxfyhMQwyzxLoYc0O +ueg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=3ZfikeYUdVx0FNVUbMiAr6Hcndu56cJCvatlL312VyM=; b=oDUlcbtGfhBXsoZ5makXgODahVkfpuMMIAzlDlWoK2GGXag9Xv4p4AqLb/bxVumDIC Ux6OBQ3aMKYRv7EyfjIYJHfHOtGKBhsMxfwGszxBFh5ouy4z7WVj4SfeSZIQf5m+uno9 lZM+b+CqmHGCwp062VewKxvNTD2a85Do3d4PVkS36LC/nnUxN3npBYpYlnF776S4xfsl wT0/TqD6JsIf5t3PsS4Yju6Ayr123UQjSYI+dIY5j6OB08LLCK1eoseq/aI5lzsG7j1d Ll/ehSCgYLjoqlOGXcrcaU6rRhdfI/YQUYJsSgCFuwAUijXV/877wQswLxDnsIIMYFzx 1Yjw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z15-20020a17090655cf00b007be53f03fa7si14654015ejp.211.2023.01.12.09.55.36; Thu, 12 Jan 2023 09:56:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232555AbjALRqF (ORCPT + 99 others); Thu, 12 Jan 2023 12:46:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237643AbjALRo7 (ORCPT ); Thu, 12 Jan 2023 12:44:59 -0500 Received: from smtp6-g21.free.fr (smtp6-g21.free.fr [IPv6:2a01:e0c:1:1599::15]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7760644378; Thu, 12 Jan 2023 09:03:57 -0800 (PST) Received: from localhost (unknown [IPv6:2a01:e35:39f2:1220:dc8b:b602:9bcd:3004]) by smtp6-g21.free.fr (Postfix) with ESMTPS id 87B7078036C; Thu, 12 Jan 2023 18:03:39 +0100 (CET) From: Yann Droneaud To: "Jason A. Donenfeld" , "Theodore Ts'o" Cc: Yann Droneaud , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Andy Lutomirski , Vincenzo Frascino , x86@kernel.org, linux-crypto@vger.kernel.org, linux-api@vger.kernel.org, linux-kernel@vger.kernel.org, Florian Weimer , Adhemerval Zanella Netto , "Carlos O'Donell" Subject: [RFC PATCH 2/4] random: introduce generic vDSO getrandom(,, GRND_TIMESTAMP) fast path Date: Thu, 12 Jan 2023 18:02:34 +0100 Message-Id: X-Mailer: git-send-email 2.37.2 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1754840338920001782?= X-GMAIL-MSGID: =?utf-8?q?1754840338920001782?= From: "Jason A. Donenfeld" Exports base_crng.generation to vDSO and adds getrandom() to the vDSO. Based on Jason A. Donenfeld patch [1] "[PATCH v14 6/7] random: introduce generic vDSO getrandom() implementation", but deal only with GRND_TIMESTAMP in vDSO: generating random stream is left to the getrandom() syscall. [1] https://lore.kernel.org/all/20230101162910.710293-7-Jason@zx2c4.com/ Link: https://lore.kernel.org/all/cover.1673539719.git.ydroneaud@opteya.com/ Signed-off-by: Yann Droneaud --- MAINTAINERS | 1 + drivers/char/random.c | 6 +++++ include/vdso/datapage.h | 9 ++++++++ lib/vdso/Kconfig | 5 ++++ lib/vdso/getrandom.c | 51 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 lib/vdso/getrandom.c diff --git a/MAINTAINERS b/MAINTAINERS index 7f86d02cb427..20e1fabcb2e9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17521,6 +17521,7 @@ T: git https://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git S: Maintained F: drivers/char/random.c F: drivers/virt/vmgenid.c +F: lib/vdso/getrandom.c RAPIDIO SUBSYSTEM M: Matt Porter diff --git a/drivers/char/random.c b/drivers/char/random.c index 9e2a37e432c0..a60f50c95ab1 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -56,6 +56,9 @@ #include #include #include +#ifdef CONFIG_VDSO_GETRANDOM +#include +#endif #include #include #include @@ -271,6 +274,9 @@ static void crng_reseed(struct work_struct *work) if (next_gen == ULONG_MAX) ++next_gen; WRITE_ONCE(base_crng.generation, next_gen); +#ifdef CONFIG_VDSO_GETRANDOM + smp_store_release(&_vdso_rng_data.generation, next_gen); +#endif if (!static_branch_likely(&crng_is_ready)) crng_init = CRNG_READY; spin_unlock_irqrestore(&base_crng.lock, flags); diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h index 73eb622e7663..7ae8e7ffe3ba 100644 --- a/include/vdso/datapage.h +++ b/include/vdso/datapage.h @@ -109,6 +109,14 @@ struct vdso_data { struct arch_vdso_data arch_data; }; +/** + * struct vdso_rng_data - vdso RNG state information + * @generation: counter representing the number of RNG reseeds + */ +struct vdso_rng_data { + u64 generation; +}; + /* * We use the hidden visibility to prevent the compiler from generating a GOT * relocation. Not only is going through a GOT useless (the entry couldn't and @@ -120,6 +128,7 @@ struct vdso_data { */ extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden"))); extern struct vdso_data _timens_data[CS_BASES] __attribute__((visibility("hidden"))); +extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden"))); /* * The generic vDSO implementation requires that gettimeofday.h diff --git a/lib/vdso/Kconfig b/lib/vdso/Kconfig index d883ac299508..3b394fa83f65 100644 --- a/lib/vdso/Kconfig +++ b/lib/vdso/Kconfig @@ -31,3 +31,8 @@ config GENERIC_VDSO_TIME_NS VDSO endif + +config VDSO_GETRANDOM + bool + help + Selected by architectures that support vDSO getrandom(). diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c new file mode 100644 index 000000000000..827351a87002 --- /dev/null +++ b/lib/vdso/getrandom.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Jason A. Donenfeld . All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include + +/** + * __cvdso_getrandom_data - Generic vDSO implementation of getrandom() syscall. + * @rng_info: Describes state of kernel RNG, memory shared with kernel. + * @buffer: Input/Output buffer. + * @len: Size of @buffer in bytes. + * @flags: Zero or more GRND_* flags. + */ +static __always_inline ssize_t +__cvdso_getrandom_data(const struct vdso_rng_data *rng_info, void *buffer, size_t len, + unsigned int flags) +{ + if (flags != GRND_TIMESTAMP) + goto fallback; + + if (unlikely(!buffer)) + goto fallback; + + /* want aligned access */ + if (unlikely(!IS_ALIGNED((uintptr_t)buffer, __alignof__(u64)))) + goto fallback; + + if (unlikely(len != sizeof(u64))) + goto fallback; + + if (!get_random_timestamp_update((u64 *)buffer, + READ_ONCE(rng_info->generation))) + return 0; + + return sizeof(u64); + +fallback: + return getrandom_syscall(buffer, len, flags); +} + +static __always_inline ssize_t +__cvdso_getrandom(void *buffer, size_t len, unsigned int flags) +{ + return __cvdso_getrandom_data(__arch_get_vdso_rng_data(), buffer, len, flags); +}