From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A719C4320A for ; Fri, 20 Aug 2021 04:34:38 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id E2B8860F58 for ; Fri, 20 Aug 2021 04:34:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E2B8860F58 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=pwning.systems Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id E4FB46B0071; Fri, 20 Aug 2021 00:34:36 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id DFF756B0072; Fri, 20 Aug 2021 00:34:36 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D151B8D0001; Fri, 20 Aug 2021 00:34:36 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0237.hostedemail.com [216.40.44.237]) by kanga.kvack.org (Postfix) with ESMTP id B48EC6B0071 for ; Fri, 20 Aug 2021 00:34:36 -0400 (EDT) Received: from smtpin17.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with ESMTP id 5B0F81848CB8F for ; Fri, 20 Aug 2021 04:34:36 +0000 (UTC) X-FDA: 78494192952.17.F4155FC Received: from MTA-12-4.privateemail.com (mta-12-4.privateemail.com [198.54.127.107]) by imf06.hostedemail.com (Postfix) with ESMTP id C9996801A89C for ; Fri, 20 Aug 2021 04:34:35 +0000 (UTC) Received: from mta-12.privateemail.com (localhost [127.0.0.1]) by mta-12.privateemail.com (Postfix) with ESMTP id 57B3418000B2; Fri, 20 Aug 2021 00:34:33 -0400 (EDT) Received: from localhost.localdomain (unknown [10.20.151.223]) by mta-12.privateemail.com (Postfix) with ESMTPA id 0EA4B18000B0; Fri, 20 Aug 2021 00:34:31 -0400 (EDT) From: Jordy Zomer To: linux-kernel@vger.kernel.org Cc: Kees Cook , Jordy Zomer , Andrew Morton , linux-mm@kvack.org Subject: [PATCH] mm/secretmem: use refcount_t instead of atomic_t Date: Fri, 20 Aug 2021 06:33:38 +0200 Message-Id: <20210820043339.2151352-1-jordy@pwning.systems> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Authentication-Results: imf06.hostedemail.com; dkim=none; dmarc=none; spf=none (imf06.hostedemail.com: domain of jordy@pwning.systems has no SPF policy when checking 198.54.127.107) smtp.mailfrom=jordy@pwning.systems X-Stat-Signature: xwhpacpedwhmp7xyjn6gotjd5h7u3yig X-Rspamd-Queue-Id: C9996801A89C X-Rspamd-Server: rspam01 X-HE-Tag: 1629434075-981547 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: When a secret memory region is active, memfd_secret disables hibernation. One of the goals is to keep the secret data from being written to persistent-storage. It accomplishes this by maintaining a reference count to `secretmem_users`. Once this reference is held your system can not be hibernated due to the check in `hibernation_available()`. However, because `secretmem_users` is of type `atomic_t`, reference counter overflows are possible. As you can see there's an `atomic_inc` for each `memfd` that is opened in the `memfd_secret` syscall. If a local attacker succeeds to open 2^32 memfd's, the counter will wrap around to 0. This implies that you may hibernate again, even though there are still regions of this secret memory, thereby bypassing the security check. In an attempt to fix this I have used `refcount_t` instead of `atomic_t` which prevents reference counter overflows. Signed-off-by: Jordy Zomer --- mm/secretmem.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/secretmem.c b/mm/secretmem.c index 030f02ddc7c1..1fea68b8d5a6 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -18,6 +18,7 @@ #include #include #include +#include =20 #include =20 @@ -40,11 +41,11 @@ module_param_named(enable, secretmem_enable, bool, 04= 00); MODULE_PARM_DESC(secretmem_enable, "Enable secretmem and memfd_secret(2) system call"); =20 -static atomic_t secretmem_users; +static refcount_t secretmem_users; =20 bool secretmem_active(void) { - return !!atomic_read(&secretmem_users); + return !!refcount_read(&secretmem_users); } =20 static vm_fault_t secretmem_fault(struct vm_fault *vmf) @@ -103,7 +104,7 @@ static const struct vm_operations_struct secretmem_vm= _ops =3D { =20 static int secretmem_release(struct inode *inode, struct file *file) { - atomic_dec(&secretmem_users); + refcount_dec(&secretmem_users); return 0; } =20 @@ -217,7 +218,7 @@ SYSCALL_DEFINE1(memfd_secret, unsigned int, flags) file->f_flags |=3D O_LARGEFILE; =20 fd_install(fd, file); - atomic_inc(&secretmem_users); + refcount_inc(&secretmem_users); return fd; =20 err_put_fd: --=20 2.27.0