diff options
author | Glauber de Oliveira Costa <glommer@br.ibm.com> | 2005-10-30 18:03:05 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-30 20:37:26 -0500 |
commit | 2973dfdb877c17b36c27ba66d71028ff1eb2f32e (patch) | |
tree | 9734599068f3fcf7cd33f948235588f7a275d193 | |
parent | 7f04c26d715a2467a49a2384268de8f70f787b51 (diff) |
[PATCH] Test for sb_getblk return value
This patch adds tests for the return value of sb_getblk() in the ext2/3
filesystems. In fs/buffer.c it is stated that the getblk() function never
fails. However, it does can return NULL in some situations due to I/O
errors, which may lead us to NULL pointer dereferences
Signed-off-by: Glauber de Oliveira Costa <glommer@br.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/ext2/inode.c | 4 | ||||
-rw-r--r-- | fs/ext3/inode.c | 9 | ||||
-rw-r--r-- | fs/ext3/resize.c | 10 |
3 files changed, 22 insertions, 1 deletions
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index fdba4d1d3c60..e7d3f0522d01 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -440,6 +440,10 @@ static int ext2_alloc_branch(struct inode *inode, | |||
440 | * the pointer to new one, then send parent to disk. | 440 | * the pointer to new one, then send parent to disk. |
441 | */ | 441 | */ |
442 | bh = sb_getblk(inode->i_sb, parent); | 442 | bh = sb_getblk(inode->i_sb, parent); |
443 | if (!bh) { | ||
444 | err = -EIO; | ||
445 | break; | ||
446 | } | ||
443 | lock_buffer(bh); | 447 | lock_buffer(bh); |
444 | memset(bh->b_data, 0, blocksize); | 448 | memset(bh->b_data, 0, blocksize); |
445 | branch[n].bh = bh; | 449 | branch[n].bh = bh; |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index b5da5244e144..5d9b00e28837 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -523,7 +523,6 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode, | |||
523 | if (!nr) | 523 | if (!nr) |
524 | break; | 524 | break; |
525 | branch[n].key = cpu_to_le32(nr); | 525 | branch[n].key = cpu_to_le32(nr); |
526 | keys = n+1; | ||
527 | 526 | ||
528 | /* | 527 | /* |
529 | * Get buffer_head for parent block, zero it out | 528 | * Get buffer_head for parent block, zero it out |
@@ -531,6 +530,9 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode, | |||
531 | * parent to disk. | 530 | * parent to disk. |
532 | */ | 531 | */ |
533 | bh = sb_getblk(inode->i_sb, parent); | 532 | bh = sb_getblk(inode->i_sb, parent); |
533 | if (!bh) | ||
534 | break; | ||
535 | keys = n+1; | ||
534 | branch[n].bh = bh; | 536 | branch[n].bh = bh; |
535 | lock_buffer(bh); | 537 | lock_buffer(bh); |
536 | BUFFER_TRACE(bh, "call get_create_access"); | 538 | BUFFER_TRACE(bh, "call get_create_access"); |
@@ -864,6 +866,10 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode, | |||
864 | if (!*errp && buffer_mapped(&dummy)) { | 866 | if (!*errp && buffer_mapped(&dummy)) { |
865 | struct buffer_head *bh; | 867 | struct buffer_head *bh; |
866 | bh = sb_getblk(inode->i_sb, dummy.b_blocknr); | 868 | bh = sb_getblk(inode->i_sb, dummy.b_blocknr); |
869 | if (!bh) { | ||
870 | *errp = -EIO; | ||
871 | goto err; | ||
872 | } | ||
867 | if (buffer_new(&dummy)) { | 873 | if (buffer_new(&dummy)) { |
868 | J_ASSERT(create != 0); | 874 | J_ASSERT(create != 0); |
869 | J_ASSERT(handle != 0); | 875 | J_ASSERT(handle != 0); |
@@ -896,6 +902,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode, | |||
896 | } | 902 | } |
897 | return bh; | 903 | return bh; |
898 | } | 904 | } |
905 | err: | ||
899 | return NULL; | 906 | return NULL; |
900 | } | 907 | } |
901 | 908 | ||
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 57f79106267d..1be78b4b4de9 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -118,6 +118,8 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, | |||
118 | int err; | 118 | int err; |
119 | 119 | ||
120 | bh = sb_getblk(sb, blk); | 120 | bh = sb_getblk(sb, blk); |
121 | if (!bh) | ||
122 | return ERR_PTR(-EIO); | ||
121 | if ((err = ext3_journal_get_write_access(handle, bh))) { | 123 | if ((err = ext3_journal_get_write_access(handle, bh))) { |
122 | brelse(bh); | 124 | brelse(bh); |
123 | bh = ERR_PTR(err); | 125 | bh = ERR_PTR(err); |
@@ -202,6 +204,10 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
202 | ext3_debug("update backup group %#04lx (+%d)\n", block, bit); | 204 | ext3_debug("update backup group %#04lx (+%d)\n", block, bit); |
203 | 205 | ||
204 | gdb = sb_getblk(sb, block); | 206 | gdb = sb_getblk(sb, block); |
207 | if (!gdb) { | ||
208 | err = -EIO; | ||
209 | goto exit_bh; | ||
210 | } | ||
205 | if ((err = ext3_journal_get_write_access(handle, gdb))) { | 211 | if ((err = ext3_journal_get_write_access(handle, gdb))) { |
206 | brelse(gdb); | 212 | brelse(gdb); |
207 | goto exit_bh; | 213 | goto exit_bh; |
@@ -643,6 +649,10 @@ static void update_backups(struct super_block *sb, | |||
643 | break; | 649 | break; |
644 | 650 | ||
645 | bh = sb_getblk(sb, group * bpg + blk_off); | 651 | bh = sb_getblk(sb, group * bpg + blk_off); |
652 | if (!bh) { | ||
653 | err = -EIO; | ||
654 | break; | ||
655 | } | ||
646 | ext3_debug("update metadata backup %#04lx\n", | 656 | ext3_debug("update metadata backup %#04lx\n", |
647 | (unsigned long)bh->b_blocknr); | 657 | (unsigned long)bh->b_blocknr); |
648 | if ((err = ext3_journal_get_write_access(handle, bh))) | 658 | if ((err = ext3_journal_get_write_access(handle, bh))) |