Skip to content

Commit

Permalink
Btrfs: fix segmentation fault when doing dio read
Browse files Browse the repository at this point in the history
Commit 2dabb32 ("Btrfs: Direct I/O read: Work on sectorsized blocks")
introduced this bug during iterating bio pages in dio read's endio hook,
and it could end up with segment fault of the dio reading task.

So the reason is 'if (nr_sectors--)', and it makes the code assume that
there is one more block in the same page, so page offset is increased and
the bio which is created to repair the bad block then has an incorrect
bvec.bv_offset, and a later access of the page content would throw a
segmentation fault.

This also adds ASSERT to check page offset against page size.

Signed-off-by: Liu Bo <[email protected]>
Reviewed-by: David Sterba <[email protected]>
Signed-off-by: David Sterba <[email protected]>
  • Loading branch information
Liu Bo authored and kdave committed Apr 11, 2017
1 parent 2e949b0 commit 97bf5a5
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -7972,8 +7972,10 @@ static int __btrfs_correct_data_nocsum(struct inode *inode,

start += sectorsize;

if (nr_sectors--) {
nr_sectors--;
if (nr_sectors) {
pgoff += sectorsize;
ASSERT(pgoff < PAGE_SIZE);
goto next_block_or_try_again;
}
}
Expand Down Expand Up @@ -8074,8 +8076,10 @@ static int __btrfs_subio_endio_read(struct inode *inode,

ASSERT(nr_sectors);

if (--nr_sectors) {
nr_sectors--;
if (nr_sectors) {
pgoff += sectorsize;
ASSERT(pgoff < PAGE_SIZE);
goto next_block;
}
}
Expand Down

0 comments on commit 97bf5a5

Please sign in to comment.