Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp1133339pxb; Thu, 19 Aug 2021 21:36:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxT0zf48THrtLk3a65cmYF8YzbMWAaikCgIcVgKupx0KlnkRE+gYgLtMYj7fyMsmAF6tSal X-Received: by 2002:a17:907:7704:: with SMTP id kw4mr19077445ejc.23.1629434203386; Thu, 19 Aug 2021 21:36:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629434203; cv=none; d=google.com; s=arc-20160816; b=n5kHUGbks2OyzYTEaX/+t3TlX55owxEm03YXZi9hG2tyrPoZ+f4E4XbMd1fO9f5EZj 5xBW9SVcMWWAn/aPLLK9dLKxbm1rNNjlhkMBKfc0DBczws+a8s3TIKbMS0PmcY/X3KN8 Y/R54rmMLkgmlfGjr4dyGZ0eUdIGw7FHQkzuiEC5tboDR1sbrqsr0s8QI3tN5c6voyvB m5nMXmH3+j4B5OKt8Dl7dZLQeGvrHxlDSsvsJLhT4LZJNEzM8tPdh/hBXUfxl3eX83UE YxmM+6xC0HzK46ps8Reaf8bZi6UPg4m0Yu6ikr8+5FJ7W4N1dvo0Bt9bp8o/Ibs6Zacx CG9w== 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 :message-id:date:subject:cc:to:from; bh=/47xz1JBvb7hBVCaFFbSHYQ6MGzHIscg2Gehfxc7VrE=; b=Wuthx0n0m74yRsbZsW/Am8LnZ1yaJSMsn2+joDqIjfSv6SKyZCGYViCuoDy1wgWzTw Ezf+PvzF5CEkM7kFzjSd3sRATnZWCmNKtFU6RbXfFdi5ITDSZC80IUJrYmTKqC78vml/ V6DISFk7UlyjkQXkenKlVSzfN7lQlZ575Lsv/PN5KNOA+fbesaCJ8Ryhp0okMtYT+p46 31zSZQlzBrwlL8m6VS1s4HMpaqKa9HOrtlJC9Gk/4mAoY3W48LRb6q7C0A5Oe/T8+zru bSQ31SZYgCZnQf73HTqhygU/Al90maP5p9RUnDPulxLlpI7lRUdbZHhpK59Z35pAgiBK ZVkA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b9si5415191ejd.404.2021.08.19.21.36.20; Thu, 19 Aug 2021 21:36:43 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230007AbhHTEfM (ORCPT + 99 others); Fri, 20 Aug 2021 00:35:12 -0400 Received: from h4.fbrelay.privateemail.com ([131.153.2.45]:41419 "EHLO h4.fbrelay.privateemail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229457AbhHTEfM (ORCPT ); Fri, 20 Aug 2021 00:35:12 -0400 Received: from MTA-12-4.privateemail.com (mta-12-1.privateemail.com [198.54.122.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by h3.fbrelay.privateemail.com (Postfix) with ESMTPS id 4E1C7800C0 for ; Fri, 20 Aug 2021 00:34:34 -0400 (EDT) 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 Content-Transfer-Encoding: 8bit X-Virus-Scanned: ClamAV using ClamSMTP Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 #include @@ -40,11 +41,11 @@ module_param_named(enable, secretmem_enable, bool, 0400); MODULE_PARM_DESC(secretmem_enable, "Enable secretmem and memfd_secret(2) system call"); -static atomic_t secretmem_users; +static refcount_t secretmem_users; bool secretmem_active(void) { - return !!atomic_read(&secretmem_users); + return !!refcount_read(&secretmem_users); } static vm_fault_t secretmem_fault(struct vm_fault *vmf) @@ -103,7 +104,7 @@ static const struct vm_operations_struct secretmem_vm_ops = { static int secretmem_release(struct inode *inode, struct file *file) { - atomic_dec(&secretmem_users); + refcount_dec(&secretmem_users); return 0; } @@ -217,7 +218,7 @@ SYSCALL_DEFINE1(memfd_secret, unsigned int, flags) file->f_flags |= O_LARGEFILE; fd_install(fd, file); - atomic_inc(&secretmem_users); + refcount_inc(&secretmem_users); return fd; err_put_fd: -- 2.27.0