Skip to content

Commit 7ee29fa

Browse files
SinkFinderakpm00
authored andcommitted
nilfs2: fix potential use after free in nilfs_gccache_submit_read_data()
In nilfs_gccache_submit_read_data(), brelse(bh) is called to drop the reference count of bh when the call to nilfs_dat_translate() fails. If the reference count hits 0 and its owner page gets unlocked, bh may be freed. However, bh->b_page is dereferenced to put the page after that, which may result in a use-after-free bug. This patch moves the release operation after unlocking and putting the page. NOTE: The function in question is only called in GC, and in combination with current userland tools, address translation using DAT does not occur in that function, so the code path that causes this issue will not be executed. However, it is possible to run that code path by intentionally modifying the userland GC library or by calling the GC ioctl directly. [konishi.ryusuke@gmail.com: NOTE added to the commit log] Link: https://lkml.kernel.org/r/1543201709-53191-1-git-send-email-bianpan2016@163.com Link: https://lkml.kernel.org/r/20230921141731.10073-1-konishi.ryusuke@gmail.com Fixes: a3d93f7 ("nilfs2: block cache for garbage collection") Signed-off-by: Pan Bian <bianpan2016@163.com> Reported-by: Ferry Meng <mengferry@linux.alibaba.com> Closes: https://lkml.kernel.org/r/20230818092022.111054-1-mengferry@linux.alibaba.com Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent ce60f27 commit 7ee29fa

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

fs/nilfs2/gcinode.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
7373
struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
7474

7575
err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn);
76-
if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */
77-
brelse(bh);
76+
if (unlikely(err)) /* -EIO, -ENOMEM, -ENOENT */
7877
goto failed;
79-
}
8078
}
8179

8280
lock_buffer(bh);
@@ -102,6 +100,8 @@ int nilfs_gccache_submit_read_data(struct inode *inode, sector_t blkoff,
102100
failed:
103101
unlock_page(bh->b_page);
104102
put_page(bh->b_page);
103+
if (unlikely(err))
104+
brelse(bh);
105105
return err;
106106
}
107107

0 commit comments

Comments
 (0)