From patchwork Tue Dec 6 15:23:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 30380 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2889779wrr; Tue, 6 Dec 2022 07:33:55 -0800 (PST) X-Google-Smtp-Source: AA0mqf6YomQkr6N/Di0Zc3eRPr8srSsAraDeD/ePHJ+z507hhpTvDdS/4ABbJZhATmLW85jjShAj X-Received: by 2002:a17:902:a50a:b0:189:dedd:a4f9 with SMTP id s10-20020a170902a50a00b00189dedda4f9mr7880329plq.99.1670340834874; Tue, 06 Dec 2022 07:33:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670340834; cv=none; d=google.com; s=arc-20160816; b=iLsPdizZKcEubabsBSvrGcD//9LtC3CwsSeHjWKkDQXLLcxdai6IysY/9DHxNthSU4 IFqsZCUVPGjwNd16ZYmpvtDCvNLOC0bGsvdQjzopAra2vr45cicnnMcVrLwleft2tJCn b4YxokpNndkCPJPLSNuylvyMQ0yEbevS1dIz3EqVnn2ceUKXkNAVSClp+ueXzZLcHlms DelNFaneNj7Wr0LBQgjFUo1hBuMr3Xg5+IidNbb7w6l9KJQ9CWi3xPOfn4MgPvO+CxXB SiCJAfXTxMEbI6zN8Zjp+T24GJmJ+05N8CS9IieF5Tnj9NHed7trcmbf8XSDgPIe6iVT FJPw== 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 :dkim-signature; bh=FWkrRAknVBR+DtqNNWTgcHsNLwaDUPfHC+NIWe1Ak98=; b=MpqhzJnVpOITkj10INKx78OSt+2Oh2+0AKWjJHvBEqI6rAbdMY16rGdqcyJ/i/dnEb d2qgGesu618wDxmjNhWdyzDuVgXqgAWILwpeR+TyY4kFOAion90GS5WaITx1Y/xcQFfE i/1S6IJHs1xavKoOk/WMiQi2GOviwzfptjH+3N0wrFoEH5vNiQZifKVdiDKrLF04Il06 rLXatPOh24dnCJ1ZMyyRtcS3/92dTr5d0k+dFhN2pWbirnRg0evQeyZSYf96Eb32dF4g 5M/6LA9ox57UQe+ruIZGfwihxT797rSU3+EJC6x5PhbUaslzxUhkbP4sIzPpBHyfAWbJ QPJA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=Fth6Ljyi; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q14-20020a631f4e000000b0042b4defce13si16905567pgm.344.2022.12.06.07.33.37; Tue, 06 Dec 2022 07:33:54 -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; dkim=pass header.i=@chromium.org header.s=google header.b=Fth6Ljyi; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234873AbiLFPYN (ORCPT + 99 others); Tue, 6 Dec 2022 10:24:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234156AbiLFPYE (ORCPT ); Tue, 6 Dec 2022 10:24:04 -0500 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55CF5ED for ; Tue, 6 Dec 2022 07:24:04 -0800 (PST) Received: by mail-pl1-x62d.google.com with SMTP id 4so14272836pli.0 for ; Tue, 06 Dec 2022 07:24:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FWkrRAknVBR+DtqNNWTgcHsNLwaDUPfHC+NIWe1Ak98=; b=Fth6Ljyi3O8BqZBrAER8NKJhbiS+1IWC8mWNeQeNKwWGRBfLBRBzE1IapAmq3O7HcY vnuXFwZthnjSaauPCurPg+gSgg1rpuOvtLGCFKszkVtulVawZm49XGMeiVaH4mB0e4lk 3qTh0tcbpMEm0Y6GAcorBW/EW1GlUGjutAtcY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FWkrRAknVBR+DtqNNWTgcHsNLwaDUPfHC+NIWe1Ak98=; b=v6jPvxYLJQrPAZBqF1XK7Fwhm+onsKX3jH59kpAbSTFXIJDYJfVBqTKjLdeVNTrL0Q hb+WkX9GmwxXEhu29CqI7xUprhUchZr/d9hLbOh4pYzQaG7A50boJdxV1q1B0/Dm5Ovz lN7uuNGhU0e9XZ0WO3f/sULVQBXCpbhutqEewOicyi0UfSLWIo0CM9t25h7YXabkpe3J r8BpEudlBL/EWwjt/mtSNt3/1zqIzGu6W8IOC1TuDnWbD3nF80rsg8mVccKAipZRliJC kCreXKyAdJ0EnERNhax0Jy7qiPQF+PqFIf5rW6/ZfCMehvUq3Eb2EpNAFywSBCBXs2VG D1YA== X-Gm-Message-State: ANoB5pmvSNmYyFF9A+DLTmcfpCGvzMNdR8JtAWMpCTn9qL4FRQ0twrEI u8bSNbenOgGm9Y2WGd48DEeOpg== X-Received: by 2002:a17:90a:6983:b0:21a:a0f:6acc with SMTP id s3-20020a17090a698300b0021a0a0f6accmr1008574pjj.77.1670340243766; Tue, 06 Dec 2022 07:24:03 -0800 (PST) Received: from jeffxud.c.googlers.com.com (30.202.168.34.bc.googleusercontent.com. [34.168.202.30]) by smtp.gmail.com with ESMTPSA id r25-20020a635d19000000b0046b1dabf9a8sm10004686pgb.70.2022.12.06.07.24.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 07:24:03 -0800 (PST) From: jeffxu@chromium.org To: skhan@linuxfoundation.org, keescook@chromium.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, jannh@google.com, linux-hardening@vger.kernel.org, Jeff Xu Subject: [PATCH v5 1/6] mm/memfd: add F_SEAL_EXEC Date: Tue, 6 Dec 2022 15:23:53 +0000 Message-Id: <20221206152358.1966099-2-jeffxu@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog In-Reply-To: <20221206152358.1966099-1-jeffxu@google.com> References: <20221206152358.1966099-1-jeffxu@google.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE autolearn=unavailable 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?1751479311221144460?= X-GMAIL-MSGID: =?utf-8?q?1751479311221144460?= 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. Signed-off-by: Daniel Verkamp Co-developed-by: Jeff Xu Signed-off-by: Jeff Xu --- 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..e8c07da58c9f 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 */ /* 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) } #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 c1d8b8a1aa3b..e18a9cf9d937 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1085,6 +1085,12 @@ static int shmem_setattr(struct user_namespace *mnt_userns, if (error) return error; + 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 = inode->i_size; loff_t newsize = attr->ia_size; From patchwork Tue Dec 6 15:23:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 30378 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2889254wrr; Tue, 6 Dec 2022 07:32:57 -0800 (PST) X-Google-Smtp-Source: AA0mqf4jRNYkALzhaTMDW2/iZsAstTKSs9mn2ciM1BQwAZ1s7FzU+cI2FMaNIPFl2nEPPOStLAys X-Received: by 2002:a17:907:37a:b0:7c0:e4b6:132e with SMTP id rs26-20020a170907037a00b007c0e4b6132emr10207364ejb.224.1670340777063; Tue, 06 Dec 2022 07:32:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670340777; cv=none; d=google.com; s=arc-20160816; b=RydW2gY+bYP3MeTbSgXPwG8ki/QV4bWl99YawNRPY+9Ll/Gy0CLyJ5xJGwWQVGwBd1 rnvDovM+OGzKmLXIXBDqd/fTBbZMoDMN19KtLfMgoBidygIzK4yb/VTNp++SWFUpcXOG PLYdUwx3CW3m9Go839Edk8ofd9TyrJcfhvmFP2TdKKAcpjhJK2LVfEiRPGqS+kPk7iOD Ukk1j21diEYL9OZTfYkZkGR6ym74hp3RCeAndNPJlnwihNZ5Am2fdrxJUvSoOR6O0//2 YTIz9F8t/WwDmUXL6LHAr3hq+HpK032XTKlR31ekT5XQcggHrQH8tjInnXKpHoR7HXoJ CXDA== 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 :dkim-signature; bh=kmJ6vAUUVWR2mQbJ18nVP5DOm/6S97wQS9z+LXJq08M=; b=B6jyFzVAZ+QnZfeUQitS9F5O1eEztzQb165v5mP76+PINQDrhDOCsq3+BCJlQo1fYm iy9CSk0F/XfbMjsDDgLfxmKsV95q0nlAFpoADENyX7Ns7CdA3Xt7q4+RKdMQ2yu2EoWa NTwwuJAjUndXc/FKz+AQufJwUFQV7gFY16K6aXLqLGEtJfgxnFplo8njgbXe/kj7hl9V Gcb3tf5GfcrGAFQBnrYxEX0FhL3sZgNsRM6JduleepBo6tv7fgqdenpVyA/ZlBcwFugw RaKwhPIjZAVvyZk7+VFTzUrpNRu0YKNlLqTMdMVqIH2DkC87/DpUw1HWgYMABXRRDuan lnmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=NycKp0JI; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id v9-20020aa7d9c9000000b004520b01a355si2056868eds.52.2022.12.06.07.32.33; Tue, 06 Dec 2022 07:32:57 -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; dkim=pass header.i=@chromium.org header.s=google header.b=NycKp0JI; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235014AbiLFPYQ (ORCPT + 99 others); Tue, 6 Dec 2022 10:24:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49474 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234347AbiLFPYG (ORCPT ); Tue, 6 Dec 2022 10:24:06 -0500 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3AC7F63AE for ; Tue, 6 Dec 2022 07:24:05 -0800 (PST) Received: by mail-pj1-x102e.google.com with SMTP id w15-20020a17090a380f00b0021873113cb4so15135942pjb.0 for ; Tue, 06 Dec 2022 07:24:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kmJ6vAUUVWR2mQbJ18nVP5DOm/6S97wQS9z+LXJq08M=; b=NycKp0JIHUfaB7gQC1rQ4lT4Sr26kgUE3lM9tnnYJpitmIubv4/0CP5fdfEAJLpfZj gQYB6D/QKKUmeoY6twXhVr2IuJet3kp3/+/WL9I3VfXcmfUAy1TUbD/zlU/durISGorD SuOIZkKIlFUjTzMtAImsXseLwvjfH2YAwJ90o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kmJ6vAUUVWR2mQbJ18nVP5DOm/6S97wQS9z+LXJq08M=; b=kMhSBMr8mxtcY3TW7o2Khl0tcjOojUVrIIivNDahmYXqLlN9EBPsN/iheDt+TikvR7 QUCGSvTiilEGR2Gu54hEyuUbQRMraB2SdGwucsdA3V3oI5+/e3qPmUC5WDHQtZpbQ5Nu faJydYaclYOJ2IJ3b8XCATScE95cVRBka+NfaO9wdhsuGxXadrCKx0NsWNN+n1i479i9 IvARKn1mLGhQcifh9lFXfn/Zq45BXlPWTR+1Dsf9dy+2BGp+exfOlwM1I3l9CHbL4kJb /0/pNr4pISp/eFC3DRYmI4eS6U13Qanjctg0SBTpf7V6hCQgsxoTBmdGIyAOilziOjTo qIMw== X-Gm-Message-State: ANoB5pmu+Hb6h4nr8MTeFSdqXTaQDNtuKPz9qvHfevLIYhDMWICwJ/F6 vLjSSpFAT/1xMIE0kmhDn1dMwA== X-Received: by 2002:a17:90a:ab08:b0:219:aea9:4487 with SMTP id m8-20020a17090aab0800b00219aea94487mr16683300pjq.161.1670340244734; Tue, 06 Dec 2022 07:24:04 -0800 (PST) Received: from jeffxud.c.googlers.com.com (30.202.168.34.bc.googleusercontent.com. [34.168.202.30]) by smtp.gmail.com with ESMTPSA id r25-20020a635d19000000b0046b1dabf9a8sm10004686pgb.70.2022.12.06.07.24.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 07:24:04 -0800 (PST) From: jeffxu@chromium.org To: skhan@linuxfoundation.org, keescook@chromium.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, jannh@google.com, linux-hardening@vger.kernel.org, Jeff Xu Subject: [PATCH v5 2/6] selftests/memfd: add tests for F_SEAL_EXEC Date: Tue, 6 Dec 2022 15:23:54 +0000 Message-Id: <20221206152358.1966099-3-jeffxu@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog In-Reply-To: <20221206152358.1966099-1-jeffxu@google.com> References: <20221206152358.1966099-1-jeffxu@google.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE 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?1751479250827096109?= X-GMAIL-MSGID: =?utf-8?q?1751479250827096109?= From: Daniel Verkamp Basic tests to ensure that user/group/other execute bits cannot be changed after applying F_SEAL_EXEC to a memfd. Signed-off-by: Daniel Verkamp Co-developed-by: Jeff Xu Signed-off-by: Jeff Xu --- 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/selftests/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 +#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 = MFD_DEF_SIZE; static const char *memfd_str = MEMFD_STR; +static ssize_t fd2name(int fd, char *buf, size_t bufsize) +{ + char buf1[MAX_PATH]; + int size; + ssize_t nbytes; + + size = 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 = readlink(buf1, buf, bufsize-1); + if (nbytes == -1) { + printf("readlink(%s) failed %m\n", buf1); + abort(); + } + buf[nbytes] = '\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) 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); s = mfd_assert_get_seals(fd); if (s != seals) { - printf("%u != %u = GET_SEALS(%d)\n", seals, s, fd); + printf("%u != %u = GET_SEALS(%s)\n", seals, s, buf); abort(); } } @@ -594,6 +629,64 @@ static void mfd_fail_grow_write(int fd) } } +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) != 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) == 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); } +/* + * 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 = 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(); test_share_dup("SHARE-DUP", ""); test_share_mmap("SHARE-MMAP", ""); From patchwork Tue Dec 6 15:23:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 30379 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2889303wrr; Tue, 6 Dec 2022 07:33:02 -0800 (PST) X-Google-Smtp-Source: AA0mqf4lRYg3Q/Qakyz1g8V7DstF+Ld8cTOZmkuwFQzx97zbHlqXeaT+xh/kQaiJnS3hQcJauc7p X-Received: by 2002:a17:906:5612:b0:7bb:8db0:53e7 with SMTP id f18-20020a170906561200b007bb8db053e7mr47706528ejq.471.1670340782168; Tue, 06 Dec 2022 07:33:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670340782; cv=none; d=google.com; s=arc-20160816; b=V8PSCSU/IHm//uGKDpXNS6qjC6AkXunEVf6Y5R9OmwP8NjEmSZcZ9tM4rRNyZyujB/ 97KKzZ7g3WiG/GfYWGm/R/x4vIgaYqDyrM71Nu1xCpuzASSo+jtAjuIxaHLhiuPvp4PX fSP8RbIaf8wYBOVJYN51t/P/mWYhw+IcG6jQZkPokswkpsAgypDFs9ftx8CiHnxgfPuB 9uJF3vI5hN8f/1xCllLUbGTCsRqtXE0MwUsLiwNwWg3i2S85wktpG2WIej0MXgiW4p4R otYWe4nnG0LoC24loXggHd6vBqbbVTf1WYX52sEV/2cvEPgeUXpZe9kMrlcN1gNxWFn3 S/5Q== 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 :dkim-signature; bh=SdDrnGbeR2v4+0YeS8iLZurDBTuoZ6giO5nJB6MXDpc=; b=aZRpjEuhiReLBthWaveqRHyuWqk6tiVlL4hOCFRvUZUfhEV3oHs789YXQmhJwEPkHC gwqZ/Fnh+lkdQa7jR6uAyHGNidd4pKpaShWPBEabSxkWMMIOxjjYzB4aanm0xCctKxNy xZz26BiAM561HgABMIREkbYwDcMFi9HZdvySSthba3RP9sEX5mOR+MmG3VE0sHY97Id8 XpzouFZL7FBYDRynvtbcmEqq2i7Z6fW1Nm07XAbDiatnW5Iwjbx/YlnUVPahrHrrRPZE O8+H/a07Tp7ZDv3Ll7IyzX6NALMiu0gq2ngBOdlh+OGqEDxjTJOSxmUxURwZErbTxUGs yoXA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=hy4suxKV; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b12-20020a056402350c00b0046400f454a3si2466604edd.125.2022.12.06.07.32.35; Tue, 06 Dec 2022 07:33:02 -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; dkim=pass header.i=@chromium.org header.s=google header.b=hy4suxKV; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235156AbiLFPYT (ORCPT + 99 others); Tue, 6 Dec 2022 10:24:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233661AbiLFPYH (ORCPT ); Tue, 6 Dec 2022 10:24:07 -0500 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C5D563DE for ; Tue, 6 Dec 2022 07:24:06 -0800 (PST) Received: by mail-pf1-x42d.google.com with SMTP id c7so11439629pfc.12 for ; Tue, 06 Dec 2022 07:24:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SdDrnGbeR2v4+0YeS8iLZurDBTuoZ6giO5nJB6MXDpc=; b=hy4suxKV0CyxFkQ/z0Lxf0gL1yedefQH7rpxWKiGLEXG11CaUMjqSwBNt4//d8Yxut t8l+OOBEGKoLm75Fu0H9KVpPxy0L7HBWe9P0jq+lD75ae+9pN2+63j2gfiStg4HrqjUj dihRnu1ru6UOyG/D0new9gAKAkWXGkicC3NDY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SdDrnGbeR2v4+0YeS8iLZurDBTuoZ6giO5nJB6MXDpc=; b=4kXuyNtPdNVEzwzVhv2EdTYdh5x+xpeKxwgW9Z+CGid4ppYN/94pjOdQtCsP1PACzC yYIKt/x+mR/p2XuUyHD5P4RiVrtXfGfGU0LGOJ+MYZsCgqVKeJNTSV4lFbTZmY+6K4Tf SimKt/7qNY3UUtQmFrmCzr/S/UiDVlntreaR3Pi5eIlu2v4RSHc3sTPE9egVIjcMycfZ uiG246899nx4Oxd2rDdsJ4R+Rrz/E0MRmuvrzdpxlPPzHjrkkVcvKYHc0sFkiB9bUk99 HrxfdZtZpPG0HZ2CWC8cOzzGpXsGcFeTs6BoONuU5MCBIqoKl4znt6w1IcgDt02uSk+W yoQA== X-Gm-Message-State: ANoB5pmYaFgKf7vXYstGfzr0iMSn0ZkGrFMQe3SX8wQShzKpCGT07xHf kvL9lWHP3Svy1y0W6xi/A/vZyg== X-Received: by 2002:a05:6a00:368e:b0:574:ead0:7c22 with SMTP id dw14-20020a056a00368e00b00574ead07c22mr29281567pfb.9.1670340245699; Tue, 06 Dec 2022 07:24:05 -0800 (PST) Received: from jeffxud.c.googlers.com.com (30.202.168.34.bc.googleusercontent.com. [34.168.202.30]) by smtp.gmail.com with ESMTPSA id r25-20020a635d19000000b0046b1dabf9a8sm10004686pgb.70.2022.12.06.07.24.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 07:24:05 -0800 (PST) From: jeffxu@chromium.org To: skhan@linuxfoundation.org, keescook@chromium.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, jannh@google.com, linux-hardening@vger.kernel.org, Jeff Xu , kernel test robot Subject: [PATCH v5 3/6] mm/memfd: add MFD_NOEXEC_SEAL and MFD_EXEC Date: Tue, 6 Dec 2022 15:23:55 +0000 Message-Id: <20221206152358.1966099-4-jeffxu@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog In-Reply-To: <20221206152358.1966099-1-jeffxu@google.com> References: <20221206152358.1966099-1-jeffxu@google.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE autolearn=unavailable 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?1751479256276297179?= X-GMAIL-MSGID: =?utf-8?q?1751479256276297179?= From: Jeff Xu The new MFD_NOEXEC_SEAL and MFD_EXEC flags allows application to set executable bit at creation time (memfd_create). When MFD_NOEXEC_SEAL is set, memfd is created without executable bit (mode:0666), and sealed with F_SEAL_EXEC, so it can't be chmod to be executable (mode: 0777) after creation. when MFD_EXEC flag is set, memfd is created with executable bit (mode:0777), this is the same as the old behavior of memfd_create. The new pid namespaced sysctl vm.memfd_noexec has 3 values: 0: memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_EXEC was set. 1: memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL acts like MFD_NOEXEC_SEAL was set. 2: memfd_create() without MFD_NOEXEC_SEAL will be rejected. The sysctl allows finer control of memfd_create for old-software that doesn't set the executable bit, for example, a container with vm.memfd_noexec=1 means the old-software will create non-executable memfd by default. Signed-off-by: Jeff Xu Co-developed-by: Daniel Verkamp Signed-off-by: Daniel Verkamp Reported-by: kernel test robot --- include/linux/pid_namespace.h | 19 ++++++++++++++ include/uapi/linux/memfd.h | 4 +++ kernel/pid_namespace.c | 48 +++++++++++++++++++++++++++++++++++ mm/memfd.c | 48 +++++++++++++++++++++++++++++++++-- 4 files changed, 117 insertions(+), 2 deletions(-) diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 07481bb87d4e..a4789a7b34a9 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -16,6 +16,21 @@ struct fs_pin; +#if defined(CONFIG_SYSCTL) && defined(CONFIG_MEMFD_CREATE) +/* + * sysctl for vm.memfd_noexec + * 0: memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL + * acts like MFD_EXEC was set. + * 1: memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL + * acts like MFD_NOEXEC_SEAL was set. + * 2: memfd_create() without MFD_NOEXEC_SEAL will be + * rejected. + */ +#define MEMFD_NOEXEC_SCOPE_EXEC 0 +#define MEMFD_NOEXEC_SCOPE_NOEXEC_SEAL 1 +#define MEMFD_NOEXEC_SCOPE_NOEXEC_ENFORCED 2 +#endif + struct pid_namespace { struct idr idr; struct rcu_head rcu; @@ -31,6 +46,10 @@ struct pid_namespace { struct ucounts *ucounts; int reboot; /* group exit code if this pidns was rebooted */ struct ns_common ns; +#if defined(CONFIG_SYSCTL) && defined(CONFIG_MEMFD_CREATE) + /* sysctl for vm.memfd_noexec */ + int memfd_noexec_scope; +#endif } __randomize_layout; extern struct pid_namespace init_pid_ns; diff --git a/include/uapi/linux/memfd.h b/include/uapi/linux/memfd.h index 7a8a26751c23..273a4e15dfcf 100644 --- a/include/uapi/linux/memfd.h +++ b/include/uapi/linux/memfd.h @@ -8,6 +8,10 @@ #define MFD_CLOEXEC 0x0001U #define MFD_ALLOW_SEALING 0x0002U #define MFD_HUGETLB 0x0004U +/* not executable and sealed to prevent changing to executable. */ +#define MFD_NOEXEC_SEAL 0x0008U +/* executable */ +#define MFD_EXEC 0x0010U /* * Huge page size encoding when MFD_HUGETLB is specified, and a huge page diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index f4f8cb0435b4..2b7563ddd22c 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -110,6 +110,11 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns ns->ucounts = ucounts; ns->pid_allocated = PIDNS_ADDING; +#if defined(CONFIG_SYSCTL) && defined(CONFIG_MEMFD_CREATE) + ns->memfd_noexec_scope = + task_active_pid_ns(current)->memfd_noexec_scope; +#endif + return ns; out_free_idr: @@ -255,6 +260,45 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) return; } +#if defined(CONFIG_SYSCTL) && defined(CONFIG_MEMFD_CREATE) +static int pid_mfd_noexec_dointvec_minmax(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) +{ + struct pid_namespace *ns = task_active_pid_ns(current); + struct ctl_table table_copy; + + if (write && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + table_copy = *table; + if (ns != &init_pid_ns) + table_copy.data = &ns->memfd_noexec_scope; + + /* + * set minimum to current value, the effect is only bigger + * value is accepted. + */ + if (*(int *)table_copy.data > *(int *)table_copy.extra1) + table_copy.extra1 = table_copy.data; + + return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos); +} + +static struct ctl_table pid_ns_ctl_table_vm[] = { + { + .procname = "memfd_noexec", + .data = &init_pid_ns.memfd_noexec_scope, + .maxlen = sizeof(init_pid_ns.memfd_noexec_scope), + .mode = 0644, + .proc_handler = pid_mfd_noexec_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_TWO, + }, + { } +}; +static struct ctl_path vm_path[] = { { .procname = "vm", }, { } }; +#endif + #ifdef CONFIG_CHECKPOINT_RESTORE static int pid_ns_ctl_handler(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) @@ -455,6 +499,10 @@ static __init int pid_namespaces_init(void) #ifdef CONFIG_CHECKPOINT_RESTORE register_sysctl_paths(kern_path, pid_ns_ctl_table); #endif + +#if defined(CONFIG_SYSCTL) && defined(CONFIG_MEMFD_CREATE) + register_sysctl_paths(vm_path, pid_ns_ctl_table_vm); +#endif return 0; } diff --git a/mm/memfd.c b/mm/memfd.c index 4ebeab94aa74..ec70675a7069 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -18,6 +18,7 @@ #include #include #include +#include #include /* @@ -263,12 +264,14 @@ long memfd_fcntl(struct file *file, unsigned int cmd, unsigned long arg) #define MFD_NAME_PREFIX_LEN (sizeof(MFD_NAME_PREFIX) - 1) #define MFD_NAME_MAX_LEN (NAME_MAX - MFD_NAME_PREFIX_LEN) -#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB) +#define MFD_ALL_FLAGS (MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_HUGETLB | MFD_NOEXEC_SEAL | MFD_EXEC) SYSCALL_DEFINE2(memfd_create, const char __user *, uname, unsigned int, flags) { + char comm[TASK_COMM_LEN]; + struct pid_namespace *ns; unsigned int *file_seals; struct file *file; int fd, error; @@ -285,6 +288,39 @@ SYSCALL_DEFINE2(memfd_create, return -EINVAL; } + /* Invalid if both EXEC and NOEXEC_SEAL are set.*/ + if ((flags & MFD_EXEC) && (flags & MFD_NOEXEC_SEAL)) + return -EINVAL; + + if (!(flags & (MFD_EXEC | MFD_NOEXEC_SEAL))) { +#ifdef CONFIG_SYSCTL + int sysctl = MEMFD_NOEXEC_SCOPE_EXEC; + + ns = task_active_pid_ns(current); + if (ns) + sysctl = ns->memfd_noexec_scope; + + switch (sysctl) { + case MEMFD_NOEXEC_SCOPE_EXEC: + flags |= MFD_EXEC; + break; + case MEMFD_NOEXEC_SCOPE_NOEXEC_SEAL: + flags |= MFD_NOEXEC_SEAL; + break; + default: + pr_warn_ratelimited( + "memfd_create(): MFD_NOEXEC_SEAL is enforced, pid=%d '%s'\n", + task_pid_nr(current), get_task_comm(comm, current)); + return -EINVAL; + } +#else + flags |= MFD_EXEC; +#endif + pr_warn_ratelimited( + "memfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL, pid=%d '%s'\n", + task_pid_nr(current), get_task_comm(comm, current)); + } + /* length includes terminating zero */ len = strnlen_user(uname, MFD_NAME_MAX_LEN + 1); if (len <= 0) @@ -328,7 +364,15 @@ SYSCALL_DEFINE2(memfd_create, file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; file->f_flags |= O_LARGEFILE; - if (flags & MFD_ALLOW_SEALING) { + if (flags & MFD_NOEXEC_SEAL) { + struct inode *inode = file_inode(file); + + inode->i_mode &= ~0111; + file_seals = memfd_file_seals_ptr(file); + *file_seals &= ~F_SEAL_SEAL; + *file_seals |= F_SEAL_EXEC; + } else if (flags & MFD_ALLOW_SEALING) { + /* MFD_EXEC and MFD_ALLOW_SEALING are set */ file_seals = memfd_file_seals_ptr(file); *file_seals &= ~F_SEAL_SEAL; } From patchwork Tue Dec 6 15:23:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 30383 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2890548wrr; Tue, 6 Dec 2022 07:35:15 -0800 (PST) X-Google-Smtp-Source: AA0mqf5w0UGzKfb2MtIlvxzdUdjjOo/1yNqW5pOvIwDVaXHgQdX3O1vRBdlVjCOhhdGXCPrERTqC X-Received: by 2002:a05:6402:5010:b0:467:60bd:41a1 with SMTP id p16-20020a056402501000b0046760bd41a1mr78981683eda.97.1670340915044; Tue, 06 Dec 2022 07:35:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670340915; cv=none; d=google.com; s=arc-20160816; b=dlpLeYkExLJHl3ySN7FDYtU2Xm/gc4YnmBS+z4vkVGXFA5UnHUYNIytOkUAzq/xfqD +x0e0hkT2cSrOIhlW4GrJZlGXhP4FlxuQB2HX+IODhZIo9srbeOqGnq8LjtENhMbre0Z IFIcmM6NFXWdoWSK85RozcYvkr/fdmm6rgX0PDXm2BpPj8p829jO5w4YF9IuCLI+vgvf tKrOiYOVYEde9osMtbnDoRgn0meVihGBChr2WQz4RXhFUA5OiTTQgAeTJNsZkOxKLcKb PDoIQ5iatsrxGjZvRhYJxl658if1XfdNBXceaSBMPaXVCnYGomZay/DFXY1fV0q0oPem +nag== 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 :dkim-signature; bh=++VLLdD5R20NP2dhD9BoY4L3MuuVmiuDtlzNl1iSWtk=; b=bntQoQnlbAW7JSFdmRfp/2wahpv0DQj6ar+ElicIbmYylvbufkiCWms3nuPmt6ZV8S usDPRt4Fd4sEOwG2cM++R9xcAqsNHoDbgLBpSUM8K+RqySYBt0acwZkL7uEXgcVUHO9Y j50SZvfkr1HK8iB+Poc38z/AWCbEKm0lE0xM/oBZT1M9KoIBa5ZFdJWjTcc7DCmhG0OK /IgDrvjW6WCbR7yW0yj0HMzbTG0fZlfcZgJ6IgLifarQpGBPK3kwVb0h5IwY/FPkjDIS nnqnYPEwUAQHzhgiRf+EIdau5RB5rMajAarLwecJke9gO9kl2zBJrullmA/nEFmyExGa ZoHg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=cAilTNJH; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id xh8-20020a170906da8800b007ba16fcfefdsi13889181ejb.936.2022.12.06.07.34.51; Tue, 06 Dec 2022 07:35:15 -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; dkim=pass header.i=@chromium.org header.s=google header.b=cAilTNJH; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234506AbiLFPYX (ORCPT + 99 others); Tue, 6 Dec 2022 10:24:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49474 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234621AbiLFPYJ (ORCPT ); Tue, 6 Dec 2022 10:24:09 -0500 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23E2910AF for ; Tue, 6 Dec 2022 07:24:07 -0800 (PST) Received: by mail-pl1-x62d.google.com with SMTP id jl24so14231535plb.8 for ; Tue, 06 Dec 2022 07:24:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=++VLLdD5R20NP2dhD9BoY4L3MuuVmiuDtlzNl1iSWtk=; b=cAilTNJHTAFkJQytHoH0SGB+6dKp6ndnZajpjXOAv2UO5kipCER/TNgAJmTUJcESYl VUtyRMqplbj+tD36ohI0lETkbFfIKMTDdyDeb35cYkms3sWCP6VCM94uPzi4In9LmbJv +2POC21Bj9oHiGiVhRrHZxnizizh3iJoxjf10= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=++VLLdD5R20NP2dhD9BoY4L3MuuVmiuDtlzNl1iSWtk=; b=mh9IwNe7Sm6XQvxLfW1nwvhyPfzf4bA5bzzNkenqDJ9Sopgf+XaPpit7fG3RN8cwFT J0gOkSDvjylNVWb0a4Iyw58DqM5ddDR9k4wIQ1B6r7mF1r7WyVWixUvGTBp27xApuvwX xMmnyMqlOK2xBMosEIz3tQhDVT9C9m3P2QCNbFHbclFkYARDJzP27hb55lIy9Frkb/Ks ynB1qnv8xeNBj6nMMw8c5wandweDOyvkmaqWJpL8ZAssAVmkgMFhcsJ5UiMcxHV9GfrM F1yzCfj11a38fsnqoYnBuH3DP46CAYCMFkpROlgqScqdRcoB4HqZMZYpoDdT+Ib52oTy y5/g== X-Gm-Message-State: ANoB5pkHyMnDfzKuEhGEKd7HnJzylM/1XMY99Y1eUV0bo4NwA5G7tYUu 6Z5xiPthJbDy4cipi8PBveld0A== X-Received: by 2002:a17:902:ccc3:b0:189:808b:c659 with SMTP id z3-20020a170902ccc300b00189808bc659mr46888465ple.13.1670340246644; Tue, 06 Dec 2022 07:24:06 -0800 (PST) Received: from jeffxud.c.googlers.com.com (30.202.168.34.bc.googleusercontent.com. [34.168.202.30]) by smtp.gmail.com with ESMTPSA id r25-20020a635d19000000b0046b1dabf9a8sm10004686pgb.70.2022.12.06.07.24.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 07:24:05 -0800 (PST) From: jeffxu@chromium.org To: skhan@linuxfoundation.org, keescook@chromium.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, jannh@google.com, linux-hardening@vger.kernel.org, Jeff Xu Subject: [PATCH v5 4/6] mm/memfd: Add write seals when apply SEAL_EXEC to executable memfd Date: Tue, 6 Dec 2022 15:23:56 +0000 Message-Id: <20221206152358.1966099-5-jeffxu@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog In-Reply-To: <20221206152358.1966099-1-jeffxu@google.com> References: <20221206152358.1966099-1-jeffxu@google.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE autolearn=unavailable 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?1751479395486388003?= X-GMAIL-MSGID: =?utf-8?q?1751479395486388003?= From: Jeff Xu In order to avoid WX mappings, add F_SEAL_WRITE when apply F_SEAL_EXEC to an executable memfd, so W^X from start. This implys application need to fill the content of the memfd first, after F_SEAL_EXEC is applied, application can no longer modify the content of the memfd. Typically, application seals the memfd right after writing to it. For example: 1. memfd_create(MFD_EXEC). 2. write() code to the memfd. 3. fcntl(F_ADD_SEALS, F_SEAL_EXEC) to convert the memfd to W^X. 4. call exec() on the memfd. Signed-off-by: Jeff Xu --- mm/memfd.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mm/memfd.c b/mm/memfd.c index ec70675a7069..92f0a5765f7c 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -222,6 +222,12 @@ static int memfd_add_seals(struct file *file, unsigned int seals) } } + /* + * SEAL_EXEC implys SEAL_WRITE, making W^X from the start. + */ + if (seals & F_SEAL_EXEC && inode->i_mode & 0111) + seals |= F_SEAL_SHRINK|F_SEAL_GROW|F_SEAL_WRITE|F_SEAL_FUTURE_WRITE; + *file_seals |= seals; error = 0; From patchwork Tue Dec 6 15:23:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 30381 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2890077wrr; Tue, 6 Dec 2022 07:34:29 -0800 (PST) X-Google-Smtp-Source: AA0mqf6zMyyH366sg9mOWondLt0opfAZUVO+XwaLDChU7uiI4gUGx/5koQxaHKV200jMnf3hOsan X-Received: by 2002:a63:4246:0:b0:477:98cc:3d01 with SMTP id p67-20020a634246000000b0047798cc3d01mr57163306pga.505.1670340869417; Tue, 06 Dec 2022 07:34:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670340869; cv=none; d=google.com; s=arc-20160816; b=Osx5guy3gqJvwvsM6QaiLdXMxDn2YaGLeVPv3rebP7/VjAaHYNBI30xPNRtwPSMM5R t8zpPrfYKJo+BI47z61yqSWV4mVtcJWDPI889+gv2UWVehLhW2iNqdBPEjz63DrEXvIz 25zhWaU00ssFo1krZ3+e/0OcVzP7BFbYemRmud9yTB44fV34BCTkLyWDQYEkZuGlXQk7 dJi55RPPdN4BUaS1lnEm0ZdXotmwF3z72wgJJVpecItgC70BUGkZ5HiE4NfEY1anrmBD M8Euu3RAFjIX+LBsVPH+y9YRqlhLBMfnEYrp1N+VLxv0h1F9e+L+wwNvb7liKis453nK u7Kw== 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 :dkim-signature; bh=BMuCN4bdPpTwWJ2iwnu2KEtJZwK23OdE1QXZ74xgH4g=; b=c+F6Jvy0ilz6VZ2cHL/rwyNPya12njub30H5YrnYfNPPhdsYOQF60fK1ZZRagHq91V DSxNMF+BtAO2DLaELsgyO5CAtcq8zHx34roAxRj03+fcisFCP16BEmDilX21FXOjiAKs 6ZSF2v6PGuhqyMhc7C6A7HhxL2w5qXZ0C1Erz+S0lqAaG/W2HNzBDPEBWnQ3cosdfdbg Qbvvof7XZh6VOWzcma6L9mhPZ52mSYNdxWoQPp1jNuw6JNlR9dByaBlaUob8kkzPjWRf T1UZBKlBD4hfw6HuZ+oKbwdy4usK3FQNwbQYqXyNxjAMHU1GG7MgPZIghNAtoiKu4baV Grcw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=dGhsZmfi; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w4-20020a656944000000b004767ab6d0ffsi17111018pgq.231.2022.12.06.07.34.15; Tue, 06 Dec 2022 07:34:29 -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; dkim=pass header.i=@chromium.org header.s=google header.b=dGhsZmfi; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234265AbiLFPY2 (ORCPT + 99 others); Tue, 6 Dec 2022 10:24:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234612AbiLFPYJ (ORCPT ); Tue, 6 Dec 2022 10:24:09 -0500 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1C05AED for ; Tue, 6 Dec 2022 07:24:08 -0800 (PST) Received: by mail-pg1-x535.google.com with SMTP id w37so13658345pga.5 for ; Tue, 06 Dec 2022 07:24:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BMuCN4bdPpTwWJ2iwnu2KEtJZwK23OdE1QXZ74xgH4g=; b=dGhsZmfi5+VUhJDsVMAzLNo+4XoNKPtjOze+pgfgQ+R70pJlF5w/azLCgFEntA1tzV t1LrXSBXciQXzsyINZcoWUlgxdUzDXbX3GfYYVKdRj47c9IcfxjlCdk/mZECyPlyofuc Jg74RGbsKughRMWj7+nIw4dUW5NMU2EWiQL0I= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BMuCN4bdPpTwWJ2iwnu2KEtJZwK23OdE1QXZ74xgH4g=; b=b8qrksBVp/+yOVmDREask/ltMjtAoUm5Tgwr7OzP2iginiyXYa37r6SWkQ9IhybXKf p6K+AKpnVelZufFz0vvPYbV8u/jMXuHmJ6dqA0I+jMwu4VH9GCLi23mLuvcEdoSUh7/P 2jtwlmLzom9TriIUaQ1omb941iVw38Oc77ZnuLQWBX6m54PDm+CLeRyaWhwOZzy2mU21 zZkk6wNIO6c/Dh/Oz9uum6qLEFE3mxLj8aR0rdS7YsMbCZcOG3Iorhw1zR3R+2JQMf2T ZQX2BlC4ITMrDzsxdbYAZWCz6+JiNiPVUoWPOalC5ctohbnI/oc6YY07m+9898y2iTty QThg== X-Gm-Message-State: ANoB5pmRpHnjfu4RQIk8zb1B1kx8+HLUvTZDQwTvJ1wwzfzXsNxWxMQu 9TfOm8mEhLW4inx4WCaxZc9rWw== X-Received: by 2002:a05:6a00:4501:b0:56b:b049:6c6c with SMTP id cw1-20020a056a00450100b0056bb0496c6cmr74263210pfb.22.1670340247616; Tue, 06 Dec 2022 07:24:07 -0800 (PST) Received: from jeffxud.c.googlers.com.com (30.202.168.34.bc.googleusercontent.com. [34.168.202.30]) by smtp.gmail.com with ESMTPSA id r25-20020a635d19000000b0046b1dabf9a8sm10004686pgb.70.2022.12.06.07.24.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 07:24:06 -0800 (PST) From: jeffxu@chromium.org To: skhan@linuxfoundation.org, keescook@chromium.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, jannh@google.com, linux-hardening@vger.kernel.org, Jeff Xu Subject: [PATCH v5 5/6] selftests/memfd: add tests for MFD_NOEXEC_SEAL MFD_EXEC Date: Tue, 6 Dec 2022 15:23:57 +0000 Message-Id: <20221206152358.1966099-6-jeffxu@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog In-Reply-To: <20221206152358.1966099-1-jeffxu@google.com> References: <20221206152358.1966099-1-jeffxu@google.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE autolearn=unavailable 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?1751479347353112916?= X-GMAIL-MSGID: =?utf-8?q?1751479347353112916?= From: Jeff Xu Tests to verify MFD_NOEXEC, MFD_EXEC and vm.memfd_noexec sysctl. Signed-off-by: Jeff Xu Co-developed-by: Daniel Verkamp Signed-off-by: Daniel Verkamp Change-Id: Idccec1141255ca948c849f4efc8ba5e97f78b6eb --- tools/testing/selftests/memfd/fuse_test.c | 1 + tools/testing/selftests/memfd/memfd_test.c | 185 ++++++++++++++++++++- 2 files changed, 181 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/memfd/fuse_test.c b/tools/testing/selftests/memfd/fuse_test.c index be675002f918..93798c8c5d54 100644 --- a/tools/testing/selftests/memfd/fuse_test.c +++ b/tools/testing/selftests/memfd/fuse_test.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c index 1d7e7b36bbdd..7fc78ff62d40 100644 --- a/tools/testing/selftests/memfd/memfd_test.c +++ b/tools/testing/selftests/memfd/memfd_test.c @@ -32,10 +32,20 @@ #define F_SEAL_EXEC 0x0020 #endif +#define F_WX_SEALS (F_SEAL_SHRINK | \ + F_SEAL_GROW | \ + F_SEAL_WRITE | \ + F_SEAL_FUTURE_WRITE | \ + F_SEAL_EXEC) + #ifndef MAX_PATH #define MAX_PATH 256 #endif +#ifndef MFD_NOEXEC_SEAL +#define MFD_NOEXEC_SEAL 0x0008U +#endif + /* * Default is not to test hugetlbfs */ @@ -86,6 +96,21 @@ static int mfd_assert_new(const char *name, loff_t sz, unsigned int flags) return fd; } +static void sysctl_assert_write(const char *val) +{ + int fd = open("/proc/sys/vm/memfd_noexec", O_WRONLY | O_CLOEXEC); + + if (fd < 0) { + printf("open sysctl failed\n"); + abort(); + } + + if (write(fd, val, strlen(val)) < 0) { + printf("write sysctl failed\n"); + abort(); + } +} + static int mfd_assert_reopen_fd(int fd_in) { int fd; @@ -764,6 +789,9 @@ static void test_create(void) mfd_fail_new("", ~0); mfd_fail_new("", 0x80000000U); + /* verify EXEC and NOEXEC_SEAL can't both be set */ + mfd_fail_new("", MFD_EXEC | MFD_NOEXEC_SEAL); + /* verify MFD_CLOEXEC is allowed */ fd = mfd_assert_new("", 0, MFD_CLOEXEC); close(fd); @@ -975,20 +1003,21 @@ static void test_seal_resize(void) /* * Test SEAL_EXEC - * Test that chmod() cannot change x bits after sealing + * Test fd is created with exec and allow sealing. + * chmod() cannot change x bits after sealing. */ -static void test_seal_exec(void) +static void test_exec_seal(void) { int fd; printf("%s SEAL-EXEC\n", memfd_str); + printf("%s Apply SEAL_EXEC\n", memfd_str); fd = mfd_assert_new("kern_memfd_seal_exec", mfd_def_size, - MFD_CLOEXEC | MFD_ALLOW_SEALING); + MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_EXEC); mfd_assert_mode(fd, 0777); - mfd_assert_chmod(fd, 0644); mfd_assert_has_seals(fd, 0); @@ -1002,10 +1031,152 @@ static void test_seal_exec(void) mfd_fail_chmod(fd, 0700); mfd_fail_chmod(fd, 0100); mfd_assert_chmod(fd, 0666); + mfd_assert_write(fd); + close(fd); + + printf("%s Apply ALL_SEALS\n", memfd_str); + fd = mfd_assert_new("kern_memfd_seal_exec", + mfd_def_size, + MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_EXEC); + + mfd_assert_mode(fd, 0777); + mfd_assert_chmod(fd, 0700); + + mfd_assert_has_seals(fd, 0); + mfd_assert_add_seals(fd, F_SEAL_EXEC); + mfd_assert_has_seals(fd, F_WX_SEALS); + mfd_fail_chmod(fd, 0711); + mfd_fail_chmod(fd, 0600); + mfd_fail_write(fd); close(fd); } +/* + * Test EXEC_NO_SEAL + * Test fd is created with exec and not allow sealing. + */ +static void test_exec_no_seal(void) +{ + int fd; + + printf("%s EXEC_NO_SEAL\n", memfd_str); + + /* Create with EXEC but without ALLOW_SEALING */ + fd = mfd_assert_new("kern_memfd_exec_no_sealing", + mfd_def_size, + MFD_CLOEXEC | MFD_EXEC); + mfd_assert_mode(fd, 0777); + mfd_assert_has_seals(fd, F_SEAL_SEAL); + mfd_assert_chmod(fd, 0666); + close(fd); +} + +/* + * Test memfd_create with MFD_NOEXEC flag + */ +static void test_noexec_seal(void) +{ + int fd; + + printf("%s NOEXEC_SEAL\n", memfd_str); + + /* Create with NOEXEC and ALLOW_SEALING */ + fd = mfd_assert_new("kern_memfd_noexec", + mfd_def_size, + MFD_CLOEXEC | MFD_ALLOW_SEALING | MFD_NOEXEC_SEAL); + 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 = mfd_assert_new("kern_memfd_noexec", + mfd_def_size, + MFD_CLOEXEC | MFD_NOEXEC_SEAL); + mfd_assert_mode(fd, 0666); + mfd_assert_has_seals(fd, F_SEAL_EXEC); + mfd_fail_chmod(fd, 0777); + close(fd); +} + +static void test_sysctl_child(void) +{ + int fd, pid, ret; + + printf("%s sysctl 0\n", memfd_str); + sysctl_assert_write("0"); + fd = mfd_assert_new("kern_memfd_sysctl_0", + mfd_def_size, + MFD_CLOEXEC | MFD_ALLOW_SEALING); + + mfd_assert_mode(fd, 0777); + mfd_assert_has_seals(fd, 0); + mfd_assert_chmod(fd, 0644); + close(fd); + + printf("%s sysctl 1\n", memfd_str); + sysctl_assert_write("1"); + fd = mfd_assert_new("kern_memfd_sysctl_1", + mfd_def_size, + MFD_CLOEXEC | MFD_ALLOW_SEALING); + + mfd_assert_mode(fd, 0666); + mfd_assert_has_seals(fd, F_SEAL_EXEC); + mfd_fail_chmod(fd, 0777); + close(fd); + + printf("%s sysctl 2\n", memfd_str); + sysctl_assert_write("2"); + mfd_fail_new("kern_memfd_sysctl_2", + MFD_CLOEXEC | MFD_ALLOW_SEALING); +} + +static int newpid_thread_fn(void *arg) +{ + test_sysctl_child(); + return 0; +} + +static pid_t spawn_newpid_thread(unsigned int flags) +{ + uint8_t *stack; + pid_t pid; + + stack = malloc(STACK_SIZE); + if (!stack) { + printf("malloc(STACK_SIZE) failed: %m\n"); + abort(); + } + + pid = clone(newpid_thread_fn, + stack + STACK_SIZE, + SIGCHLD | flags, + NULL); + if (pid < 0) { + printf("clone() failed: %m\n"); + abort(); + } + + return pid; +} + +static void join_newpid_thread(pid_t pid) +{ + waitpid(pid, NULL, 0); +} + +/* + * Test sysctl + * A very basic sealing test to see whether setting/retrieving seals works. + */ +static void test_sysctl(void) +{ + int pid = spawn_newpid_thread(CLONE_NEWPID); + + join_newpid_thread(pid); +} + /* * Test sharing via dup() * Test that seals are shared between dupped FDs and they're all equal. @@ -1179,13 +1350,15 @@ int main(int argc, char **argv) test_create(); test_basic(); + test_exec_seal(); + test_exec_no_seal(); + test_noexec_seal(); test_seal_write(); test_seal_future_write(); test_seal_shrink(); test_seal_grow(); test_seal_resize(); - test_seal_exec(); test_share_dup("SHARE-DUP", ""); test_share_mmap("SHARE-MMAP", ""); @@ -1201,6 +1374,8 @@ int main(int argc, char **argv) test_share_fork("SHARE-FORK", SHARED_FT_STR); join_idle_thread(pid); + test_sysctl(); + printf("memfd: DONE\n"); return 0; From patchwork Tue Dec 6 15:23:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Xu X-Patchwork-Id: 30382 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2890231wrr; Tue, 6 Dec 2022 07:34:45 -0800 (PST) X-Google-Smtp-Source: AA0mqf78TiIyXEeSfveK7YycONQ+gpZT1Z8fh6xTPbGUxGCrk4RnJ7rfJQ8CnkuihbaH3zvkTL3f X-Received: by 2002:a63:941:0:b0:478:a350:77ed with SMTP id 62-20020a630941000000b00478a35077edmr12647814pgj.417.1670340885032; Tue, 06 Dec 2022 07:34:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670340885; cv=none; d=google.com; s=arc-20160816; b=WWBDwZFRi3ZwjJ3dp71jEApXTDmqxJ9KwImy6yCKI+LHXF3VaChQXGljcHeJUhspXt l6z3UlqzbwszP1wwcDqfvaM/ZYXRC+TDqzMJZx8rlqu0Ef910zWUPj2svXWs8FABhTk/ TD319UEZ4zvLhGmZYNlSO/1m5zMzsh74w0QhTpRrtXZtYotrT8TA/LTAPeB68GgDzDsn Q4XFlEyUKHboRZbhYH/W37K5RBAQ86Xe7MX/qFROKYtVZNsDCPDeJbU4rd3CZRlCdEkc /IwbVzYKiaw5KBRinq2QzX25J9xVz8t9MuS6vrxeKHKApeP6SdHLZ3hlV7cmDn5Gg3Fi UxNg== 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 :dkim-signature; bh=RP30KXKl/PR6YPpKgU+DDNG5UwR2kZxBVDTlEl1cNxU=; b=TTYUUrueI90cHMKXlBX6FFE8Ml3Z6lK83ZgEJywsGuvIoOtF9kjmYq5Vu9CARmRYUi u9QB+e6ztbdceq+U71hBuW89KfEx7N+PSrGtquWCrvxGwoCUShvG+tvHUOf40QATU8QM sOSa07QzrE7JA4ARbk9xZvduqGE4E3li+OYlBVS+4519sLypRFkY+zK3bS7TBdmjHpWR cUJzMHtVhn0v1EYoOYk40oZMMxp6bYquBh4+YGyglqrxvvYW6drxhUNs3cx2qr4uiX++ lUbE3oxOYtbUmGjfaTQ4G/qfHSJDFFXdatvGUGlD2pv/y6mWn6bzSI6Ib2Tl8UtzN8dH 9ZjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=fmR1lznJ; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t6-20020a170902e84600b00186ba56bda8si19053379plg.61.2022.12.06.07.34.31; Tue, 06 Dec 2022 07:34:45 -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; dkim=pass header.i=@chromium.org header.s=google header.b=fmR1lznJ; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234507AbiLFPYb (ORCPT + 99 others); Tue, 6 Dec 2022 10:24:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234255AbiLFPYK (ORCPT ); Tue, 6 Dec 2022 10:24:10 -0500 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16B629FCA for ; Tue, 6 Dec 2022 07:24:09 -0800 (PST) Received: by mail-pj1-x102b.google.com with SMTP id v13-20020a17090a6b0d00b00219c3be9830so7162011pjj.4 for ; Tue, 06 Dec 2022 07:24:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RP30KXKl/PR6YPpKgU+DDNG5UwR2kZxBVDTlEl1cNxU=; b=fmR1lznJtSVRR9L4Ia3CMGkwAZ2v4hkWoOPZm7PR1nH/3nuAorOgqKoWJuydk4wqi1 4Jv46XmZFzLlrkx7ctSkFgyRoHoerAtS2sX3lfOp8Jl6EZM58L/vapg/v4JYZQWR5omU taxuDneZ5WG7Y4370lPtuckGfA3P8kfdDM44o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RP30KXKl/PR6YPpKgU+DDNG5UwR2kZxBVDTlEl1cNxU=; b=o7SG7IB/HDkknFDCyaryWMxppykh6rZxDStH5qKAP72aosuz13ELey8xjjMDuaJR0I gwW8PdRqEzf5bghBj+B7f8ZjrT9FnKHIlj+ANiLajAqCmP3ijVytvoKAQ5wFM37Lg210 3MGIgQfwURwzO9homtM/Rkq2/0t8MdMyFLwom+6q8uYlgGbdRkf7c6ChOSdlXXK2e1lo 3I5CUmzqyzmzZrRGL4rotH+s135DRpwr0UqwfCCCr7tyaKM2uriGvMiU/A/bUJK5nCm0 acsIMdkCzvKHrWgmAMlpHYXQVQ2oquFNwfNm4PiJ5Hkv9swpHBNcjgxXQCIsMe1lkElR s9GA== X-Gm-Message-State: ANoB5pnjismBucuRVzP572oV+tNsXs6R6mlZBbBak8Lu58E7h5rhupPg +C3ICojPmJJGhq3V2XHlC335Bg== X-Received: by 2002:a17:902:7898:b0:188:584d:b6d4 with SMTP id q24-20020a170902789800b00188584db6d4mr70697461pll.170.1670340248607; Tue, 06 Dec 2022 07:24:08 -0800 (PST) Received: from jeffxud.c.googlers.com.com (30.202.168.34.bc.googleusercontent.com. [34.168.202.30]) by smtp.gmail.com with ESMTPSA id r25-20020a635d19000000b0046b1dabf9a8sm10004686pgb.70.2022.12.06.07.24.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Dec 2022 07:24:07 -0800 (PST) From: jeffxu@chromium.org To: skhan@linuxfoundation.org, keescook@chromium.org Cc: akpm@linux-foundation.org, dmitry.torokhov@gmail.com, dverkamp@chromium.org, hughd@google.com, jeffxu@google.com, jorgelo@chromium.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, jannh@google.com, linux-hardening@vger.kernel.org, Jeff Xu , kernel test robot Subject: [PATCH v5 6/6] mm/memfd: security hook for memfd_create Date: Tue, 6 Dec 2022 15:23:58 +0000 Message-Id: <20221206152358.1966099-7-jeffxu@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog In-Reply-To: <20221206152358.1966099-1-jeffxu@google.com> References: <20221206152358.1966099-1-jeffxu@google.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE autolearn=unavailable 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?1751479363882343044?= X-GMAIL-MSGID: =?utf-8?q?1751479363882343044?= From: Jeff Xu The new security_memfd_create allows lsm to check flags of memfd_create. The security by default system (such as chromeos) can use this to implement system wide lsm to allow only non-executable memfd being created. Signed-off-by: Jeff Xu Reported-by: kernel test robot --- include/linux/lsm_hook_defs.h | 1 + include/linux/lsm_hooks.h | 4 ++++ include/linux/security.h | 6 ++++++ mm/memfd.c | 5 +++++ security/security.c | 13 +++++++++++++ 5 files changed, 29 insertions(+) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index ec119da1d89b..fd40840927c8 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -164,6 +164,7 @@ LSM_HOOK(int, 0, file_alloc_security, struct file *file) LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file) LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd, unsigned long arg) +LSM_HOOK(int, 0, memfd_create, char *name, unsigned int flags) LSM_HOOK(int, 0, mmap_addr, unsigned long addr) LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 4ec80b96c22e..5a18a6552278 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -543,6 +543,10 @@ * simple integer value. When @arg represents a user space pointer, it * should never be used by the security module. * Return 0 if permission is granted. + * @memfd_create: + * @name is the name of memfd file. + * @flags is the flags used in memfd_create. + * Return 0 if permission is granted. * @mmap_addr : * Check permissions for a mmap operation at @addr. * @addr contains virtual address that will be used for the operation. diff --git a/include/linux/security.h b/include/linux/security.h index ca1b7109c0db..5b87a780822a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -384,6 +384,7 @@ int security_file_permission(struct file *file, int mask); int security_file_alloc(struct file *file); void security_file_free(struct file *file); int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +int security_memfd_create(char *name, unsigned int flags); int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags); int security_mmap_addr(unsigned long addr); @@ -963,6 +964,11 @@ static inline int security_file_ioctl(struct file *file, unsigned int cmd, return 0; } +static inline int security_memfd_create(char *name, unsigned int flags) +{ + return 0; +} + static inline int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags) { diff --git a/mm/memfd.c b/mm/memfd.c index 92f0a5765f7c..f04ed5f0474f 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -356,6 +356,11 @@ SYSCALL_DEFINE2(memfd_create, goto err_name; } + /* security hook for memfd_create */ + error = security_memfd_create(name, flags); + if (error) + return error; + if (flags & MFD_HUGETLB) { file = hugetlb_file_setup(name, 0, VM_NORESERVE, HUGETLB_ANONHUGE_INODE, diff --git a/security/security.c b/security/security.c index 79d82cb6e469..5c018e080923 100644 --- a/security/security.c +++ b/security/security.c @@ -1010,6 +1010,19 @@ int security_sb_clone_mnt_opts(const struct super_block *oldsb, } EXPORT_SYMBOL(security_sb_clone_mnt_opts); +int security_add_mnt_opt(const char *option, const char *val, int len, + void **mnt_opts) +{ + return call_int_hook(sb_add_mnt_opt, -EINVAL, + option, val, len, mnt_opts); +} +EXPORT_SYMBOL(security_add_mnt_opt); + +int security_memfd_create(char *name, unsigned int flags) +{ + return call_int_hook(memfd_create, 0, name, flags); +} + int security_move_mount(const struct path *from_path, const struct path *to_path) { return call_int_hook(move_mount, 0, from_path, to_path);