From: Glauber de Oliveira Costa Date: Sun, 30 Oct 2005 23:03:05 +0000 (-0800) Subject: [PATCH] Test for sb_getblk return value X-Git-Tag: v2.6.15-rc1~59^2~15^2~54 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2973dfdb877c17b36c27ba66d71028ff1eb2f32e;p=linux-2.6 [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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index fdba4d1d3c..e7d3f0522d 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -440,6 +440,10 @@ static int ext2_alloc_branch(struct inode *inode, * the pointer to new one, then send parent to disk. */ bh = sb_getblk(inode->i_sb, parent); + if (!bh) { + err = -EIO; + break; + } lock_buffer(bh); memset(bh->b_data, 0, blocksize); branch[n].bh = bh; diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index b5da5244e1..5d9b00e288 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, if (!nr) break; branch[n].key = cpu_to_le32(nr); - keys = n+1; /* * Get buffer_head for parent block, zero it out @@ -531,6 +530,9 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode, * parent to disk. */ bh = sb_getblk(inode->i_sb, parent); + if (!bh) + break; + keys = n+1; branch[n].bh = bh; lock_buffer(bh); BUFFER_TRACE(bh, "call get_create_access"); @@ -864,6 +866,10 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode, if (!*errp && buffer_mapped(&dummy)) { struct buffer_head *bh; bh = sb_getblk(inode->i_sb, dummy.b_blocknr); + if (!bh) { + *errp = -EIO; + goto err; + } if (buffer_new(&dummy)) { J_ASSERT(create != 0); J_ASSERT(handle != 0); @@ -896,6 +902,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode, } return bh; } +err: return NULL; } diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 57f7910626..1be78b4b4d 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, int err; bh = sb_getblk(sb, blk); + if (!bh) + return ERR_PTR(-EIO); if ((err = ext3_journal_get_write_access(handle, bh))) { brelse(bh); bh = ERR_PTR(err); @@ -202,6 +204,10 @@ static int setup_new_group_blocks(struct super_block *sb, ext3_debug("update backup group %#04lx (+%d)\n", block, bit); gdb = sb_getblk(sb, block); + if (!gdb) { + err = -EIO; + goto exit_bh; + } if ((err = ext3_journal_get_write_access(handle, gdb))) { brelse(gdb); goto exit_bh; @@ -643,6 +649,10 @@ static void update_backups(struct super_block *sb, break; bh = sb_getblk(sb, group * bpg + blk_off); + if (!bh) { + err = -EIO; + break; + } ext3_debug("update metadata backup %#04lx\n", (unsigned long)bh->b_blocknr); if ((err = ext3_journal_get_write_access(handle, bh)))