mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
NFS: fix folio dereference before NULL check in nfs_inode_remove_request()
nfs_inode_remove_request() obtains the folio for the head request via
nfs_page_to_folio(), which returns NULL when the PG_FOLIO flag is not
set on req->wb_head.
The presence of the "if (likely(folio))" check shows the code already
assumes folio can be NULL. However, folio was dereferenced before that
check:
folio = nfs_page_to_folio(req->wb_head);
mapping = folio->mapping; /* deref */
spin_lock(&mapping->i_private_lock);
if (likely(folio)) { /* too late */
folio->mapping is read (and mapping->i_private_lock is taken, and
folio_end_dropbehind(folio) is called outside the check) before folio
is validated, so a NULL folio would crash before the guard is ever
reached, rendering the check useless.
Move the folio->mapping read, the i_private_lock section and the
folio_end_dropbehind() call inside the "if (likely(folio))" block so
the folio is only dereferenced after it has been confirmed non-NULL.
The behaviour is unchanged when folio is non-NULL.
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
b4dd7f8159
commit
59075fb8b7
|
|
@ -739,17 +739,18 @@ static void nfs_inode_remove_request(struct nfs_page *req)
|
|||
nfs_page_group_lock(req);
|
||||
if (nfs_page_group_sync_on_bit_locked(req, PG_REMOVE)) {
|
||||
struct folio *folio = nfs_page_to_folio(req->wb_head);
|
||||
struct address_space *mapping = folio->mapping;
|
||||
|
||||
spin_lock(&mapping->i_private_lock);
|
||||
if (likely(folio)) {
|
||||
struct address_space *mapping = folio->mapping;
|
||||
|
||||
spin_lock(&mapping->i_private_lock);
|
||||
folio->private = NULL;
|
||||
folio_clear_private(folio);
|
||||
clear_bit(PG_MAPPED, &req->wb_head->wb_flags);
|
||||
}
|
||||
spin_unlock(&mapping->i_private_lock);
|
||||
spin_unlock(&mapping->i_private_lock);
|
||||
|
||||
folio_end_dropbehind(folio);
|
||||
folio_end_dropbehind(folio);
|
||||
}
|
||||
}
|
||||
nfs_page_group_unlock(req);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user