From patchwork Thu Nov 7 19:53:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Fernandes X-Patchwork-Id: 11233695 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 998E014E5 for ; Thu, 7 Nov 2019 19:54:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 76DFB21D7E for ; Thu, 7 Nov 2019 19:54:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=joelfernandes.org header.i=@joelfernandes.org header.b="MF2KEhws" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726019AbfKGTyD (ORCPT ); Thu, 7 Nov 2019 14:54:03 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:32768 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725818AbfKGTyD (ORCPT ); Thu, 7 Nov 2019 14:54:03 -0500 Received: by mail-pf1-f195.google.com with SMTP id c184so3259842pfb.0 for ; Thu, 07 Nov 2019 11:54:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=joelfernandes.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Ghp1ccQ5fcbrX+RPWdRWrW5V+/l6RykYTQKYb1Z+Wp4=; b=MF2KEhwsFOY2JznvdfjXOUNj6W3qYNeau+VKgjLdGcoHKMwypDOQ9+KNmwpoguPBnA 7i/obFhGjyKDKsUMxeH64dpCWx1uMOpGLtazJ2WOFQJj2EgXR2EKcxlrJHXs+HFIxiKU AjzqDaEAAzRnfgvLsssB5KV+gpsE0RcbDcp+E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Ghp1ccQ5fcbrX+RPWdRWrW5V+/l6RykYTQKYb1Z+Wp4=; b=h7PLnicgwdhgQnNMg1r8Cb4jQ+FbZp897xlWUHJqosfKfbHbr2oqguBtH6f5PbrOhB kZ9R/6Mou7K95Bcw5pi6J79w/5wxFVhdGxO1ErfERSSTk/iQaf/Wf8xjJUKwVI9CmzzB MHMTfUuB3xMF7pl5Itgvu6pw6wFr6LKtaqgATO3XFfGVPLDcdMrqQqF8DYmhd0sdpEKC iYF8byFMib8bwi87vAOIkrwz569ilmRiBWAiy8vdfHH/F261Bxx2z5MTi6LfCV5Hfylh Hwym84aDRooiqYLpF3xTI5LErfbhnmq7U4i12BDBWzfL3Uz+SLp8GEDyO+xaJwy2vG74 ocuw== X-Gm-Message-State: APjAAAWHHBF3fnxbJ4eoCH5owIG0CNbmbA/H1kL2xpWj+Jxi6tqjunB9 xPdCOASf7ItUuzeB+mi7fSWIKw== X-Google-Smtp-Source: APXvYqxa4V3GDy6MxEr8e4GyHJt30Yq7/f7FjZfuQPYkIlqBQ0ZxitLHpBCbWZAaGGArGLkuPC825w== X-Received: by 2002:a63:f852:: with SMTP id v18mr4706535pgj.71.1573156442796; Thu, 07 Nov 2019 11:54:02 -0800 (PST) Received: from joelaf.cam.corp.google.com ([2620:15c:6:12:9c46:e0da:efbf:69cc]) by smtp.gmail.com with ESMTPSA id y2sm3365870pfe.126.2019.11.07.11.54.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2019 11:54:02 -0800 (PST) From: "Joel Fernandes (Google)" To: linux-kernel@vger.kernel.org Cc: Nicolas Geoffray , kernel-team@android.com, Joel Fernandes , Andrew Morton , Hugh Dickins , linux-kselftest@vger.kernel.org, linux-mm@kvack.org, Shuah Khan Subject: [PATCH 1/2] memfd: Fix COW issue on MAP_PRIVATE and F_SEAL_FUTURE_WRITE mappings Date: Thu, 7 Nov 2019 14:53:54 -0500 Message-Id: <20191107195355.80608-1-joel@joelfernandes.org> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org From: Nicolas Geoffray F_SEAL_FUTURE_WRITE has unexpected behavior when used with MAP_PRIVATE: A private mapping created after the memfd file that gets sealed with F_SEAL_FUTURE_WRITE loses the copy-on-write at fork behavior, meaning children and parent share the same memory, even though the mapping is private. The reason for this is due to the code below: static int shmem_mmap(struct file *file, struct vm_area_struct *vma) { struct shmem_inode_info *info = SHMEM_I(file_inode(file)); if (info->seals & F_SEAL_FUTURE_WRITE) { /* * New PROT_WRITE and MAP_SHARED mmaps are not allowed when * "future write" seal active. */ if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_WRITE)) return -EPERM; /* * Since the F_SEAL_FUTURE_WRITE seals allow for a MAP_SHARED * read-only mapping, take care to not allow mprotect to revert * protections. */ vma->vm_flags &= ~(VM_MAYWRITE); } ... } And for the mm to know if a mapping is copy-on-write: static inline bool is_cow_mapping(vm_flags_t flags) { return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; } The patch fixes the issue by making the mprotect revert protection happen only for shared mappings. For private mappings, using mprotect will have no effect on the seal behavior. Cc: kernel-team@android.com Signed-off-by: Nicolas Geoffray Signed-off-by: Joel Fernandes (Google) --- Google bug: 143833776 mm/shmem.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index 447fd575587c..6ac5e867ef13 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2214,11 +2214,14 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) return -EPERM; /* - * Since the F_SEAL_FUTURE_WRITE seals allow for a MAP_SHARED - * read-only mapping, take care to not allow mprotect to revert - * protections. + * Since an F_SEAL_FUTURE_WRITE sealed memfd can be mapped as + * MAP_SHARED and read-only, take care to not allow mprotect to + * revert protections on such mappings. Do this only for shared + * mappings. For private mappings, don't need to mask VM_MAYWRITE + * as we still want them to be COW-writable. */ - vma->vm_flags &= ~(VM_MAYWRITE); + if (vma->vm_flags & VM_SHARED) + vma->vm_flags &= ~(VM_MAYWRITE); } file_accessed(file); From patchwork Thu Nov 7 19:53:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Fernandes X-Patchwork-Id: 11233699 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 808A614E5 for ; Thu, 7 Nov 2019 19:54:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5E819222C5 for ; Thu, 7 Nov 2019 19:54:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=joelfernandes.org header.i=@joelfernandes.org header.b="xJlo1DuP" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726989AbfKGTyF (ORCPT ); Thu, 7 Nov 2019 14:54:05 -0500 Received: from mail-pg1-f193.google.com ([209.85.215.193]:43170 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725844AbfKGTyF (ORCPT ); Thu, 7 Nov 2019 14:54:05 -0500 Received: by mail-pg1-f193.google.com with SMTP id l24so2654356pgh.10 for ; Thu, 07 Nov 2019 11:54:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=joelfernandes.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Yt65JEzI8B4ThC22+VCw7CM+LK+ArEMO8/zLSXCHvk0=; b=xJlo1DuPB3YVBQAgFBR+GjVfwFtDBuQ75nv+sOnYtZPQ9qSXZxB8HraZUGDFxy1Drz f71wLXCjXxGHlCCs4z60NYnl14ny5cszdYwgmbJgZFxncgjtZ1MXyr1R/0NkJ+bOhIbG 3pRidFtRgR2sgu8rJHSs23dG8WMz3UGcczVaM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Yt65JEzI8B4ThC22+VCw7CM+LK+ArEMO8/zLSXCHvk0=; b=f2ZV3VRm9moH6dMoSVr+KmPzr56AbAuc++MsOJx0vD9V2D1NZ1HZ7P7vav17LAegnL new7wwx/0J6iFdMzbZMoaUyB8ZIS2kKj4eOnvNHooNEzCe9gbj7y3LLHnStTkSUTAGdZ ibcqOuzzQWEmt+y3uXhoJNyPeI+CIXtxt5dg2tQwJJaS7wLoXy3Kx0+nr0NEIYg1u1P0 tp+AyGWz5QhtHbovPgolasqOye9QrQ+soj5kKq/or6oV6h0rZNgPoxdFyyJ9hicPIBdP rp9lFhDXMlfpJzokwYLtQSDgGHS9l3SIZfp0hFrKt67jYyjrG6m3TAIHPQQEnjQbue+R hnMA== X-Gm-Message-State: APjAAAU42H86ZP42ZslV1ZYcUUyLNilY3YB9y7EbqN0gXKmV9MhhhmM0 1+OvnNLjKZZ+0QL+QUUmlVi6VA== X-Google-Smtp-Source: APXvYqyoeYqV+vMTE2cL67Ov6JWJRzPg3lrGLBosK857p3VGFNE53iEGD9JcdWLwOQIALLrrUutrDg== X-Received: by 2002:a63:d70f:: with SMTP id d15mr6903311pgg.424.1573156444237; Thu, 07 Nov 2019 11:54:04 -0800 (PST) Received: from joelaf.cam.corp.google.com ([2620:15c:6:12:9c46:e0da:efbf:69cc]) by smtp.gmail.com with ESMTPSA id y2sm3365870pfe.126.2019.11.07.11.54.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2019 11:54:03 -0800 (PST) From: "Joel Fernandes (Google)" To: linux-kernel@vger.kernel.org Cc: "Joel Fernandes (Google)" , Andrew Morton , Hugh Dickins , kernel-team@android.com, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, Shuah Khan Subject: [PATCH 2/2] memfd: Add test for COW on MAP_PRIVATE and F_SEAL_FUTURE_WRITE mappings Date: Thu, 7 Nov 2019 14:53:55 -0500 Message-Id: <20191107195355.80608-2-joel@joelfernandes.org> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog In-Reply-To: <20191107195355.80608-1-joel@joelfernandes.org> References: <20191107195355.80608-1-joel@joelfernandes.org> MIME-Version: 1.0 Sender: linux-kselftest-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org In this test, the parent and child both have writable private mappings. The test shows that without the patch in this series, the parent and child shared the same memory which is incorrect. In other words, COW needs to be triggered so any writes to child's copy stays local to the child. Signed-off-by: Joel Fernandes (Google) --- tools/testing/selftests/memfd/memfd_test.c | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c index c67d32eeb668..334a7eea2004 100644 --- a/tools/testing/selftests/memfd/memfd_test.c +++ b/tools/testing/selftests/memfd/memfd_test.c @@ -290,6 +290,40 @@ static void mfd_assert_read_shared(int fd) munmap(p, mfd_def_size); } +static void mfd_assert_fork_private_write(int fd) +{ + int *p; + pid_t pid; + + p = mmap(NULL, + mfd_def_size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE, + fd, + 0); + if (p == MAP_FAILED) { + printf("mmap() failed: %m\n"); + abort(); + } + + p[0] = 22; + + pid = fork(); + if (pid == 0) { + p[0] = 33; + exit(0); + } else { + waitpid(pid, NULL, 0); + + if (p[0] != 22) { + printf("MAP_PRIVATE copy-on-write failed: %m\n"); + abort(); + } + } + + munmap(p, mfd_def_size); +} + static void mfd_assert_write(int fd) { ssize_t l; @@ -760,6 +794,8 @@ static void test_seal_future_write(void) mfd_assert_read_shared(fd2); mfd_fail_write(fd2); + mfd_assert_fork_private_write(fd); + munmap(p, mfd_def_size); close(fd2); close(fd);