Message ID | 20240326143210.291116-2-david@redhat.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | mm/secretmem: one fix and one refactoring | expand |
On Tue, Mar 26, 2024 at 03:32:08PM +0100, David Hildenbrand wrote: > folio_is_secretmem() currently relies on secretmem folios being LRU folios, > to save some cycles. > > However, folios might reside in a folio batch without the LRU flag set, or > temporarily have their LRU flag cleared. Consequently, the LRU flag is > unreliable for this purpose. > > In particular, this is the case when secretmem_fault() allocates a > fresh page and calls filemap_add_folio()->folio_add_lru(). The folio might > be added to the per-cpu folio batch and won't get the LRU flag set until > the batch was drained using e.g., lru_add_drain(). > > Consequently, folio_is_secretmem() might not detect secretmem folios > and GUP-fast can succeed in grabbing a secretmem folio, crashing the > kernel when we would later try reading/writing to the folio, because > the folio has been unmapped from the directmap. > > Fix it by removing that unreliable check. > > Reported-by: xingwei lee <xrivendell7@gmail.com> > Reported-by: yue sun <samsun1006219@gmail.com> > Closes: https://lore.kernel.org/lkml/CABOYnLyevJeravW=QrH0JUPYEcDN160aZFb7kwndm-J2rmz0HQ@mail.gmail.com/ > Debugged-by: Miklos Szeredi <miklos@szeredi.hu> > Tested-by: Miklos Szeredi <mszeredi@redhat.com> > Fixes: 1507f51255c9 ("mm: introduce memfd_secret system call to create "secret" memory areas") > Cc: <stable@vger.kernel.org> > Signed-off-by: David Hildenbrand <david@redhat.com> Reviewed-by: Mike Rapoport (IBM) <rppt@kernel.org> > --- > include/linux/secretmem.h | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/include/linux/secretmem.h b/include/linux/secretmem.h > index 35f3a4a8ceb1..acf7e1a3f3de 100644 > --- a/include/linux/secretmem.h > +++ b/include/linux/secretmem.h > @@ -13,10 +13,10 @@ static inline bool folio_is_secretmem(struct folio *folio) > /* > * Using folio_mapping() is quite slow because of the actual call > * instruction. > - * We know that secretmem pages are not compound and LRU so we can > + * We know that secretmem pages are not compound, so we can > * save a couple of cycles here. > */ > - if (folio_test_large(folio) || !folio_test_lru(folio)) > + if (folio_test_large(folio)) > return false; > > mapping = (struct address_space *) > -- > 2.43.2 >
diff --git a/include/linux/secretmem.h b/include/linux/secretmem.h index 35f3a4a8ceb1..acf7e1a3f3de 100644 --- a/include/linux/secretmem.h +++ b/include/linux/secretmem.h @@ -13,10 +13,10 @@ static inline bool folio_is_secretmem(struct folio *folio) /* * Using folio_mapping() is quite slow because of the actual call * instruction. - * We know that secretmem pages are not compound and LRU so we can + * We know that secretmem pages are not compound, so we can * save a couple of cycles here. */ - if (folio_test_large(folio) || !folio_test_lru(folio)) + if (folio_test_large(folio)) return false; mapping = (struct address_space *)