From patchwork Thu Oct 12 17:04:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Stoakes X-Patchwork-Id: 13419484 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5BE0FCDB46E for ; Thu, 12 Oct 2023 17:04:49 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E6EE08D0138; Thu, 12 Oct 2023 13:04:48 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E1E478D0002; Thu, 12 Oct 2023 13:04:48 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id CC0B28D0138; Thu, 12 Oct 2023 13:04:48 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id B897A8D0002 for ; Thu, 12 Oct 2023 13:04:48 -0400 (EDT) Received: from smtpin10.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 8E6EBB5254 for ; Thu, 12 Oct 2023 17:04:48 +0000 (UTC) X-FDA: 81337433856.10.928DC8A Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) by imf16.hostedemail.com (Postfix) with ESMTP id 786A71800CD for ; Thu, 12 Oct 2023 17:04:36 +0000 (UTC) Authentication-Results: imf16.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=YPIFZHV4; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf16.hostedemail.com: domain of lstoakes@gmail.com designates 209.85.128.45 as permitted sender) smtp.mailfrom=lstoakes@gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1697130276; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=s8vXm3Rb5eaL+HF5MglErGcxxNG7EAs28QhToMLXn+Y=; b=5PmnjMQ9MWkNSCZeHutHwdeU9mA/eQZMJboiEZL9BDxZVzjSO6E0w9PxGuQ88KVVnpNTon wczGeWP7vyxVYFKrI9K8mi/p8davvAA+pKSAU2zN1jpfJVF8asuYdwuhtd62MFQVxQaWZU +kl17i8g4vfnVjr5U6wwdi2vV+/7SuU= ARC-Authentication-Results: i=1; imf16.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=YPIFZHV4; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf16.hostedemail.com: domain of lstoakes@gmail.com designates 209.85.128.45 as permitted sender) smtp.mailfrom=lstoakes@gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1697130276; a=rsa-sha256; cv=none; b=LMVo+mkAtBHVnOkfvlkLtQrB+bFyNWvaTNXd3bBPqEZ1SrnzPojcatbp2+loh5bOebKaWJ Qk0CmBzDacFNVnPLVRVVKf4NHRtDuRGirs1lde2XSglU22rzInKB5oAguFwzH+0Z7aXwkK WLOF7K4UFoHeGfaGhJEpNMsolBB0BPs= Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-40572aeb73cso12923635e9.3 for ; Thu, 12 Oct 2023 10:04:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1697130274; x=1697735074; darn=kvack.org; 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=s8vXm3Rb5eaL+HF5MglErGcxxNG7EAs28QhToMLXn+Y=; b=YPIFZHV48IRcsCnYQUBVe8h1fW/Up+DOs0C8L8nOP+dVaPg0R1zHJ+wj+XpDOA8A4O iZXZLz+ymr6xUy/PlPe8Rctzcxy0L5lB7YnZfHeMzzg0Vp0jLtBNjGLjutZLc6OOJkt6 biFXoJdGiYBsNxMx2U/pwwO+URsfyk15N84wb6EWUh+uGXfFT1sHjW/CwuhM3HD/jcmB oaKDoR9W8wT5HVP2X8/aHz6EfMxHmENsZ0U6IxLE23D2CLfwRP9jPkK4JpP8nIBUjzOv w+T4uXSoGhLhUmEmTss73uXnsbGCTrjF5Hv3hz1025UmsKnjqjBlercDJaN8C4iFTR2s OMAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697130274; x=1697735074; 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=s8vXm3Rb5eaL+HF5MglErGcxxNG7EAs28QhToMLXn+Y=; b=lQIuGfW3etkItf7g2VHV/PrAXa4HAsgq8YtArSmDaQf5ik52tFRyij3Rb/9tr7npGp /VKo5hn8p/a3tu7sCt8rp8+z0IKTysOrGCbvghhBTjfYK7IVedlWfbwsYI1GyjJc0WIa INxkbOe6Xeonur0e8AIkErei89FWSXgzW8QwMO5Zi3C/QSBZ19cUtCsfNsbz2Zk/2zm/ YltZPnr+N0PcpueZUI/SFBD06/soEea4lX4vuoh9wevTs3vUazJgAPyBHddeZqEYvwcP COTvc8ImZECRtbLsTm69jpa8e6QXW+uwaPWxRRPDe875Yy0Q6h/Ai+Rq4J2Aq/FamLgd 7/qQ== X-Gm-Message-State: AOJu0Yxw/JfECqCWI2jHaxpxoq3+r47RlR/A4TiG/426YBn8i2Fo1wB0 +OSlunIqGzhrZO233Gj36bDLIzIN25s= X-Google-Smtp-Source: AGHT+IG1WtI4624aFb3uDRoHHKgnKF/CRfbpjPSiwsKx3X2z2FPwp37I71ARseeuIXbEk1RVZb30MA== X-Received: by 2002:a5d:458f:0:b0:321:6ff5:9256 with SMTP id p15-20020a5d458f000000b003216ff59256mr19911164wrq.58.1697130274280; Thu, 12 Oct 2023 10:04:34 -0700 (PDT) Received: from lucifer.home ([2a00:23c5:dc8c:8701:1663:9a35:5a7b:1d76]) by smtp.googlemail.com with ESMTPSA id h16-20020adffd50000000b003197869bcd7sm18875418wrs.13.2023.10.12.10.04.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 12 Oct 2023 10:04:33 -0700 (PDT) From: Lorenzo Stoakes To: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrew Morton Cc: Mike Kravetz , Muchun Song , Alexander Viro , Christian Brauner , Matthew Wilcox , Hugh Dickins , Andy Lutomirski , Jan Kara , linux-fsdevel@vger.kernel.org, bpf@vger.kernel.org, Lorenzo Stoakes Subject: [PATCH v4 1/3] mm: drop the assumption that VM_SHARED always implies writable Date: Thu, 12 Oct 2023 18:04:28 +0100 Message-ID: X-Mailer: git-send-email 2.42.0 In-Reply-To: References: MIME-Version: 1.0 X-Rspam-User: X-Stat-Signature: 4ppbubyinmt95ke75dwxr5pung6uu8ip X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: 786A71800CD X-HE-Tag: 1697130276-268442 X-HE-Meta: U2FsdGVkX1+U0mPeInX6Y6s7Pxdk3zsFIodhDojngmNM27cOLK5R0+JiPZ6Tnnvy9VJ5EKkRLAtSWzHnN4HrgxOn4mXuFsGt2RLSSZP1VUqT7dp1pVSz4bVXnk2SSGu3FIldq3IRpOSkhQJXV0UMujZgwsJ5o1BYr5GgOAdDFLz0TFt5cJNWz1sWh4Bc9GbsT7FK2P/ECeHZwvyY6umX1rhzCHs9wyt4UgE/m3fIgiir1CmgB77iUKvjw3ENio8pfe7+4/o3HlGlfCUkIvKuLn067x8xCAQ2JZBBCTVlOrGC2r/6Xw7gl6hLAIc5AZPd1n+38MeZo+BH8hYzlJ7WiWDyPNa5g7mYFHcHZdV/OGB4PjGp+UHER8y7SiRS7SeNmKjWeaWvC+2LwBXlFVF0tKn/bbhyuNVxOzcn3I4iFlIM15PXjfEA5DASowEHGBL0vFiepSvnZw+xAJd76KCsBQpF2x9cFiUjf4IqJeFmgLzJJARogy8uaBFS6WNHioVMcCl/OoRwODxqFBZDCPhw+3c2OWdacC6XRPpoYp/emHMatPqmu9HclwjYVrp9DFyQ2K+SgDxr7J4jHdGAB0/CTEspNuQdSsFJxMweW0tC8hadmvoBMEAENIrent8W3udgmy+Eh71afyggxaR2P+KbY9Hm0So70R+wmmqcpR4/BZNisda59hh7Vz1yev8Yr8LTVKJCffJ+HbpUlO7zjyvdcASvBDAYa41nkWeGRg7vjeuDOPCXf17lNWp0x49zOK784DyiAqKv+uB+yP8AS+Udo1gCwQcCknIjNtdE0H6UkFu3BysIo4YcMHmBOxEfFpKRfH5zTof/1USoyK70z+qgD8e55rfgQa+7ydMCNaOzbL4R6vLJ4RAJqYqxg/wF3tPamFz+uknjrIzhWBXI3ic23zkEnwaS19xJDK4DADpDfPZfiD2u19dZkO6uki61kvzBilaHQLzpNMzKcqd5Fe+ gLTk1yf9 eD27/lnTR1esUxvRm97fNxucbXz/BWDfBkYI4EcCP0Amw9/WEm8DfpKosP+bxUQ5C83gpWPaFzDhqX/FFgXjtfF8zndA4/W933C9wF4KCEDjLNnT8/qgYxQ3gyLPgJ62I4mMaTXo4kZzvwUmooaS5eXyoA+rBPg+ZHIgzGxpDPqmp4ylO9kkAD6YCXPDXO4HujcLlYhuzf+SrlPZ4caAURFeKOz0wI/OaQzvm6u3dhU3pcIDoaoHVq/aU3Awlz4ck3ay3Aszh1imFQAyaf3HBygHYYOSLXKekwWFI/yO6U5sub8g9fX9ZbItUOUmwu2p8FymCF3mnO7cFZ3OdFGHWrxDsl3Ppk2dfsiKdsTEL5iykHlfO3pmhKcrElGmCR0F7D8ENgxByeB5DLupjKiB1oirKoDopfAlMPdjd1gLgZik05/xYan6HPJoFyEyBKcA7XUP2iMzCZ2nqOWQSsGW6ug7VykEU1RZSXqEmF6wb2fHefvbL5eF0u2vIG5THVf1E9USBruRJzR5DMEHgbGya9CTJdZmH76tyDP7D X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: There is a general assumption that VMAs with the VM_SHARED flag set are writable. If the VM_MAYWRITE flag is not set, then this is simply not the case. Update those checks which affect the struct address_space->i_mmap_writable field to explicitly test for this by introducing [vma_]is_shared_maywrite() helper functions. This remains entirely conservative, as the lack of VM_MAYWRITE guarantees that the VMA cannot be written to. Suggested-by: Andy Lutomirski Signed-off-by: Lorenzo Stoakes --- include/linux/fs.h | 4 ++-- include/linux/mm.h | 11 +++++++++++ kernel/fork.c | 2 +- mm/filemap.c | 2 +- mm/madvise.c | 2 +- mm/mmap.c | 12 ++++++------ 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/include/linux/fs.h b/include/linux/fs.h index 92a9c6157de1..e9c03fb00d5c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -454,7 +454,7 @@ extern const struct address_space_operations empty_aops; * It is also used to block modification of page cache contents through * memory mappings. * @gfp_mask: Memory allocation flags to use for allocating pages. - * @i_mmap_writable: Number of VM_SHARED mappings. + * @i_mmap_writable: Number of VM_SHARED, VM_MAYWRITE mappings. * @nr_thps: Number of THPs in the pagecache (non-shmem only). * @i_mmap: Tree of private and shared mappings. * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable. @@ -557,7 +557,7 @@ static inline int mapping_mapped(struct address_space *mapping) /* * Might pages of this file have been modified in userspace? - * Note that i_mmap_writable counts all VM_SHARED vmas: do_mmap + * Note that i_mmap_writable counts all VM_SHARED, VM_MAYWRITE vmas: do_mmap * marks vma as VM_SHARED if it is shared, and the file was opened for * writing i.e. vma may be mprotected writable even if now readonly. * diff --git a/include/linux/mm.h b/include/linux/mm.h index 74d7547ffb70..bae234d18d81 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -937,6 +937,17 @@ static inline bool vma_is_accessible(struct vm_area_struct *vma) return vma->vm_flags & VM_ACCESS_FLAGS; } +static inline bool is_shared_maywrite(vm_flags_t vm_flags) +{ + return (vm_flags & (VM_SHARED | VM_MAYWRITE)) == + (VM_SHARED | VM_MAYWRITE); +} + +static inline bool vma_is_shared_maywrite(struct vm_area_struct *vma) +{ + return is_shared_maywrite(vma->vm_flags); +} + static inline struct vm_area_struct *vma_find(struct vma_iterator *vmi, unsigned long max) { diff --git a/kernel/fork.c b/kernel/fork.c index e45a4457ba83..1e6c656e0857 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -733,7 +733,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, get_file(file); i_mmap_lock_write(mapping); - if (tmp->vm_flags & VM_SHARED) + if (vma_is_shared_maywrite(tmp)) mapping_allow_writable(mapping); flush_dcache_mmap_lock(mapping); /* insert tmp into the share list, just after mpnt */ diff --git a/mm/filemap.c b/mm/filemap.c index 9ef49255f1a5..9710f43a89ac 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3618,7 +3618,7 @@ int generic_file_mmap(struct file *file, struct vm_area_struct *vma) */ int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma) { - if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) + if (vma_is_shared_maywrite(vma)) return -EINVAL; return generic_file_mmap(file, vma); } diff --git a/mm/madvise.c b/mm/madvise.c index 70dafc99ff1e..6214a1ab5654 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -981,7 +981,7 @@ static long madvise_remove(struct vm_area_struct *vma, return -EINVAL; } - if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)) + if (!vma_is_shared_maywrite(vma)) return -EACCES; offset = (loff_t)(start - vma->vm_start) diff --git a/mm/mmap.c b/mm/mmap.c index 3ea52451623b..0041e3631f6c 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -107,7 +107,7 @@ void vma_set_page_prot(struct vm_area_struct *vma) static void __remove_shared_vm_struct(struct vm_area_struct *vma, struct file *file, struct address_space *mapping) { - if (vma->vm_flags & VM_SHARED) + if (vma_is_shared_maywrite(vma)) mapping_unmap_writable(mapping); flush_dcache_mmap_lock(mapping); @@ -384,7 +384,7 @@ static unsigned long count_vma_pages_range(struct mm_struct *mm, static void __vma_link_file(struct vm_area_struct *vma, struct address_space *mapping) { - if (vma->vm_flags & VM_SHARED) + if (vma_is_shared_maywrite(vma)) mapping_allow_writable(mapping); flush_dcache_mmap_lock(mapping); @@ -2846,7 +2846,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, vma->vm_pgoff = pgoff; if (file) { - if (vm_flags & VM_SHARED) { + if (is_shared_maywrite(vm_flags)) { error = mapping_map_writable(file->f_mapping); if (error) goto free_vma; @@ -2920,7 +2920,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, mm->map_count++; if (vma->vm_file) { i_mmap_lock_write(vma->vm_file->f_mapping); - if (vma->vm_flags & VM_SHARED) + if (vma_is_shared_maywrite(vma)) mapping_allow_writable(vma->vm_file->f_mapping); flush_dcache_mmap_lock(vma->vm_file->f_mapping); @@ -2937,7 +2937,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, /* Once vma denies write, undo our temporary denial count */ unmap_writable: - if (file && vm_flags & VM_SHARED) + if (file && is_shared_maywrite(vm_flags)) mapping_unmap_writable(file->f_mapping); file = vma->vm_file; ksm_add_vma(vma); @@ -2985,7 +2985,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, unmap_region(mm, &vmi.mas, vma, prev, next, vma->vm_start, vma->vm_end, vma->vm_end, true); } - if (file && (vm_flags & VM_SHARED)) + if (file && is_shared_maywrite(vm_flags)) mapping_unmap_writable(file->f_mapping); free_vma: vm_area_free(vma);