forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
omfs: check bounds on block numbers before passing to sb_bread
In case of filesystem corruption, passing unchecked block numbers into sb_bread can result in an infinite loop in __getblk(). Introduce a wrapper function omfs_sbread() to check the block numbers and to also perform the clus_to_blk() scaling. Signed-off-by: Bob Copeland <[email protected]>
- Loading branch information
Showing
4 changed files
with
29 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,15 @@ MODULE_AUTHOR("Bob Copeland <[email protected]>"); | |
MODULE_DESCRIPTION("OMFS (ReplayTV/Karma) Filesystem for Linux"); | ||
MODULE_LICENSE("GPL"); | ||
|
||
struct buffer_head *omfs_bread(struct super_block *sb, sector_t block) | ||
{ | ||
struct omfs_sb_info *sbi = OMFS_SB(sb); | ||
if (block >= sbi->s_num_blocks) | ||
return NULL; | ||
|
||
return sb_bread(sb, clus_to_blk(sbi, block)); | ||
} | ||
|
||
struct inode *omfs_new_inode(struct inode *dir, int mode) | ||
{ | ||
struct inode *inode; | ||
|
@@ -93,15 +102,13 @@ static int __omfs_write_inode(struct inode *inode, int wait) | |
struct omfs_inode *oi; | ||
struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb); | ||
struct buffer_head *bh, *bh2; | ||
unsigned int block; | ||
u64 ctime; | ||
int i; | ||
int ret = -EIO; | ||
int sync_failed = 0; | ||
|
||
/* get current inode since we may have written sibling ptrs etc. */ | ||
block = clus_to_blk(sbi, inode->i_ino); | ||
bh = sb_bread(inode->i_sb, block); | ||
bh = omfs_bread(inode->i_sb, inode->i_ino); | ||
if (!bh) | ||
goto out; | ||
|
||
|
@@ -140,8 +147,7 @@ static int __omfs_write_inode(struct inode *inode, int wait) | |
|
||
/* if mirroring writes, copy to next fsblock */ | ||
for (i = 1; i < sbi->s_mirrors; i++) { | ||
bh2 = sb_bread(inode->i_sb, block + i * | ||
(sbi->s_blocksize / sbi->s_sys_blocksize)); | ||
bh2 = omfs_bread(inode->i_sb, inode->i_ino + i); | ||
if (!bh2) | ||
goto out_brelse; | ||
|
||
|
@@ -193,7 +199,6 @@ struct inode *omfs_iget(struct super_block *sb, ino_t ino) | |
struct omfs_sb_info *sbi = OMFS_SB(sb); | ||
struct omfs_inode *oi; | ||
struct buffer_head *bh; | ||
unsigned int block; | ||
u64 ctime; | ||
unsigned long nsecs; | ||
struct inode *inode; | ||
|
@@ -204,8 +209,7 @@ struct inode *omfs_iget(struct super_block *sb, ino_t ino) | |
if (!(inode->i_state & I_NEW)) | ||
return inode; | ||
|
||
block = clus_to_blk(sbi, ino); | ||
bh = sb_bread(inode->i_sb, block); | ||
bh = omfs_bread(inode->i_sb, ino); | ||
if (!bh) | ||
goto iget_failed; | ||
|
||
|
@@ -319,6 +323,9 @@ static int omfs_get_imap(struct super_block *sb) | |
goto nomem; | ||
|
||
block = clus_to_blk(sbi, sbi->s_bitmap_ino); | ||
if (block >= sbi->s_num_blocks) | ||
goto nomem; | ||
|
||
ptr = sbi->s_imap; | ||
for (count = bitmap_size; count > 0; count -= sb->s_blocksize) { | ||
bh = sb_bread(sb, block++); | ||
|
@@ -417,7 +424,6 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) | |
struct omfs_root_block *omfs_rb; | ||
struct omfs_sb_info *sbi; | ||
struct inode *root; | ||
sector_t start; | ||
int ret = -EINVAL; | ||
|
||
save_mount_options(sb, (char *) data); | ||
|
@@ -486,8 +492,7 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) | |
sbi->s_block_shift = get_bitmask_order(sbi->s_blocksize) - | ||
get_bitmask_order(sbi->s_sys_blocksize); | ||
|
||
start = clus_to_blk(sbi, be64_to_cpu(omfs_sb->s_root_block)); | ||
bh2 = sb_bread(sb, start); | ||
bh2 = omfs_bread(sb, be64_to_cpu(omfs_sb->s_root_block)); | ||
if (!bh2) | ||
goto out_brelse_bh; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters