From patchwork Tue Apr 25 07:14:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Stoakes X-Patchwork-Id: 13222904 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 71E53C77B61 for ; Tue, 25 Apr 2023 07:14:24 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A22906B0071; Tue, 25 Apr 2023 03:14:23 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 9D2446B0074; Tue, 25 Apr 2023 03:14:23 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 873576B0075; Tue, 25 Apr 2023 03:14:23 -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 774096B0071 for ; Tue, 25 Apr 2023 03:14:23 -0400 (EDT) Received: from smtpin20.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 472A880190 for ; Tue, 25 Apr 2023 07:14:23 +0000 (UTC) X-FDA: 80719050006.20.30D7596 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) by imf08.hostedemail.com (Postfix) with ESMTP id 73D00160004 for ; Tue, 25 Apr 2023 07:14:21 +0000 (UTC) Authentication-Results: imf08.hostedemail.com; dkim=pass header.d=gmail.com header.s=20221208 header.b=H6uBR9WA; spf=pass (imf08.hostedemail.com: domain of lstoakes@gmail.com designates 209.85.128.51 as permitted sender) smtp.mailfrom=lstoakes@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1682406861; 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:references:dkim-signature; bh=yjgzdqrbPo7+Td+Wlne0g57m41H7q9g5vLYpPDzT+qw=; b=JOYkGJIMbWLfhIlYQKQuO9gQ32SRm9ExA6/BIb1EF3xnXok4DxXFUqaGHryV6UDRVEgVam EzwrUPeD8b5ljnbDL4wti3aik+WF+IRNewTYMGE3KII2YhUtU6J7C7M4YBlROH6S3DMIpu 4AhDG1ORdZb91Ln1QWno8A5NSQh3evc= ARC-Authentication-Results: i=1; imf08.hostedemail.com; dkim=pass header.d=gmail.com header.s=20221208 header.b=H6uBR9WA; spf=pass (imf08.hostedemail.com: domain of lstoakes@gmail.com designates 209.85.128.51 as permitted sender) smtp.mailfrom=lstoakes@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1682406861; a=rsa-sha256; cv=none; b=OvmHZEG4+73YC4qqw9mgfeHCZrBfXeDEK3LXxjpu5VOqqqQpbgwJYgc5Gg9OtuGBGyVY+f k67Z7aSQ9Nc4+0K7S0jTChHF0kV44+x8Obys2XrvOu84NIDtUr243cKquuc4hTiIgMUGWl Y9oCBUXknZhynyG2vES3r8eeokSVbTo= Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-3f178da21afso35364705e9.1 for ; Tue, 25 Apr 2023 00:14:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682406859; x=1684998859; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=yjgzdqrbPo7+Td+Wlne0g57m41H7q9g5vLYpPDzT+qw=; b=H6uBR9WAiN3nmtRogzKnpHyF+tj7CFYbFApxatJP1VLKGlPzsCJ25finM3hrSD0TEB XfOldeEJUhs/ALeP7EP6+mTWtQrLcql/7gRagSd2UsEVk6dOtOVqwu+fHLSYibPjJ6sb lfh1f+YYWcf4GP7VXXXzEejq9r0Co3wq2ip3LqUMigGlznjo31/lUKWLuIIc0IlTJIDb dL+v/hGG5bbSSG9J0HDhLj+KsUrvRopsq2vI0ls5gl/cgjerlsF9u86OWWWjJDtKmUdV IFPEkfr3t8/hkfk2cywUJTNAy1Ngjcu0MDpEQ4OwgZG18kbtqh1YdMWEM5VVO0i0Srmw cGGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682406859; x=1684998859; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=yjgzdqrbPo7+Td+Wlne0g57m41H7q9g5vLYpPDzT+qw=; b=Btfn33xUHDyXbusj/K4SL45x+M8uQGd6CqCxWaFgz2h8S+SFMK4rI8zm2pX8pph3Ro q6UMfiCmF0330XiD4l3jiLb2se+B66wpy/QtxwbP624yQugKS+NHmjAWsCh6H54IFRze qUy0neWK64S3XeSk1ES4sAgilzjxRIFa7INVM/3NhRvtqu0/2JxKd+ZFKYJA2CJ3vOme 0RNndnKwB5FMoz00wFXbYG4d5fe6HW+tH6E/74x8d2Ona5ihRvChYoWfUqqCDGIgM2cS LqhngPmKfuPFMyZnYeGKwuHOV8an8MpajMMPqG8s2dGmrABQuk1V+nj/iZDPbdgbztWG +s1w== X-Gm-Message-State: AAQBX9cEl6fbTpAdgXeiPbCP1KhQVKDQ2ZLb90SVFU/qy3nBlsVZOgQe HFQXncsN7EN56FXhuHhZArrawp16O+RSyg== X-Google-Smtp-Source: AKy350aSZ0ogFp8y55zCmLsghq92v+eab4GmjRhmzl2lUP7Ai4SILM+68B2FMmp0r+I/N2CUHcFWng== X-Received: by 2002:a7b:cd09:0:b0:3f1:6980:2d2e with SMTP id f9-20020a7bcd09000000b003f169802d2emr9984982wmj.22.1682406858687; Tue, 25 Apr 2023 00:14:18 -0700 (PDT) Received: from lucifer.home (host86-156-84-164.range86-156.btcentralplus.com. [86.156.84.164]) by smtp.googlemail.com with ESMTPSA id c16-20020a05600c0ad000b003f198dfbbfcsm8382138wmr.19.2023.04.25.00.14.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Apr 2023 00:14:17 -0700 (PDT) From: Lorenzo Stoakes To: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Andrew Morton Cc: Jason Gunthorpe , Jens Axboe , Matthew Wilcox , Dennis Dalessandro , Leon Romanovsky , Christian Benvenuti , Nelson Escobar , Bernard Metzler , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , Bjorn Topel , Magnus Karlsson , Maciej Fijalkowski , Jonathan Lemon , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Christian Brauner , Richard Cochran , Alexei Starovoitov , Daniel Borkmann , Jesper Dangaard Brouer , John Fastabend , linux-fsdevel@vger.kernel.org, linux-perf-users@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, Oleg Nesterov , Jason Gunthorpe , John Hubbard , Jan Kara , "Kirill A . Shutemov" , Pavel Begunkov , Lorenzo Stoakes Subject: [PATCH v3] mm/gup: disallow GUP writing to file-backed mappings by default Date: Tue, 25 Apr 2023 08:14:14 +0100 Message-Id: <23c19e27ef0745f6d3125976e047ee0da62569d4.1682406295.git.lstoakes@gmail.com> X-Mailer: git-send-email 2.40.0 MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 73D00160004 X-Stat-Signature: d1exf5qsx6izixeua8q5ekd1tk9zpw9d X-HE-Tag: 1682406861-597536 X-HE-Meta: U2FsdGVkX191Zn4lvyGUo9KaROHeaB1zZfK2TZBc9FwOomBNrWz/wI7Tk2O9a4UK/rR+yHundERKjdFqoI25TuOKYGbps0t+IOejIQKkGOtK3aCtrzZJQuMjmznVLPY0mzvwWO8lkPcvCyl3n2Tmqgk0i/3kzQbj29AORqRXUUpJiz8EQ+kqX6XtibNeqQuyo6Hcjun8wtlPTnZ4f2DkxEqMMOQE0DAXf++//xvDj+U57qIOigpLw9c1pTE8f3MAT5UuSPwD4QEGenxlLHXgpfXIt0gvdgCSJ2Lc8R57i/hOLNp9FD+jHGjCPWDlsbhRF1hZjBw+jJnNsyGeqIH7j/YyAQBfQoIZKHs3d3HpPUJRw1gpFKAYhky4/7aG0gnLcIE4q9xiwqfj+/hzmpsPcPphoC5aJQJTyaVL55gSnjkviSezSrXuqcGCw1KzS+gBUFEaeqkcPa+g2MfkORVam00LDiOAQ6I2+0V/DVLItYiILLaYZEs2O+9lMlIWbgIBuWieSij7WGsrcquygyABY0McEelspXxBnMWopdFwSksttOLXLeTMkohpW8ALEWg/X+LV8eT9QxP8z9/dK2QGMpzmAzkKf/HHbSPBDjRF9rAIhewkkaoW4AAAyCeVdUtKlRyISWN+DMHSv0JlXDLADiYVxctG3g4ILOsc0EEWPOlrANTrxrIShCosM6p3Qi+SNlEQFXUdJxGuXjJFLnwmNbXZ3EpdDiGuvl8fJw/8UMQG3XXRDBqMkogT/0nPUFTXY8wFM7BYSIhDe6h/X6on9DG2dbMnbgdldY19lqjPfRnSGijAgSvdhDSxSWs/rXRyIyOMsSdGJrCrlk0kRwa7moaoMyInXfen16Yns72szi4QBeOsvPPcrCpKPRkYwJN/YESwIYpXg1N6jB87mkMUp6H0FhUZaxG550KHHeTDe5f910UeJY5nHqMmajo3FuUSUVixL6EoE9/zZ+GkcQq RglM7sP0 tbkxeYTrww6c0BLU+sTYgOfN1ArnSsoxkBbjiUIVwFp3byLSDyI8ioHRWBG5MIY1FpPJgIAWsZfJbWCEnoZOMaPWqDsKAY24TQytaN6ZgwYbA9i81p+pZPHzYU5y6Nczyi8l6x3uLJh8yEO/R0ih2XHetK79F9h2LB4f+ZsGNu7fPBznV4jl0/7xChqPS97/NcALgi3lnJaRJLASuh8IR+EfZCG1JViGmZepQEr+8oehdOn49LYjfeHi0yHsUJQVH2GjRSwuBdsOuFHxr1VziJjaEELsWR1EsYiTr9S7ti39YbMrobyhI1VVUa7IF1g7uxRVMS8VK8noAveXRPWvWM+loTFdhmO/9+k/r16N/HPZrPwZJ8TBE4BqKXJOb1dZqBqrgnRGXuS4m4AViP9KBbKIf0/VXvTClDqbivEdy2JuKXdiZ8A39fEIG0Ol3avUnPm5GsiFpduej8HFB7H1P4YaaLRo1H2tIkRbxpwxML/o+unQv2HLKSjA5fPKuClYCoqMsrUIYOdtfF98fNEvo/2BQE1vF+1u1ufmZlX2525X1DRtDjYq0b6/T6g== 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: GUP does not correctly implement write-notify semantics, nor does it guarantee that the underlying pages are correctly dirtied, which could lead to a kernel oops or data corruption when writing to file-backed mappings. This is only relevant when the mappings are file-backed and the underlying file system requires folio dirty tracking. File systems which do not, such as shmem or hugetlb, are not at risk and therefore can be written to without issue. Unfortunately this limitation of GUP has been present for some time and requires future rework of the GUP API in order to provide correct write access to such mappings. In the meantime, we add a check for the most broken GUP case - FOLL_LONGTERM - which really under no circumstances can safely access dirty-tracked file mappings. Suggested-by: Jason Gunthorpe Signed-off-by: Lorenzo Stoakes --- v3: - Rebased on latest mm-unstable as of 24th April 2023. - Explicitly check whether file system requires folio dirtying. Note that vma_wants_writenotify() could not be used directly as it is very much focused on determining if the PTE r/w should be set (e.g. assuming private mapping does not require it as already set, soft dirty considerations). - Tested code against shmem and hugetlb mappings - confirmed that these are not disallowed by the check. - Eliminate FOLL_ALLOW_BROKEN_FILE_MAPPING flag and instead perform check only for FOLL_LONGTERM pins. - As a result, limit check to internal GUP code. v2: - Add accidentally excluded ptrace_access_vm() use of FOLL_ALLOW_BROKEN_FILE_MAPPING. - Tweak commit message. https://lore.kernel.org/all/c8ee7e02d3d4f50bb3e40855c53bda39eec85b7d.1682321768.git.lstoakes@gmail.com/ v1: https://lore.kernel.org/all/f86dc089b460c80805e321747b0898fd1efe93d7.1682168199.git.lstoakes@gmail.com/ mm/gup.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) -- 2.40.0 diff --git a/mm/gup.c b/mm/gup.c index 1f72a717232b..f77810ee8a9f 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -959,16 +960,58 @@ static int faultin_page(struct vm_area_struct *vma, return 0; } +/* + * Writing to file-backed mappings which require folio dirty tracking using GUP + * is a fundamentally broken operation as kernel write access to GUP mappings + * may not adhere to the semantics expected by a file system. + */ +static inline bool can_write_file_mapping(struct vm_area_struct *vma, + unsigned long gup_flags) +{ + const struct vm_operations_struct *vm_ops = vma->vm_ops; + const struct file *file = vma->vm_file; + + /* If we aren't pinning then no problematic write can occur. */ + if (!(gup_flags & (FOLL_GET | FOLL_PIN))) + return true; + + /* We limit this check to the most egregious case - a long term pin. */ + if (!(gup_flags & FOLL_LONGTERM)) + return true; + + /* + * If the underlying file system needs to be notified of writes, then it + * requires correct dirty tracking which we cannot guarantee. + */ + if (vm_ops && (vm_ops->page_mkwrite || vm_ops->pfn_mkwrite)) + return false; + + /* + * If no pfn_mkwrite() is specified, no dirty tracking is required for a + * PFN map. + */ + if (vma->vm_flags & VM_PFNMAP) + return true; + + /* + * Even if the file system does not require write notification, if its + * underlying mapping can writeback, dirty tracking will be required. + */ + return !file || !file->f_mapping || + !mapping_can_writeback(file->f_mapping); +} + static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) { vm_flags_t vm_flags = vma->vm_flags; int write = (gup_flags & FOLL_WRITE); int foreign = (gup_flags & FOLL_REMOTE); + bool vma_anon = vma_is_anonymous(vma); if (vm_flags & (VM_IO | VM_PFNMAP)) return -EFAULT; - if (gup_flags & FOLL_ANON && !vma_is_anonymous(vma)) + if ((gup_flags & FOLL_ANON) && !vma_anon) return -EFAULT; if ((gup_flags & FOLL_LONGTERM) && vma_is_fsdax(vma)) @@ -978,6 +1021,9 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) return -EFAULT; if (write) { + if (!vma_anon && !can_write_file_mapping(vma, gup_flags)) + return -EFAULT; + if (!(vm_flags & VM_WRITE)) { if (!(gup_flags & FOLL_FORCE)) return -EFAULT;