From nobody Sat Apr 20 04:23:03 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 50C94C25B0D for ; Fri, 5 Aug 2022 22:22:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241812AbiHEWV7 (ORCPT ); Fri, 5 Aug 2022 18:21:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36326 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241818AbiHEWVu (ORCPT ); Fri, 5 Aug 2022 18:21:50 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3994C1CB1B for ; Fri, 5 Aug 2022 15:21:49 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id j11-20020a05690212cb00b006454988d225so3152361ybu.10 for ; Fri, 05 Aug 2022 15:21:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=mbnTnCyzBrPsZ2cIyy/polFSFcHi5iA+y2wZHy5S50g=; b=O1tv2Chuzvi0NDU6zf4N/Fshq6yGCqiuDTuun/edjoU5VnoWU6HlwRqRq214Cym4mz noFPwUsXvo0SYNfeNEjWoXIVZcign3gEgsFpITz4QnZrbGOtKfeY+cDS9TK5falMgCNI DJ6xcL5LbkGOVjDMSML6SM3jRDsvX6GsPMXFLvFKSYD1BtYOfgnhaOBaYbe12JSlISWh zKPVACct5OHq40PuoLQGZTx+YFMcXX1RgsGmCiYPiEbumgKzZ847z4pJf7UeYvrXqLcR FAIEKIHGSOX0P4KPT7WoPV95vsdEH3BO4vgVQ2JI3EeE9rV4Ph0MSuemj+SCfQWNltzS 3OGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=mbnTnCyzBrPsZ2cIyy/polFSFcHi5iA+y2wZHy5S50g=; b=5wYBSxWmcS890kbBm70mdtag84TBFm+rWqFkoVlfT4Z137hbmjz/OFcsU6KCFHcuD4 bzQlVBx8XVX2f33ZEZfI0rzD14Z6gF4r3vI9AcWRJGzEkrv0bfIQLBQih0j20uEI5pVo hF80cUMLeovOsaqmPCzi1J7Ifd34RgbXvy9Rn8YIMoFsu+bApc3lrZ4xDYCzhocLJnEI 6JU7eKrHN6QwLS3S9VK2wfNK2MJNXbYGsn+YUwGgqSRuQCqffqB3C+81z5EiTqLdL/rt GaXAF0sAh2pp5BmQXbrfMOV80OLBtLWf6S5Hp80rwCtz/wSbQ+c8md/p7G/sl2UYz9TN 1fDg== X-Gm-Message-State: ACgBeo3DKsxt3JY2CDOl92YMgkR8oSEo5oTy5qdlAkgDDaf3UevggY+F BAzOl6dxe8aIdMsQTQOTnoeEwNYPJFg= X-Google-Smtp-Source: AA6agR6sCneuMkIn8ODRd5RHoaPnFVjTcuaTHnQMf3gsH0n2vQfppBnVbsN+vr+g2fHjPeLdvPi2NkEA0yQ= X-Received: from jeffxud.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:e37]) (user=jeffxu job=sendgmr) by 2002:a05:6902:723:b0:677:115b:553c with SMTP id l3-20020a056902072300b00677115b553cmr7776175ybt.214.1659738108553; Fri, 05 Aug 2022 15:21:48 -0700 (PDT) Date: Fri, 5 Aug 2022 22:21:22 +0000 In-Reply-To: <20220805222126.142525-1-jeffxu@google.com> Message-Id: <20220805222126.142525-2-jeffxu@google.com> Mime-Version: 1.0 References: <20220805222126.142525-1-jeffxu@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v2 1/5] mm/memfd: add F_SEAL_EXEC From: To: skhan@linuxfoundation.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, keescook@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, mnissler@chromium.org, jannh@google.com, Jeff Xu Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Daniel Verkamp The new F_SEAL_EXEC flag will prevent modification of the exec bits: written as traditional octal mask, 0111, or as named flags, S_IXUSR | S_IXGRP | S_IXOTH. Any chmod(2) or similar call that attempts to modify any of these bits after the seal is applied will fail with errno EPERM. This will preserve the execute bits as they are at the time of sealing, so the memfd will become either permanently executable or permanently un-executable. Co-developed-by: Jeff Xu Signed-off-by: Jeff Xu Signed-off-by: Daniel Verkamp --- include/uapi/linux/fcntl.h | 1 + mm/memfd.c | 2 ++ mm/shmem.c | 6 ++++++ 3 files changed, 9 insertions(+) diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index 2f86b2ad6d7e..a472ba69596c 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -43,6 +43,7 @@ #define F_SEAL_GROW 0x0004 /* prevent file from growing */ #define F_SEAL_WRITE 0x0008 /* prevent writes */ #define F_SEAL_FUTURE_WRITE 0x0010 /* prevent future writes while mapped = */ +#define F_SEAL_EXEC 0x0020 /* prevent chmod modifying exec bits */ /* (1U << 31) is reserved for signed error codes */ =20 /* diff --git a/mm/memfd.c b/mm/memfd.c index 08f5f8304746..4ebeab94aa74 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -147,6 +147,7 @@ static unsigned int *memfd_file_seals_ptr(struct file *= file) } =20 #define F_ALL_SEALS (F_SEAL_SEAL | \ + F_SEAL_EXEC | \ F_SEAL_SHRINK | \ F_SEAL_GROW | \ F_SEAL_WRITE | \ @@ -175,6 +176,7 @@ static int memfd_add_seals(struct file *file, unsigned = int seals) * SEAL_SHRINK: Prevent the file from shrinking * SEAL_GROW: Prevent the file from growing * SEAL_WRITE: Prevent write access to the file + * SEAL_EXEC: Prevent modification of the exec bits in the file mode * * As we don't require any trust relationship between two parties, we * must prevent seals from being removed. Therefore, sealing a file diff --git a/mm/shmem.c b/mm/shmem.c index e5e43b990fdc..bb530f562bdd 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1082,6 +1082,12 @@ static int shmem_setattr(struct user_namespace *mnt_= userns, if (error) return error; =20 + if ((info->seals & F_SEAL_EXEC) && (attr->ia_valid & ATTR_MODE)) { + if ((inode->i_mode ^ attr->ia_mode) & 0111) { + return -EPERM; + } + } + if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { loff_t oldsize =3D inode->i_size; loff_t newsize =3D attr->ia_size; --=20 2.37.1.559.g78731f0fdb-goog From nobody Sat Apr 20 04:23:03 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11329C25B08 for ; Fri, 5 Aug 2022 22:22:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241826AbiHEWWC (ORCPT ); Fri, 5 Aug 2022 18:22:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241730AbiHEWVw (ORCPT ); Fri, 5 Aug 2022 18:21:52 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B5C11CFD1 for ; Fri, 5 Aug 2022 15:21:51 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id s14-20020a5b044e000000b00672caf96368so3119629ybp.21 for ; Fri, 05 Aug 2022 15:21:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=5E4PGAWMReAFHkj0eA7xzWpJk8N5M4FgV4LT8CvMVPA=; b=TDuzZmP48qciezv1MXsf3LVuEa0sxCTwiXmz3GaFb6bY9Qtk1DrEr4hk/hgSUCSU9D AfNdO6ggJ2vgmMWeMOlX/leMgSXGcQVjNK0zYR0phfm+32xYcPAHGvQSYoqPiNbxudnk HvE2bkCtTLZ4+b3Ay+j53c5ejYOvr0jzKdc8h62ng9xyA/YGHmq7HQjrLzA1ZaYH+BV9 0FZ6JoFGedju30kgJTOIXqXWVdCHFjQ55uchR5QBZO9lhMl46oSxaKE6Z0a+P78bLdDl tNj+/17Hexg7tUbRBM+OCbb+sqB6gZJt9lxBqysd3REOSfOgCXMUXOEiZd1Awo0K8DSt 9wmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=5E4PGAWMReAFHkj0eA7xzWpJk8N5M4FgV4LT8CvMVPA=; b=vkSddsHy996CBN8ekXqt4p5n68JpjcfKNzxLfCtm5xCclqEV6vcxYUPD1DK9W32wQb 35o8+f+VH8/ALyoFYVrNtP5R1gm5ARRuGCIkwwtaFYEy4ZIUBx1KpVI9WtBHxuxh2OyD eEJviGm0Inzd18be4w3U5KvF6352cDzUiqC9mWc/x5Fgedl5yDGW5VlqQe0djwI95ttj 9xEW2xmcTQpod/Tb4uTgfyDSI72FIkth9jUAAYoMAMtRyq/pyUjzEbmxeObrr1pVJhs5 PcdtMt5BdoLIi/NsS7AWE/YL8E+BxagXBvT6/yK4NQVK6O95yppeBj3eX73ktcaFcz22 m+ag== X-Gm-Message-State: ACgBeo20dgyf+xsVcO5QA0T9Rxn2vjW8KxoLAHnIIHenskhkvZoUUQFT hF57S3HmHtmDiRMBIJ4nZElJx/FkZSc= X-Google-Smtp-Source: AA6agR55Nd+GF+Zicb9UzLXVsBAJG/nkDrQRMgHX77YRUR2vsXmmAEpB7Hc955x1MuY3F3Ah7dc0fEbCssM= X-Received: from jeffxud.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:e37]) (user=jeffxu job=sendgmr) by 2002:a25:9c87:0:b0:671:82fd:9106 with SMTP id y7-20020a259c87000000b0067182fd9106mr7167620ybo.546.1659738110679; Fri, 05 Aug 2022 15:21:50 -0700 (PDT) Date: Fri, 5 Aug 2022 22:21:23 +0000 In-Reply-To: <20220805222126.142525-1-jeffxu@google.com> Message-Id: <20220805222126.142525-3-jeffxu@google.com> Mime-Version: 1.0 References: <20220805222126.142525-1-jeffxu@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v2 2/5] mm/memfd: add MFD_NOEXEC flag to memfd_create From: To: skhan@linuxfoundation.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, keescook@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, mnissler@chromium.org, jannh@google.com, Jeff Xu Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Daniel Verkamp The new MFD_NOEXEC flag allows the creation of a permanently non-executable memfd. This is accomplished by creating it with a different set of file mode bits (0666) than the default (0777) and applying the F_SEAL_EXEC seal at creation time, so there is no window between memfd creation and seal application. Unfortunately, the default for memfd must remain executable, since changing this would be an API break, and some programs depend on being able to exec code from a memfd directly. However, this new flag will allow programs to create non-executable memfds, and a distribution may choose to enforce use of this flag in memfd_create calls via other security mechanisms. Co-developed-by: Jeff Xu Signed-off-by: Jeff Xu Signed-off-by: Daniel Verkamp --- include/uapi/linux/memfd.h | 1 + mm/memfd.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/memfd.h b/include/uapi/linux/memfd.h index 7a8a26751c23..140e125c9f65 100644 --- a/include/uapi/linux/memfd.h +++ b/include/uapi/linux/memfd.h @@ -8,6 +8,7 @@ #define MFD_CLOEXEC 0x0001U #define MFD_ALLOW_SEALING 0x0002U #define MFD_HUGETLB 0x0004U +#define MFD_NOEXEC 0x0008U =20 /* * Huge page size encoding when MFD_HUGETLB is specified, and a huge page diff --git a/mm/memfd.c b/mm/memfd.c index 4ebeab94aa74..b841514eb0fd 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -263,7 +263,7 @@ long memfd_fcntl(struct file *file, unsigned int cmd, u= nsigned long arg) #define MFD_NAME_PREFIX_LEN (sizeof(MFD_NAME_PREFIX) - 1) #define MFD_NAME_MAX_LEN (NAME_MAX - MFD_NAME_PREFIX_LEN) =20 -#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB) +#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB | MFD= _NOEXEC) =20 SYSCALL_DEFINE2(memfd_create, const char __user *, uname, @@ -333,6 +333,14 @@ SYSCALL_DEFINE2(memfd_create, *file_seals &=3D ~F_SEAL_SEAL; } =20 + if (flags & MFD_NOEXEC) { + struct inode *inode =3D file_inode(file); + + inode->i_mode &=3D ~0111; + file_seals =3D memfd_file_seals_ptr(file); + *file_seals |=3D F_SEAL_EXEC; + } + fd_install(fd, file); kfree(name); return fd; --=20 2.37.1.559.g78731f0fdb-goog From nobody Sat Apr 20 04:23:03 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0EA95C00140 for ; Fri, 5 Aug 2022 22:22:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241830AbiHEWWE (ORCPT ); Fri, 5 Aug 2022 18:22:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36290 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241733AbiHEWVy (ORCPT ); Fri, 5 Aug 2022 18:21:54 -0400 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8755D1B7B6 for ; Fri, 5 Aug 2022 15:21:53 -0700 (PDT) Received: by mail-yb1-xb4a.google.com with SMTP id bu13-20020a056902090d00b00671743601f1so3133848ybb.0 for ; Fri, 05 Aug 2022 15:21:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=8AvsEq4SstPGeW7QF9LLj/CM82M+f11wZB7WzW/AmUg=; b=mMb+PeyF4VQkekJjv1Q+X2LF/3kKZ0J2TCbHkTTU/n5K6SxiBoS32IjQbd7vR1JBuY KK5mNxKRvJhbNpXkBgLNsjozyQGZZykaqk9VJaar90tvBTvpEwaJWc/oPcu8lkQsledi CfI3NYgAM5qa/N6/BrSW4XoQzQJwhjQqwzUAlLdH+uaizI1Yde5jEVhQMh4/W4ts0DRC nTZKmQYKwiV5MoJ69N1hpt8b+LYHYMNfd2Tl2jK9YjWAMNbaO4NhjiFuji/3ZwNy8TCO iFrzR+jYcS+CMSO5r4DA1Bvpyvedk6yb/v6haitjoDbX9YF4zss9+D/gTqEGtTKwy5vd 1RBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=8AvsEq4SstPGeW7QF9LLj/CM82M+f11wZB7WzW/AmUg=; b=4g3tpfm2XzyK5Oqmpphz5wVJ5tZbm4eqzj+8ibwVh1gNm0zsttNqGMiElnBEIGZDAQ qO9A0yz7PR01cugoJOxDVFPQaVMpsSpnkGYbU5eqKAPUmb7zoaqsSo4tHVotcDWZK60b J9L9/KI4JKzQEEfo0gVOAfpLRv21CZrArjFuQml2EmoQ5OoN5bL52kjnVkOzRS1hryaS 4+mZsWx2+bODHuIGP/Pg3MipeMDlF+ZV5Xs1ELO3CmwvL3+q7Bi5pd9kJFIjMSPkpULV ZKqcseHa6rX40vcjmvN2gLY8tEkfMJzv7BL/di3ASvrmDyalulY189Vdl4cOMYRfD2KB fATw== X-Gm-Message-State: ACgBeo2ws59c+LpjmGi7YicJPBIkiFoxu4tGXiEPpTJfeyhjdwbJ1qLR ptkxtnruCl48qOSUfNTurEvFvEpzoBU= X-Google-Smtp-Source: AA6agR7MhJWGNuJekXT5wplu+5rroD6wgWIQKDgy1c8mBYuUwU+BizAsUUXtqWQTJ2dbcZa+Q1JevcSWC98= X-Received: from jeffxud.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:e37]) (user=jeffxu job=sendgmr) by 2002:a81:7b85:0:b0:321:119:5a0d with SMTP id w127-20020a817b85000000b0032101195a0dmr8242026ywc.55.1659738112795; Fri, 05 Aug 2022 15:21:52 -0700 (PDT) Date: Fri, 5 Aug 2022 22:21:24 +0000 In-Reply-To: <20220805222126.142525-1-jeffxu@google.com> Message-Id: <20220805222126.142525-4-jeffxu@google.com> Mime-Version: 1.0 References: <20220805222126.142525-1-jeffxu@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v2 3/5] selftests/memfd: add tests for F_SEAL_EXEC From: To: skhan@linuxfoundation.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, keescook@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, mnissler@chromium.org, jannh@google.com, Jeff Xu Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Daniel Verkamp Basic tests to ensure that user/group/other execute bits cannot be changed after applying F_SEAL_EXEC to a memfd. Co-developed-by: Jeff Xu Signed-off-by: Jeff Xu Signed-off-by: Daniel Verkamp --- tools/testing/selftests/memfd/memfd_test.c | 129 ++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/sel= ftests/memfd/memfd_test.c index 94df2692e6e4..1d7e7b36bbdd 100644 --- a/tools/testing/selftests/memfd/memfd_test.c +++ b/tools/testing/selftests/memfd/memfd_test.c @@ -28,12 +28,44 @@ #define MFD_DEF_SIZE 8192 #define STACK_SIZE 65536 =20 +#ifndef F_SEAL_EXEC +#define F_SEAL_EXEC 0x0020 +#endif + +#ifndef MAX_PATH +#define MAX_PATH 256 +#endif + /* * Default is not to test hugetlbfs */ static size_t mfd_def_size =3D MFD_DEF_SIZE; static const char *memfd_str =3D MEMFD_STR; =20 +static ssize_t fd2name(int fd, char *buf, size_t bufsize) +{ + char buf1[MAX_PATH]; + int size; + ssize_t nbytes; + + size =3D snprintf(buf1, MAX_PATH, "/proc/self/fd/%d", fd); + if (size < 0) { + printf("snprintf(%d) failed on %m\n", fd); + abort(); + } + + /* + * reserver one byte for string termination. + */ + nbytes =3D readlink(buf1, buf, bufsize-1); + if (nbytes =3D=3D -1) { + printf("readlink(%s) failed %m\n", buf1); + abort(); + } + buf[nbytes] =3D '\0'; + return nbytes; +} + static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags) { int r, fd; @@ -98,11 +130,14 @@ static unsigned int mfd_assert_get_seals(int fd) =20 static void mfd_assert_has_seals(int fd, unsigned int seals) { + char buf[MAX_PATH]; + int nbytes; unsigned int s; + fd2name(fd, buf, MAX_PATH); =20 s =3D mfd_assert_get_seals(fd); if (s !=3D seals) { - printf("%u !=3D %u =3D GET_SEALS(%d)\n", seals, s, fd); + printf("%u !=3D %u =3D GET_SEALS(%s)\n", seals, s, buf); abort(); } } @@ -594,6 +629,64 @@ static void mfd_fail_grow_write(int fd) } } =20 +static void mfd_assert_mode(int fd, int mode) +{ + struct stat st; + char buf[MAX_PATH]; + int nbytes; + + fd2name(fd, buf, MAX_PATH); + + if (fstat(fd, &st) < 0) { + printf("fstat(%s) failed: %m\n", buf); + abort(); + } + + if ((st.st_mode & 07777) !=3D mode) { + printf("fstat(%s) wrong file mode 0%04o, but expected 0%04o\n", + buf, (int)st.st_mode & 07777, mode); + abort(); + } +} + +static void mfd_assert_chmod(int fd, int mode) +{ + char buf[MAX_PATH]; + int nbytes; + + fd2name(fd, buf, MAX_PATH); + + if (fchmod(fd, mode) < 0) { + printf("fchmod(%s, 0%04o) failed: %m\n", buf, mode); + abort(); + } + + mfd_assert_mode(fd, mode); +} + +static void mfd_fail_chmod(int fd, int mode) +{ + struct stat st; + char buf[MAX_PATH]; + int nbytes; + + fd2name(fd, buf, MAX_PATH); + + if (fstat(fd, &st) < 0) { + printf("fstat(%s) failed: %m\n", buf); + abort(); + } + + if (fchmod(fd, mode) =3D=3D 0) { + printf("fchmod(%s, 0%04o) didn't fail as expected\n", + buf, mode); + abort(); + } + + /* verify that file mode bits did not change */ + mfd_assert_mode(fd, st.st_mode & 07777); +} + static int idle_thread_fn(void *arg) { sigset_t set; @@ -880,6 +973,39 @@ static void test_seal_resize(void) close(fd); } =20 +/* + * Test SEAL_EXEC + * Test that chmod() cannot change x bits after sealing + */ +static void test_seal_exec(void) +{ + int fd; + + printf("%s SEAL-EXEC\n", memfd_str); + + fd =3D mfd_assert_new("kern_memfd_seal_exec", + mfd_def_size, + MFD_CLOEXEC | MFD_ALLOW_SEALING); + + mfd_assert_mode(fd, 0777); + + mfd_assert_chmod(fd, 0644); + + mfd_assert_has_seals(fd, 0); + mfd_assert_add_seals(fd, F_SEAL_EXEC); + mfd_assert_has_seals(fd, F_SEAL_EXEC); + + mfd_assert_chmod(fd, 0600); + mfd_fail_chmod(fd, 0777); + mfd_fail_chmod(fd, 0670); + mfd_fail_chmod(fd, 0605); + mfd_fail_chmod(fd, 0700); + mfd_fail_chmod(fd, 0100); + mfd_assert_chmod(fd, 0666); + + close(fd); +} + /* * Test sharing via dup() * Test that seals are shared between dupped FDs and they're all equal. @@ -1059,6 +1185,7 @@ int main(int argc, char **argv) test_seal_shrink(); test_seal_grow(); test_seal_resize(); + test_seal_exec(); =20 test_share_dup("SHARE-DUP", ""); test_share_mmap("SHARE-MMAP", ""); --=20 2.37.1.559.g78731f0fdb-goog From nobody Sat Apr 20 04:23:03 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 608FDC00140 for ; Fri, 5 Aug 2022 22:22:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241851AbiHEWWK (ORCPT ); Fri, 5 Aug 2022 18:22:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36234 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241779AbiHEWV4 (ORCPT ); Fri, 5 Aug 2022 18:21:56 -0400 Received: from mail-pg1-x549.google.com (mail-pg1-x549.google.com [IPv6:2607:f8b0:4864:20::549]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C3A11ADAF for ; Fri, 5 Aug 2022 15:21:55 -0700 (PDT) Received: by mail-pg1-x549.google.com with SMTP id y17-20020a63e251000000b0041d322b88b6so173779pgj.2 for ; Fri, 05 Aug 2022 15:21:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=18f+8YL6aOvEHaZ2GuJdUMnF89FwCoTjUmHERMQZXDE=; b=FsK4U64sZVq+y1SyuqOQStvSBS7X8QECCn6LIsVMr2xn0nkzLI8+c5D4j5EMd+AUhk j3t/30i3HkCUWA8GRrEV/n5la5QXWMAMmnEib1Gi4341JdPl8J5TfnHLWNa+y5fVP+eV oJ9bBE123va/TwKlbkn1J19gX+WOPS5lk3FwZlPtz0EcE3ZPCeaSKNYq9YOdEzFcDRFj lzgI8luSNRGb7P0bwY+aM7gsZ7WkQblht0scSjo8RmMJapESKs0qw+DFJAb+seJ/d+fa mzUs1GKxmI0hZowF1OygbHCwUgPDBmTWHAd9Z5XtwUGQJ2j7xvAyT0Qa4igHULcSRtrM vWkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=18f+8YL6aOvEHaZ2GuJdUMnF89FwCoTjUmHERMQZXDE=; b=LDFgZmATr2+n85CsSaAXdxzclozTdaDUQjUFwtFFzJM8+BiuxwiPIplaYTR1wr3S2v pFPeS9XV4aeCF2t0uxsE7fejclcLLijbGZO0eYa/NIepS8Pt01ARwWMecx5FMqeLdZNl 8+MsTijDXyKvMDtbpJhl7elHW/PyR/8wp0wgvqaZFgYScArr9X0BE5ZWJBG4Gd7ePmyt sYUyLLjJ5PHo6PSstdwbF7yoq1HcF8O8hIzyHZpBVA63sbhLN35qYzFsds4G3mqVB0mX EyeL21uXiC2iP1hoo8LnG4lJXo8gHrEHmt6cUKW4wlhvqu87eesWc15y/SWKPXKiV5G7 +ndQ== X-Gm-Message-State: ACgBeo34+mEviIUStsYMqD42ua1mPNiiGgbGLfBv0zeGa6PFu63XsBAV BNRgK1GddHzeTZZhlyhGeTexatSzS14= X-Google-Smtp-Source: AA6agR5SYNgjRPD70HCAO4QbLAX75hHQo60LfWD/m1Gc2TjfjizdokqQLPw4iq40ChDMtnBNielltDU4BD0= X-Received: from jeffxud.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:e37]) (user=jeffxu job=sendgmr) by 2002:a05:6a00:22d0:b0:52e:49f3:3f52 with SMTP id f16-20020a056a0022d000b0052e49f33f52mr8783529pfj.54.1659738115213; Fri, 05 Aug 2022 15:21:55 -0700 (PDT) Date: Fri, 5 Aug 2022 22:21:25 +0000 In-Reply-To: <20220805222126.142525-1-jeffxu@google.com> Message-Id: <20220805222126.142525-5-jeffxu@google.com> Mime-Version: 1.0 References: <20220805222126.142525-1-jeffxu@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v2 4/5] selftests/memfd: add tests for MFD_NOEXEC From: To: skhan@linuxfoundation.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, keescook@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, mnissler@chromium.org, jannh@google.com, Jeff Xu Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Daniel Verkamp Tests that ensure MFD_NOEXEC memfds have the appropriate mode bits and cannot be chmod-ed into being executable. Co-developed-by: Jeff Xu Signed-off-by: Jeff Xu Signed-off-by: Daniel Verkamp --- tools/testing/selftests/memfd/memfd_test.c | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/sel= ftests/memfd/memfd_test.c index 1d7e7b36bbdd..4906f778564e 100644 --- a/tools/testing/selftests/memfd/memfd_test.c +++ b/tools/testing/selftests/memfd/memfd_test.c @@ -36,6 +36,10 @@ #define MAX_PATH 256 #endif =20 +#ifndef MFD_NOEXEC +#define MFD_NOEXEC 0x0008U +#endif + /* * Default is not to test hugetlbfs */ @@ -1006,6 +1010,35 @@ static void test_seal_exec(void) close(fd); } =20 +/* + * Test memfd_create with MFD_NOEXEC flag + * Test that MFD_NOEXEC applies F_SEAL_EXEC and prevents change of exec bi= ts + */ +static void test_noexec(void) +{ + int fd; + + printf("%s NOEXEC\n", memfd_str); + + /* Create with NOEXEC and ALLOW_SEALING */ + fd =3D mfd_assert_new("kern_memfd_noexec", + mfd_def_size, + MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC); + mfd_assert_mode(fd, 0666); + mfd_assert_has_seals(fd, F_SEAL_EXEC); + mfd_fail_chmod(fd, 0777); + close(fd); + + /* Create with NOEXEC but without ALLOW_SEALING */ + fd =3D mfd_assert_new("kern_memfd_noexec", + mfd_def_size, + MFD_CLOEXEC | MFD_NOEXEC); + mfd_assert_mode(fd, 0666); + mfd_assert_has_seals(fd, F_SEAL_EXEC | F_SEAL_SEAL); + mfd_fail_chmod(fd, 0777); + close(fd); +} + /* * Test sharing via dup() * Test that seals are shared between dupped FDs and they're all equal. @@ -1179,6 +1212,7 @@ int main(int argc, char **argv) =20 test_create(); test_basic(); + test_noexec(); =20 test_seal_write(); test_seal_future_write(); --=20 2.37.1.559.g78731f0fdb-goog From nobody Sat Apr 20 04:23:03 2024 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8217C00140 for ; Fri, 5 Aug 2022 22:22:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241857AbiHEWWO (ORCPT ); Fri, 5 Aug 2022 18:22:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241804AbiHEWV7 (ORCPT ); Fri, 5 Aug 2022 18:21:59 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B2761C135 for ; Fri, 5 Aug 2022 15:21:58 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31cdce3ed04so31819677b3.13 for ; Fri, 05 Aug 2022 15:21:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=p3xudRLR9dNuWUK9U/ylm6O3b8FVaNLRrb9pQqFzR0w=; b=tEC+w7ZCMSi41gOV32xpW1cs0vFZd0pjxoK1AeJyyH01noSX4dLvRhywvBcccI9kdU JKFh83XKg1Si8IMewvVtmvDTWjRKjw3vuzZtx6w3xA2KeuXUxoU/6vRz//098kabUzjE eFwl26ps6MG+nYqCcCI1foMbFHepHOTyrxI0z85iwM8dIVVGbzs366K/ASaVu+V0zPT/ uJ/lsElcVWzYS8YYewDpoOAwFTi+w1gRSdsGaOWMYHEI+AEzCyag0hQVzUs3cU93g+T8 p0Ut/ZVPUs8LdBcNe3+7UfinveQxYxEtWF7YFesMt+DabZUIKwIYMEaR3aoNOvIbKV0C 8E5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=p3xudRLR9dNuWUK9U/ylm6O3b8FVaNLRrb9pQqFzR0w=; b=p0otPQkQTj/9A4nKR0nb0zbo163/gGx1LH7P/GW6q4LvJOIyjBCaiDqbJ4VvTAppZq gZh6gc4s2fFDjHXMl55VyZucLZxagJ9wsD3mX+zEGzyNsfhFXWb7WWrYj+xamI+kiTfZ PCxKXyZMvLqTKRT2qUyaUv5zpZ7MI/KLrrELVaBAqx1ivCj/PwVocJxaqQM+9oEh4b/X Xjfia5NSzkJhB5Yf6bWuFC89v8bVr5Pm8VFJFAUCiBBGsTI/3Z2KuqjcYRlShg5UwtfY mJKfQKMtWfw6jrlPEgj54mmgORkm0szyw+Z8jVuVwBuT+FfX4r9v1h12NxGze1Co119E AOcA== X-Gm-Message-State: ACgBeo1rUYWxckiBtjMe8mMMCsboxA2zuqo/m6lR5zuz2WxgIH1SOIT3 gZFpXND2l2mi5V2RKP3rsf9TeiuqjmE= X-Google-Smtp-Source: AA6agR7Pdt67CAVIWF/fYp+P3xXpceR93JSbt9+i7cJEfvpa+CoelR+6dqwVhJxpBe3viA/07hQjowUu1E0= X-Received: from jeffxud.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:e37]) (user=jeffxu job=sendgmr) by 2002:a25:33c5:0:b0:67a:6950:c188 with SMTP id z188-20020a2533c5000000b0067a6950c188mr7334020ybz.175.1659738117501; Fri, 05 Aug 2022 15:21:57 -0700 (PDT) Date: Fri, 5 Aug 2022 22:21:26 +0000 In-Reply-To: <20220805222126.142525-1-jeffxu@google.com> Message-Id: <20220805222126.142525-6-jeffxu@google.com> Mime-Version: 1.0 References: <20220805222126.142525-1-jeffxu@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v2 5/5] sysctl: add support for mfd_noexec From: To: skhan@linuxfoundation.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, keescook@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, mnissler@chromium.org, jannh@google.com, Jeff Xu Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Jeff Xu Add vm.mfd_noexec. When the value is 1 (enabled), memfd_create syscall will created non-executable memfd. The default value is 0 (disabled), admin can change the setting from 0 =3D> 1, however 1 =3D> 0 is not allowed, unless reboot. Signed-off-by: Jeff Xu Reported-by: kernel test robot --- include/linux/mm.h | 4 ++++ kernel/sysctl.c | 9 +++++++++ mm/memfd.c | 27 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index 7898e29bcfb5..1c66cf4aca11 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -203,6 +203,10 @@ extern int sysctl_overcommit_memory; extern int sysctl_overcommit_ratio; extern unsigned long sysctl_overcommit_kbytes; =20 +extern int sysctl_mfd_noexec_scope; +extern int mfd_noexec_dointvec_minmax(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos); + int overcommit_ratio_handler(struct ctl_table *, int, void *, size_t *, loff_t *); int overcommit_kbytes_handler(struct ctl_table *, int, void *, size_t *, diff --git a/kernel/sysctl.c b/kernel/sysctl.c index b233714a1c78..54510da007ff 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2362,6 +2362,15 @@ static struct ctl_table vm_table[] =3D { .mode =3D 0644, .proc_handler =3D mmap_min_addr_handler, }, + { + .procname =3D "mfd_noexec", + .data =3D &sysctl_mfd_noexec_scope, + .maxlen =3D sizeof(sysctl_mfd_noexec_scope), + .mode =3D 0644, + .proc_handler =3D mfd_noexec_dointvec_minmax, + .extra1 =3D SYSCTL_ZERO, + .extra2 =3D SYSCTL_ONE, + }, #endif #ifdef CONFIG_NUMA { diff --git a/mm/memfd.c b/mm/memfd.c index b841514eb0fd..c6ccb8481ed2 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -20,6 +20,11 @@ #include #include =20 +#define MFD_NOEXEC_SCOPE_DISABLED 0 +#define MFD_NOEXEC_SCOPE_ENABLED 1 + +int sysctl_mfd_noexec_scope __read_mostly =3D MFD_NOEXEC_SCOPE_DISABLED; + /* * We need a tag: a new tag would expand every xa_node by 8 bytes, * so reuse a tag which we firmly believe is never set or cleared on tmpfs @@ -275,6 +280,10 @@ SYSCALL_DEFINE2(memfd_create, char *name; long len; =20 + if (sysctl_mfd_noexec_scope =3D=3D MFD_NOEXEC_SCOPE_ENABLED) { + flags |=3D MFD_NOEXEC; + } + if (!(flags & MFD_HUGETLB)) { if (flags & ~(unsigned int)MFD_ALL_FLAGS) return -EINVAL; @@ -351,3 +360,21 @@ SYSCALL_DEFINE2(memfd_create, kfree(name); return error; } + +#ifdef CONFIG_SYSCTL +int mfd_noexec_dointvec_minmax(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + struct ctl_table table_copy; + + if (write && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + /* Lock the max value if it ever gets set. */ + table_copy =3D *table; + if (*(int *)table_copy.data =3D=3D *(int *)table_copy.extra2) + table_copy.extra1 =3D table_copy.extra2; + + return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos); +} +#endif --=20 2.37.1.559.g78731f0fdb-goog