* [PATCH 0/2] ext3_bread usage audit due non-initialized variable @ 2012-10-01 19:50 Carlos Maiolino 2012-10-01 19:50 ` [PATCH 1/2] ext3: fix possible non-initialized variable on htree_dirblock_to_tree() Carlos Maiolino 2012-10-01 19:50 ` [PATCH 2/2] ext3: ext3_bread usage audit Carlos Maiolino 0 siblings, 2 replies; 14+ messages in thread From: Carlos Maiolino @ 2012-10-01 19:50 UTC (permalink / raw) To: linux-ext4 This is a backport from ext4 to fix a possible non-initialized variable and wrong behaviour of ext3_bread() callers caused due this. Carlos Maiolino (2): ext3: fix possible non-initialized variable on htree_dirblock_to_tree() ext3: ext3_bread usage audit fs/ext3/namei.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 10 deletions(-) -- 1.7.11.4 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] ext3: fix possible non-initialized variable on htree_dirblock_to_tree() 2012-10-01 19:50 [PATCH 0/2] ext3_bread usage audit due non-initialized variable Carlos Maiolino @ 2012-10-01 19:50 ` Carlos Maiolino 2012-10-02 13:55 ` Jan Kara 2012-10-01 19:50 ` [PATCH 2/2] ext3: ext3_bread usage audit Carlos Maiolino 1 sibling, 1 reply; 14+ messages in thread From: Carlos Maiolino @ 2012-10-01 19:50 UTC (permalink / raw) To: linux-ext4 This is a backport of ext4 commit 90b0a9732 which fixes a possible non-initialized variable on htree_dirblock_to_tree(). Ext3 has the same non initialized variable, but, in any case it will be initialized by ext3_get_blocks_handle(), which will avoid the bug to be triggered, but, the non-initialized variable by htree_dirblock_to_tree() is still a bug. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> --- fs/ext3/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 8f4fdda..7f6c938 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -559,7 +559,7 @@ static int htree_dirblock_to_tree(struct file *dir_file, { struct buffer_head *bh; struct ext3_dir_entry_2 *de, *top; - int err, count = 0; + int err = 0, count = 0; dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] ext3: fix possible non-initialized variable on htree_dirblock_to_tree() 2012-10-01 19:50 ` [PATCH 1/2] ext3: fix possible non-initialized variable on htree_dirblock_to_tree() Carlos Maiolino @ 2012-10-02 13:55 ` Jan Kara 0 siblings, 0 replies; 14+ messages in thread From: Jan Kara @ 2012-10-02 13:55 UTC (permalink / raw) To: Carlos Maiolino; +Cc: linux-ext4 On Mon 01-10-12 16:50:54, Carlos Maiolino wrote: > This is a backport of ext4 commit 90b0a9732 which fixes a possible > non-initialized variable on htree_dirblock_to_tree(). > Ext3 has the same non initialized variable, but, in any case it will be > initialized by ext3_get_blocks_handle(), which will avoid the bug to be > triggered, but, the non-initialized variable by htree_dirblock_to_tree() is > still a bug. This is a good cleanup. I've taken that into my tree. Honza > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> > --- > fs/ext3/namei.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c > index 8f4fdda..7f6c938 100644 > --- a/fs/ext3/namei.c > +++ b/fs/ext3/namei.c > @@ -559,7 +559,7 @@ static int htree_dirblock_to_tree(struct file *dir_file, > { > struct buffer_head *bh; > struct ext3_dir_entry_2 *de, *top; > - int err, count = 0; > + int err = 0, count = 0; > > dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); > if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) > -- > 1.7.11.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/2] ext3: ext3_bread usage audit 2012-10-01 19:50 [PATCH 0/2] ext3_bread usage audit due non-initialized variable Carlos Maiolino 2012-10-01 19:50 ` [PATCH 1/2] ext3: fix possible non-initialized variable on htree_dirblock_to_tree() Carlos Maiolino @ 2012-10-01 19:50 ` Carlos Maiolino 2012-10-02 13:55 ` Jan Kara 2012-10-03 2:59 ` [PATCH 2/2] ext3: ext3_bread usage audit [V2] Carlos Maiolino 1 sibling, 2 replies; 14+ messages in thread From: Carlos Maiolino @ 2012-10-01 19:50 UTC (permalink / raw) To: linux-ext4 This is the ext3 version of the same patch applied to Ext4, where such goal is to audit the usage of ext3_bread() due a possible misinterpretion of its return value. Focused on directory blocks, a NULL value returned from ext3_bread() means a hole, which cannot exist into a directory inode. It can pass undetected after a fix in an uninitialized error variable. The (now) initialized variable into ext3_getblk() may lead to a zero'ed return value of ext3_bread() to its callers, which can make the caller do not detect the hole in the directory inode. This checks for directory holes when buffer_head and error value are both zero'ed returning -EIO to their callers Some ext3_bread() callers do not needed any changes either because they already had its own hole detector paths or because these are deprecaded (like dx_show_entries) Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> --- fs/ext3/namei.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 7f6c938..8e56c2cc 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -56,6 +56,11 @@ static struct buffer_head *ext3_append(handle_t *handle, bh = NULL; } } + if (!bh && !(*err)) { + *err = -EIO; + ext3_error(inode->i_sb, __func__, + "Directory hole detected on inode %lu\n", inode->i_ino); + } return bh; } @@ -339,8 +344,11 @@ dx_probe(struct qstr *entry, struct inode *dir, u32 hash; frame->bh = NULL; - if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) + if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) { + if (!(*err)) + *err = ERR_BAD_DX_DIR; goto fail; + } root = (struct dx_root *) bh->b_data; if (root->info.hash_version != DX_HASH_TEA && root->info.hash_version != DX_HASH_HALF_MD4 && @@ -436,8 +444,11 @@ dx_probe(struct qstr *entry, struct inode *dir, frame->entries = entries; frame->at = at; if (!indirect--) return frame; - if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) + if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) { + if (!(*err)) + *err = ERR_BAD_DX_DIR; goto fail2; + } at = entries = ((struct dx_node *) bh->b_data)->entries; if (dx_get_limit(entries) != dx_node_limit (dir)) { ext3_warning(dir->i_sb, __func__, @@ -536,8 +547,15 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash, */ while (num_frames--) { if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), - 0, &err))) + 0, &err))) { + if (!err) { + ext3_error(dir->i_sb, __func__, + "Directory hole detected on inode %lu\n", + dir->i_ino); + return -EIO; + } return err; /* Failure */ + } p++; brelse (p->bh); p->bh = bh; @@ -562,8 +580,15 @@ static int htree_dirblock_to_tree(struct file *dir_file, int err = 0, count = 0; dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); - if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) + if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) { + if (!err) { + ext3_error(dir->i_sb, __func__, + "Directory hole detected on inode %lu\n", + dir->i_ino); + return -EIO; + } return err; + } de = (struct ext3_dir_entry_2 *) bh->b_data; top = (struct ext3_dir_entry_2 *) ((char *) de + @@ -976,8 +1001,15 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, return NULL; do { block = dx_get_block(frame->at); - if (!(bh = ext3_bread (NULL,dir, block, 0, err))) + if (!(bh = ext3_bread (NULL,dir, block, 0, err))) { + if (!(*err)) { + *err = -EIO; + ext3_error(dir->i_sb, __func__, + "Directory hole detected on inode %lu\n", + dir->i_ino); + } goto errout; + } retval = search_dirblock(bh, dir, entry, block << EXT3_BLOCK_SIZE_BITS(sb), @@ -1458,9 +1490,15 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, } blocks = dir->i_size >> sb->s_blocksize_bits; for (block = 0; block < blocks; block++) { - bh = ext3_bread(handle, dir, block, 0, &retval); - if(!bh) + if (!(bh = ext3_bread(handle, dir, block, 0, &retval))) { + if (!retval) { + retval = -EIO; + ext3_error(dir->i_sb, __func__, + "Directory hole detected on inode %lu\n", + dir->i_ino); + } return retval; + } retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh); if (retval != -ENOSPC) return retval; @@ -1500,8 +1538,15 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, entries = frame->entries; at = frame->at; - if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) + if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) { + if (!err) { + err = -EIO; + ext3_error(dir->i_sb, __func__, + "Directory hole detected on inode %lu\n", + dir->i_ino); + } goto cleanup; + } BUFFER_TRACE(bh, "get_write_access"); err = ext3_journal_get_write_access(handle, bh); @@ -1791,8 +1836,15 @@ retry: inode->i_fop = &ext3_dir_operations; inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) + if (!dir_block) { + if (!err) { + err = -EIO; + ext3_error(inode->i_sb, __func__, + "Directory hole detected on inode %lu\n", + inode->i_ino); + } goto out_clear_inode; + } BUFFER_TRACE(dir_block, "get_write_access"); err = ext3_journal_get_write_access(handle, dir_block); @@ -1898,6 +1950,11 @@ static int empty_dir (struct inode * inode) "error %d reading directory" " #%lu offset %lu", err, inode->i_ino, offset); + else + ext3_warning(inode->i_sb, __func__, + "bad directory (dir #%lu) - no data block", + inode->i_ino); + offset += sb->s_blocksize; continue; } -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit 2012-10-01 19:50 ` [PATCH 2/2] ext3: ext3_bread usage audit Carlos Maiolino @ 2012-10-02 13:55 ` Jan Kara 2012-10-02 14:27 ` Carlos Maiolino 2012-10-03 2:59 ` [PATCH 2/2] ext3: ext3_bread usage audit [V2] Carlos Maiolino 1 sibling, 1 reply; 14+ messages in thread From: Jan Kara @ 2012-10-02 13:55 UTC (permalink / raw) To: Carlos Maiolino; +Cc: linux-ext4 On Mon 01-10-12 16:50:55, Carlos Maiolino wrote: > This is the ext3 version of the same patch applied to Ext4, where such goal is > to audit the usage of ext3_bread() due a possible misinterpretion of its return > value. > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > hole, which cannot exist into a directory inode. It can pass undetected after a > fix in an uninitialized error variable. > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > value of ext3_bread() to its callers, which can make the caller do not detect > the hole in the directory inode. > > This checks for directory holes when buffer_head and error value are both > zero'ed returning -EIO to their callers > > Some ext3_bread() callers do not needed any changes either because they already > had its own hole detector paths or because these are deprecaded (like > dx_show_entries) Umm, can you wrap the check for hole + error message in a helper function like ext3_dir_bread() please? That would save us quite some dupplication.. Thanks! Honza > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> > --- > fs/ext3/namei.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 66 insertions(+), 9 deletions(-) > > diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c > index 7f6c938..8e56c2cc 100644 > --- a/fs/ext3/namei.c > +++ b/fs/ext3/namei.c > @@ -56,6 +56,11 @@ static struct buffer_head *ext3_append(handle_t *handle, > bh = NULL; > } > } > + if (!bh && !(*err)) { > + *err = -EIO; > + ext3_error(inode->i_sb, __func__, > + "Directory hole detected on inode %lu\n", inode->i_ino); > + } > return bh; > } > > @@ -339,8 +344,11 @@ dx_probe(struct qstr *entry, struct inode *dir, > u32 hash; > > frame->bh = NULL; > - if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) > + if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) { > + if (!(*err)) > + *err = ERR_BAD_DX_DIR; > goto fail; > + } > root = (struct dx_root *) bh->b_data; > if (root->info.hash_version != DX_HASH_TEA && > root->info.hash_version != DX_HASH_HALF_MD4 && > @@ -436,8 +444,11 @@ dx_probe(struct qstr *entry, struct inode *dir, > frame->entries = entries; > frame->at = at; > if (!indirect--) return frame; > - if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) > + if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) { > + if (!(*err)) > + *err = ERR_BAD_DX_DIR; > goto fail2; > + } > at = entries = ((struct dx_node *) bh->b_data)->entries; > if (dx_get_limit(entries) != dx_node_limit (dir)) { > ext3_warning(dir->i_sb, __func__, > @@ -536,8 +547,15 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash, > */ > while (num_frames--) { > if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), > - 0, &err))) > + 0, &err))) { > + if (!err) { > + ext3_error(dir->i_sb, __func__, > + "Directory hole detected on inode %lu\n", > + dir->i_ino); > + return -EIO; > + } > return err; /* Failure */ > + } > p++; > brelse (p->bh); > p->bh = bh; > @@ -562,8 +580,15 @@ static int htree_dirblock_to_tree(struct file *dir_file, > int err = 0, count = 0; > > dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); > - if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) > + if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) { > + if (!err) { > + ext3_error(dir->i_sb, __func__, > + "Directory hole detected on inode %lu\n", > + dir->i_ino); > + return -EIO; > + } > return err; > + } > > de = (struct ext3_dir_entry_2 *) bh->b_data; > top = (struct ext3_dir_entry_2 *) ((char *) de + > @@ -976,8 +1001,15 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, > return NULL; > do { > block = dx_get_block(frame->at); > - if (!(bh = ext3_bread (NULL,dir, block, 0, err))) > + if (!(bh = ext3_bread (NULL,dir, block, 0, err))) { > + if (!(*err)) { > + *err = -EIO; > + ext3_error(dir->i_sb, __func__, > + "Directory hole detected on inode %lu\n", > + dir->i_ino); > + } > goto errout; > + } > > retval = search_dirblock(bh, dir, entry, > block << EXT3_BLOCK_SIZE_BITS(sb), > @@ -1458,9 +1490,15 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, > } > blocks = dir->i_size >> sb->s_blocksize_bits; > for (block = 0; block < blocks; block++) { > - bh = ext3_bread(handle, dir, block, 0, &retval); > - if(!bh) > + if (!(bh = ext3_bread(handle, dir, block, 0, &retval))) { > + if (!retval) { > + retval = -EIO; > + ext3_error(dir->i_sb, __func__, > + "Directory hole detected on inode %lu\n", > + dir->i_ino); > + } > return retval; > + } > retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh); > if (retval != -ENOSPC) > return retval; > @@ -1500,8 +1538,15 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, > entries = frame->entries; > at = frame->at; > > - if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) > + if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) { > + if (!err) { > + err = -EIO; > + ext3_error(dir->i_sb, __func__, > + "Directory hole detected on inode %lu\n", > + dir->i_ino); > + } > goto cleanup; > + } > > BUFFER_TRACE(bh, "get_write_access"); > err = ext3_journal_get_write_access(handle, bh); > @@ -1791,8 +1836,15 @@ retry: > inode->i_fop = &ext3_dir_operations; > inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; > dir_block = ext3_bread (handle, inode, 0, 1, &err); > - if (!dir_block) > + if (!dir_block) { > + if (!err) { > + err = -EIO; > + ext3_error(inode->i_sb, __func__, > + "Directory hole detected on inode %lu\n", > + inode->i_ino); > + } > goto out_clear_inode; > + } > > BUFFER_TRACE(dir_block, "get_write_access"); > err = ext3_journal_get_write_access(handle, dir_block); > @@ -1898,6 +1950,11 @@ static int empty_dir (struct inode * inode) > "error %d reading directory" > " #%lu offset %lu", > err, inode->i_ino, offset); > + else > + ext3_warning(inode->i_sb, __func__, > + "bad directory (dir #%lu) - no data block", > + inode->i_ino); > + > offset += sb->s_blocksize; > continue; > } > -- > 1.7.11.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit 2012-10-02 13:55 ` Jan Kara @ 2012-10-02 14:27 ` Carlos Maiolino 2012-10-04 12:38 ` Jan Kara 0 siblings, 1 reply; 14+ messages in thread From: Carlos Maiolino @ 2012-10-02 14:27 UTC (permalink / raw) To: linux-ext4 Hi Jan On Tue, Oct 02, 2012 at 03:55:13PM +0200, Jan Kara wrote: > On Mon 01-10-12 16:50:55, Carlos Maiolino wrote: > > This is the ext3 version of the same patch applied to Ext4, where such goal is > > to audit the usage of ext3_bread() due a possible misinterpretion of its return > > value. > > > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > > hole, which cannot exist into a directory inode. It can pass undetected after a > > fix in an uninitialized error variable. > > > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > > value of ext3_bread() to its callers, which can make the caller do not detect > > the hole in the directory inode. > > > > This checks for directory holes when buffer_head and error value are both > > zero'ed returning -EIO to their callers > > > > Some ext3_bread() callers do not needed any changes either because they already > > had its own hole detector paths or because these are deprecaded (like > > dx_show_entries) > Umm, can you wrap the check for hole + error message in a helper function > like ext3_dir_bread() please? That would save us quite some dupplication.. > Thanks! > I thought about a kind of handler too, but haven't done something like that by Ted's suggestion. Please see thread http://marc.info/?l=linux-ext4&m=134827512716575&w=2 But I can work on a kind of wrapper for ext3 if this is ok for you and send a V2 version of this patch. Cheers, Carlos -- --Carlos ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit 2012-10-02 14:27 ` Carlos Maiolino @ 2012-10-04 12:38 ` Jan Kara 0 siblings, 0 replies; 14+ messages in thread From: Jan Kara @ 2012-10-04 12:38 UTC (permalink / raw) To: Carlos Maiolino; +Cc: linux-ext4 On Tue 02-10-12 11:27:23, Carlos Maiolino wrote: > Hi Jan > On Tue, Oct 02, 2012 at 03:55:13PM +0200, Jan Kara wrote: > > On Mon 01-10-12 16:50:55, Carlos Maiolino wrote: > > > This is the ext3 version of the same patch applied to Ext4, where such goal is > > > to audit the usage of ext3_bread() due a possible misinterpretion of its return > > > value. > > > > > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > > > hole, which cannot exist into a directory inode. It can pass undetected after a > > > fix in an uninitialized error variable. > > > > > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > > > value of ext3_bread() to its callers, which can make the caller do not detect > > > the hole in the directory inode. > > > > > > This checks for directory holes when buffer_head and error value are both > > > zero'ed returning -EIO to their callers > > > > > > Some ext3_bread() callers do not needed any changes either because they already > > > had its own hole detector paths or because these are deprecaded (like > > > dx_show_entries) > > Umm, can you wrap the check for hole + error message in a helper function > > like ext3_dir_bread() please? That would save us quite some dupplication.. > > Thanks! > > Please use reply-to-all when replying next time. It makes me see the email much faster and reply cannot get lost in mailing list traffic... > I thought about a kind of handler too, but haven't done something like that by > Ted's suggestion. Please see thread > http://marc.info/?l=linux-ext4&m=134827512716575&w=2 > > But I can work on a kind of wrapper for ext3 if this is ok for you and send a V2 > version of this patch. I see. Still I'd rather have the helper function. So please send V2. Thanks. Honza -- Jan Kara <jack@suse.cz> SUSE Labs, CR ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/2] ext3: ext3_bread usage audit [V2] 2012-10-01 19:50 ` [PATCH 2/2] ext3: ext3_bread usage audit Carlos Maiolino 2012-10-02 13:55 ` Jan Kara @ 2012-10-03 2:59 ` Carlos Maiolino 2012-10-04 12:42 ` Jan Kara 1 sibling, 1 reply; 14+ messages in thread From: Carlos Maiolino @ 2012-10-03 2:59 UTC (permalink / raw) To: linux-ext4 This is the ext3 version of the same patch applied to Ext4, where such goal is to audit the usage of ext3_bread() due a possible misinterpretion of its return value. Focused on directory blocks, a NULL value returned from ext3_bread() means a hole, which cannot exist into a directory inode. It can pass undetected after a fix in an uninitialized error variable. The (now) initialized variable into ext3_getblk() may lead to a zero'ed return value of ext3_bread() to its callers, which can make the caller do not detect the hole in the directory inode. This checks for directory holes when buffer_head and error value are both zero'ed returning -EIO to their callers Some ext3_bread() callers do not needed any changes either because they already had its own hole detector paths or because these are deprecaded (like dx_show_entries) V2: It adds a wrapper function ext3_dir_bread() to check for directory holes when reading blocks for a directory inode, and callers of ext3_bread() to read directory blocks were replaced by this wrapper. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> --- fs/ext3/namei.c | 36 +++++++++++++++++++----------------- fs/ext3/namei.h | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 7f6c938..0eecf4d 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -46,8 +46,7 @@ static struct buffer_head *ext3_append(handle_t *handle, *block = inode->i_size >> inode->i_sb->s_blocksize_bits; - bh = ext3_bread(handle, inode, *block, 1, err); - if (bh) { + if ((bh = ext3_dir_bread(handle, inode, *block, 1, err))) { inode->i_size += inode->i_sb->s_blocksize; EXT3_I(inode)->i_disksize = inode->i_size; *err = ext3_journal_get_write_access(handle, bh); @@ -339,8 +338,10 @@ dx_probe(struct qstr *entry, struct inode *dir, u32 hash; frame->bh = NULL; - if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) + if (!(bh = ext3_dir_bread(NULL, dir, 0, 0, err))) { + *err = ERR_BAD_DX_DIR; goto fail; + } root = (struct dx_root *) bh->b_data; if (root->info.hash_version != DX_HASH_TEA && root->info.hash_version != DX_HASH_HALF_MD4 && @@ -436,8 +437,10 @@ dx_probe(struct qstr *entry, struct inode *dir, frame->entries = entries; frame->at = at; if (!indirect--) return frame; - if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) + if (!(bh = ext3_dir_bread(NULL, dir, dx_get_block(at), 0, err))) { + *err = ERR_BAD_DX_DIR; goto fail2; + } at = entries = ((struct dx_node *) bh->b_data)->entries; if (dx_get_limit(entries) != dx_node_limit (dir)) { ext3_warning(dir->i_sb, __func__, @@ -535,8 +538,8 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash, * block so no check is necessary */ while (num_frames--) { - if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), - 0, &err))) + if (!(bh = ext3_dir_bread(NULL, dir, dx_get_block(p->at), + 0, &err))) return err; /* Failure */ p++; brelse (p->bh); @@ -562,7 +565,8 @@ static int htree_dirblock_to_tree(struct file *dir_file, int err = 0, count = 0; dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); - if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) + + if (!(bh = ext3_dir_bread(NULL, dir, block, 0, &err))) return err; de = (struct ext3_dir_entry_2 *) bh->b_data; @@ -976,7 +980,7 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, return NULL; do { block = dx_get_block(frame->at); - if (!(bh = ext3_bread (NULL,dir, block, 0, err))) + if (!(bh = ext3_dir_bread (NULL, dir, block, 0, err))) goto errout; retval = search_dirblock(bh, dir, entry, @@ -1458,9 +1462,9 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, } blocks = dir->i_size >> sb->s_blocksize_bits; for (block = 0; block < blocks; block++) { - bh = ext3_bread(handle, dir, block, 0, &retval); - if(!bh) + if (!(bh = ext3_dir_bread(handle, dir, block, 0, &retval))) return retval; + retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh); if (retval != -ENOSPC) return retval; @@ -1500,7 +1504,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, entries = frame->entries; at = frame->at; - if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) + if (!(bh = ext3_dir_bread(handle, dir, dx_get_block(frame->at), 0, &err))) goto cleanup; BUFFER_TRACE(bh, "get_write_access"); @@ -1790,8 +1794,7 @@ retry: inode->i_op = &ext3_dir_inode_operations; inode->i_fop = &ext3_dir_operations; inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) + if (!(dir_block = ext3_dir_bread(handle, inode, 0, 1, &err))) goto out_clear_inode; BUFFER_TRACE(dir_block, "get_write_access"); @@ -1859,7 +1862,7 @@ static int empty_dir (struct inode * inode) sb = inode->i_sb; if (inode->i_size < EXT3_DIR_REC_LEN(1) + EXT3_DIR_REC_LEN(2) || - !(bh = ext3_bread (NULL, inode, 0, 0, &err))) { + !(bh = ext3_dir_bread(NULL, inode, 0, 0, &err))) { if (err) ext3_error(inode->i_sb, __func__, "error %d reading directory #%lu offset 0", @@ -1890,9 +1893,8 @@ static int empty_dir (struct inode * inode) (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) { err = 0; brelse (bh); - bh = ext3_bread (NULL, inode, - offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err); - if (!bh) { + if (!(bh = ext3_dir_bread (NULL, inode, + offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err))) { if (err) ext3_error(sb, __func__, "error %d reading directory" diff --git a/fs/ext3/namei.h b/fs/ext3/namei.h index f2ce2b0..46304d8 100644 --- a/fs/ext3/namei.h +++ b/fs/ext3/namei.h @@ -6,3 +6,22 @@ */ extern struct dentry *ext3_get_parent(struct dentry *child); + +static inline struct buffer_head *ext3_dir_bread(handle_t *handle, + struct inode *inode, + int block, int create, + int *err) +{ + struct buffer_head *bh; + + bh = ext3_bread(handle, inode, block, create, err); + + if (!bh && !(*err)) { + *err = -EIO; + ext3_error(inode->i_sb, __func__, + "Directory hole detected on inode %lu\n", + inode->i_ino); + return NULL; + } + return bh; +} -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit [V2] 2012-10-03 2:59 ` [PATCH 2/2] ext3: ext3_bread usage audit [V2] Carlos Maiolino @ 2012-10-04 12:42 ` Jan Kara 2012-10-04 13:02 ` Jan Kara 0 siblings, 1 reply; 14+ messages in thread From: Jan Kara @ 2012-10-04 12:42 UTC (permalink / raw) To: Carlos Maiolino; +Cc: linux-ext4 On Tue 02-10-12 23:59:23, Carlos Maiolino wrote: > This is the ext3 version of the same patch applied to Ext4, where such goal is > to audit the usage of ext3_bread() due a possible misinterpretion of its return > value. > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > hole, which cannot exist into a directory inode. It can pass undetected after a > fix in an uninitialized error variable. > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > value of ext3_bread() to its callers, which can make the caller do not detect > the hole in the directory inode. > > This checks for directory holes when buffer_head and error value are both > zero'ed returning -EIO to their callers > > Some ext3_bread() callers do not needed any changes either because they already > had its own hole detector paths or because these are deprecaded (like > dx_show_entries) > > V2: It adds a wrapper function ext3_dir_bread() to check for directory holes > when reading blocks for a directory inode, and callers of ext3_bread() to read > directory blocks were replaced by this wrapper. > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> Oh, I see you already sent V2. Thanks. I've put the patch to my tree. Honza > --- > fs/ext3/namei.c | 36 +++++++++++++++++++----------------- > fs/ext3/namei.h | 19 +++++++++++++++++++ > 2 files changed, 38 insertions(+), 17 deletions(-) > > diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c > index 7f6c938..0eecf4d 100644 > --- a/fs/ext3/namei.c > +++ b/fs/ext3/namei.c > @@ -46,8 +46,7 @@ static struct buffer_head *ext3_append(handle_t *handle, > > *block = inode->i_size >> inode->i_sb->s_blocksize_bits; > > - bh = ext3_bread(handle, inode, *block, 1, err); > - if (bh) { > + if ((bh = ext3_dir_bread(handle, inode, *block, 1, err))) { > inode->i_size += inode->i_sb->s_blocksize; > EXT3_I(inode)->i_disksize = inode->i_size; > *err = ext3_journal_get_write_access(handle, bh); > @@ -339,8 +338,10 @@ dx_probe(struct qstr *entry, struct inode *dir, > u32 hash; > > frame->bh = NULL; > - if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) > + if (!(bh = ext3_dir_bread(NULL, dir, 0, 0, err))) { > + *err = ERR_BAD_DX_DIR; > goto fail; > + } > root = (struct dx_root *) bh->b_data; > if (root->info.hash_version != DX_HASH_TEA && > root->info.hash_version != DX_HASH_HALF_MD4 && > @@ -436,8 +437,10 @@ dx_probe(struct qstr *entry, struct inode *dir, > frame->entries = entries; > frame->at = at; > if (!indirect--) return frame; > - if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) > + if (!(bh = ext3_dir_bread(NULL, dir, dx_get_block(at), 0, err))) { > + *err = ERR_BAD_DX_DIR; > goto fail2; > + } > at = entries = ((struct dx_node *) bh->b_data)->entries; > if (dx_get_limit(entries) != dx_node_limit (dir)) { > ext3_warning(dir->i_sb, __func__, > @@ -535,8 +538,8 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash, > * block so no check is necessary > */ > while (num_frames--) { > - if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), > - 0, &err))) > + if (!(bh = ext3_dir_bread(NULL, dir, dx_get_block(p->at), > + 0, &err))) > return err; /* Failure */ > p++; > brelse (p->bh); > @@ -562,7 +565,8 @@ static int htree_dirblock_to_tree(struct file *dir_file, > int err = 0, count = 0; > > dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); > - if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) > + > + if (!(bh = ext3_dir_bread(NULL, dir, block, 0, &err))) > return err; > > de = (struct ext3_dir_entry_2 *) bh->b_data; > @@ -976,7 +980,7 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, > return NULL; > do { > block = dx_get_block(frame->at); > - if (!(bh = ext3_bread (NULL,dir, block, 0, err))) > + if (!(bh = ext3_dir_bread (NULL, dir, block, 0, err))) > goto errout; > > retval = search_dirblock(bh, dir, entry, > @@ -1458,9 +1462,9 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, > } > blocks = dir->i_size >> sb->s_blocksize_bits; > for (block = 0; block < blocks; block++) { > - bh = ext3_bread(handle, dir, block, 0, &retval); > - if(!bh) > + if (!(bh = ext3_dir_bread(handle, dir, block, 0, &retval))) > return retval; > + > retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh); > if (retval != -ENOSPC) > return retval; > @@ -1500,7 +1504,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, > entries = frame->entries; > at = frame->at; > > - if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) > + if (!(bh = ext3_dir_bread(handle, dir, dx_get_block(frame->at), 0, &err))) > goto cleanup; > > BUFFER_TRACE(bh, "get_write_access"); > @@ -1790,8 +1794,7 @@ retry: > inode->i_op = &ext3_dir_inode_operations; > inode->i_fop = &ext3_dir_operations; > inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; > - dir_block = ext3_bread (handle, inode, 0, 1, &err); > - if (!dir_block) > + if (!(dir_block = ext3_dir_bread(handle, inode, 0, 1, &err))) > goto out_clear_inode; > > BUFFER_TRACE(dir_block, "get_write_access"); > @@ -1859,7 +1862,7 @@ static int empty_dir (struct inode * inode) > > sb = inode->i_sb; > if (inode->i_size < EXT3_DIR_REC_LEN(1) + EXT3_DIR_REC_LEN(2) || > - !(bh = ext3_bread (NULL, inode, 0, 0, &err))) { > + !(bh = ext3_dir_bread(NULL, inode, 0, 0, &err))) { > if (err) > ext3_error(inode->i_sb, __func__, > "error %d reading directory #%lu offset 0", > @@ -1890,9 +1893,8 @@ static int empty_dir (struct inode * inode) > (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) { > err = 0; > brelse (bh); > - bh = ext3_bread (NULL, inode, > - offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err); > - if (!bh) { > + if (!(bh = ext3_dir_bread (NULL, inode, > + offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err))) { > if (err) > ext3_error(sb, __func__, > "error %d reading directory" > diff --git a/fs/ext3/namei.h b/fs/ext3/namei.h > index f2ce2b0..46304d8 100644 > --- a/fs/ext3/namei.h > +++ b/fs/ext3/namei.h > @@ -6,3 +6,22 @@ > */ > > extern struct dentry *ext3_get_parent(struct dentry *child); > + > +static inline struct buffer_head *ext3_dir_bread(handle_t *handle, > + struct inode *inode, > + int block, int create, > + int *err) > +{ > + struct buffer_head *bh; > + > + bh = ext3_bread(handle, inode, block, create, err); > + > + if (!bh && !(*err)) { > + *err = -EIO; > + ext3_error(inode->i_sb, __func__, > + "Directory hole detected on inode %lu\n", > + inode->i_ino); > + return NULL; > + } > + return bh; > +} > -- > 1.7.11.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Jan Kara <jack@suse.cz> SUSE Labs, CR ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit [V2] 2012-10-04 12:42 ` Jan Kara @ 2012-10-04 13:02 ` Jan Kara 2012-10-04 13:57 ` Carlos Maiolino 0 siblings, 1 reply; 14+ messages in thread From: Jan Kara @ 2012-10-04 13:02 UTC (permalink / raw) To: Carlos Maiolino; +Cc: linux-ext4 On Thu 04-10-12 14:42:12, Jan Kara wrote: > On Tue 02-10-12 23:59:23, Carlos Maiolino wrote: > > This is the ext3 version of the same patch applied to Ext4, where such goal is > > to audit the usage of ext3_bread() due a possible misinterpretion of its return > > value. > > > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > > hole, which cannot exist into a directory inode. It can pass undetected after a > > fix in an uninitialized error variable. > > > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > > value of ext3_bread() to its callers, which can make the caller do not detect > > the hole in the directory inode. > > > > This checks for directory holes when buffer_head and error value are both > > zero'ed returning -EIO to their callers > > > > Some ext3_bread() callers do not needed any changes either because they already > > had its own hole detector paths or because these are deprecaded (like > > dx_show_entries) > > > > V2: It adds a wrapper function ext3_dir_bread() to check for directory holes > > when reading blocks for a directory inode, and callers of ext3_bread() to read > > directory blocks were replaced by this wrapper. > > > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> > Oh, I see you already sent V2. Thanks. I've put the patch to my tree. Umm, after checking - any reason why you didn't convert also ext3_bread() in dir.c and ext3_bread() in ext3_rename()? Honza -- Jan Kara <jack@suse.cz> SUSE Labs, CR ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit [V2] 2012-10-04 13:02 ` Jan Kara @ 2012-10-04 13:57 ` Carlos Maiolino 2012-10-04 14:29 ` Jan Kara 0 siblings, 1 reply; 14+ messages in thread From: Carlos Maiolino @ 2012-10-04 13:57 UTC (permalink / raw) To: linux-ext4 On Thu, Oct 04, 2012 at 03:02:44PM +0200, Jan Kara wrote: > On Thu 04-10-12 14:42:12, Jan Kara wrote: > > On Tue 02-10-12 23:59:23, Carlos Maiolino wrote: > > > This is the ext3 version of the same patch applied to Ext4, where such goal is > > > to audit the usage of ext3_bread() due a possible misinterpretion of its return > > > value. > > > > > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > > > hole, which cannot exist into a directory inode. It can pass undetected after a > > > fix in an uninitialized error variable. > > > > > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > > > value of ext3_bread() to its callers, which can make the caller do not detect > > > the hole in the directory inode. > > > > > > This checks for directory holes when buffer_head and error value are both > > > zero'ed returning -EIO to their callers > > > > > > Some ext3_bread() callers do not needed any changes either because they already > > > had its own hole detector paths or because these are deprecaded (like > > > dx_show_entries) > > > > > > V2: It adds a wrapper function ext3_dir_bread() to check for directory holes > > > when reading blocks for a directory inode, and callers of ext3_bread() to read > > > directory blocks were replaced by this wrapper. > > > > > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> > > Oh, I see you already sent V2. Thanks. I've put the patch to my tree. > Umm, after checking - any reason why you didn't convert also ext3_bread() > in dir.c and ext3_bread() in ext3_rename()? > I didn't convert some calls for ext3_bread() - like ext3_readdir() - because those really don't care about the err value, only about if bh is valid or not. I can change this if you want, not a problem from my point. -- --Carlos ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit [V2] 2012-10-04 13:57 ` Carlos Maiolino @ 2012-10-04 14:29 ` Jan Kara 2012-10-04 17:47 ` Carlos Maiolino 0 siblings, 1 reply; 14+ messages in thread From: Jan Kara @ 2012-10-04 14:29 UTC (permalink / raw) To: Carlos Maiolino; +Cc: linux-ext4 On Thu 04-10-12 10:57:46, Carlos Maiolino wrote: > On Thu, Oct 04, 2012 at 03:02:44PM +0200, Jan Kara wrote: > > On Thu 04-10-12 14:42:12, Jan Kara wrote: > > > On Tue 02-10-12 23:59:23, Carlos Maiolino wrote: > > > > This is the ext3 version of the same patch applied to Ext4, where such goal is > > > > to audit the usage of ext3_bread() due a possible misinterpretion of its return > > > > value. > > > > > > > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > > > > hole, which cannot exist into a directory inode. It can pass undetected after a > > > > fix in an uninitialized error variable. > > > > > > > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > > > > value of ext3_bread() to its callers, which can make the caller do not detect > > > > the hole in the directory inode. > > > > > > > > This checks for directory holes when buffer_head and error value are both > > > > zero'ed returning -EIO to their callers > > > > > > > > Some ext3_bread() callers do not needed any changes either because they already > > > > had its own hole detector paths or because these are deprecaded (like > > > > dx_show_entries) > > > > > > > > V2: It adds a wrapper function ext3_dir_bread() to check for directory holes > > > > when reading blocks for a directory inode, and callers of ext3_bread() to read > > > > directory blocks were replaced by this wrapper. > > > > > > > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> > > > Oh, I see you already sent V2. Thanks. I've put the patch to my tree. > > Umm, after checking - any reason why you didn't convert also ext3_bread() > > in dir.c and ext3_bread() in ext3_rename()? > > > I didn't convert some calls for ext3_bread() - like ext3_readdir() - > because those really don't care about the err value, only about if bh is > valid or not. I can change this if you want, not a problem from my point. Right. I've converted the call in ext3_rename() because there it seems useful. In ext3_readdir() calling ext3_bread() is better because we want to be able to read the faulty directory. Honza -- Jan Kara <jack@suse.cz> SUSE Labs, CR ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit [V2] 2012-10-04 14:29 ` Jan Kara @ 2012-10-04 17:47 ` Carlos Maiolino 2012-10-08 16:15 ` Jan Kara 0 siblings, 1 reply; 14+ messages in thread From: Carlos Maiolino @ 2012-10-04 17:47 UTC (permalink / raw) To: linux-ext4 On Thu, Oct 04, 2012 at 04:29:00PM +0200, Jan Kara wrote: > On Thu 04-10-12 10:57:46, Carlos Maiolino wrote: > > On Thu, Oct 04, 2012 at 03:02:44PM +0200, Jan Kara wrote: > > > On Thu 04-10-12 14:42:12, Jan Kara wrote: > > > > On Tue 02-10-12 23:59:23, Carlos Maiolino wrote: > > > > > This is the ext3 version of the same patch applied to Ext4, where such goal is > > > > > to audit the usage of ext3_bread() due a possible misinterpretion of its return > > > > > value. > > > > > > > > > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > > > > > hole, which cannot exist into a directory inode. It can pass undetected after a > > > > > fix in an uninitialized error variable. > > > > > > > > > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > > > > > value of ext3_bread() to its callers, which can make the caller do not detect > > > > > the hole in the directory inode. > > > > > > > > > > This checks for directory holes when buffer_head and error value are both > > > > > zero'ed returning -EIO to their callers > > > > > > > > > > Some ext3_bread() callers do not needed any changes either because they already > > > > > had its own hole detector paths or because these are deprecaded (like > > > > > dx_show_entries) > > > > > > > > > > V2: It adds a wrapper function ext3_dir_bread() to check for directory holes > > > > > when reading blocks for a directory inode, and callers of ext3_bread() to read > > > > > directory blocks were replaced by this wrapper. > > > > > > > > > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> > > > > Oh, I see you already sent V2. Thanks. I've put the patch to my tree. > > > Umm, after checking - any reason why you didn't convert also ext3_bread() > > > in dir.c and ext3_bread() in ext3_rename()? > > > > > I didn't convert some calls for ext3_bread() - like ext3_readdir() - > > because those really don't care about the err value, only about if bh is > > valid or not. I can change this if you want, not a problem from my point. > Right. I've converted the call in ext3_rename() because there it seems > useful. In ext3_readdir() calling ext3_bread() is better because we want > to be able to read the faulty directory. K, so I don't need to send a V3? cheers -- --Carlos ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] ext3: ext3_bread usage audit [V2] 2012-10-04 17:47 ` Carlos Maiolino @ 2012-10-08 16:15 ` Jan Kara 0 siblings, 0 replies; 14+ messages in thread From: Jan Kara @ 2012-10-08 16:15 UTC (permalink / raw) To: Carlos Maiolino; +Cc: linux-ext4 On Thu 04-10-12 14:47:43, Carlos Maiolino wrote: > On Thu, Oct 04, 2012 at 04:29:00PM +0200, Jan Kara wrote: > > On Thu 04-10-12 10:57:46, Carlos Maiolino wrote: > > > On Thu, Oct 04, 2012 at 03:02:44PM +0200, Jan Kara wrote: > > > > On Thu 04-10-12 14:42:12, Jan Kara wrote: > > > > > On Tue 02-10-12 23:59:23, Carlos Maiolino wrote: > > > > > > This is the ext3 version of the same patch applied to Ext4, where such goal is > > > > > > to audit the usage of ext3_bread() due a possible misinterpretion of its return > > > > > > value. > > > > > > > > > > > > Focused on directory blocks, a NULL value returned from ext3_bread() means a > > > > > > hole, which cannot exist into a directory inode. It can pass undetected after a > > > > > > fix in an uninitialized error variable. > > > > > > > > > > > > The (now) initialized variable into ext3_getblk() may lead to a zero'ed return > > > > > > value of ext3_bread() to its callers, which can make the caller do not detect > > > > > > the hole in the directory inode. > > > > > > > > > > > > This checks for directory holes when buffer_head and error value are both > > > > > > zero'ed returning -EIO to their callers > > > > > > > > > > > > Some ext3_bread() callers do not needed any changes either because they already > > > > > > had its own hole detector paths or because these are deprecaded (like > > > > > > dx_show_entries) > > > > > > > > > > > > V2: It adds a wrapper function ext3_dir_bread() to check for directory holes > > > > > > when reading blocks for a directory inode, and callers of ext3_bread() to read > > > > > > directory blocks were replaced by this wrapper. > > > > > > > > > > > > Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com> > > > > > Oh, I see you already sent V2. Thanks. I've put the patch to my tree. > > > > Umm, after checking - any reason why you didn't convert also ext3_bread() > > > > in dir.c and ext3_bread() in ext3_rename()? > > > > > > > I didn't convert some calls for ext3_bread() - like ext3_readdir() - > > > because those really don't care about the err value, only about if bh is > > > valid or not. I can change this if you want, not a problem from my point. > > Right. I've converted the call in ext3_rename() because there it seems > > useful. In ext3_readdir() calling ext3_bread() is better because we want > > to be able to read the faulty directory. > > K, so I don't need to send a V3? No. And please use reply-to-all! ;) Honza -- Jan Kara <jack@suse.cz> SUSE Labs, CR ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2012-10-08 16:15 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-10-01 19:50 [PATCH 0/2] ext3_bread usage audit due non-initialized variable Carlos Maiolino 2012-10-01 19:50 ` [PATCH 1/2] ext3: fix possible non-initialized variable on htree_dirblock_to_tree() Carlos Maiolino 2012-10-02 13:55 ` Jan Kara 2012-10-01 19:50 ` [PATCH 2/2] ext3: ext3_bread usage audit Carlos Maiolino 2012-10-02 13:55 ` Jan Kara 2012-10-02 14:27 ` Carlos Maiolino 2012-10-04 12:38 ` Jan Kara 2012-10-03 2:59 ` [PATCH 2/2] ext3: ext3_bread usage audit [V2] Carlos Maiolino 2012-10-04 12:42 ` Jan Kara 2012-10-04 13:02 ` Jan Kara 2012-10-04 13:57 ` Carlos Maiolino 2012-10-04 14:29 ` Jan Kara 2012-10-04 17:47 ` Carlos Maiolino 2012-10-08 16:15 ` Jan Kara
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).