From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934172AbcHJWNR (ORCPT ); Wed, 10 Aug 2016 18:13:17 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:33874 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752652AbcHJWMp (ORCPT ); Wed, 10 Aug 2016 18:12:45 -0400 From: Salah Triki To: akpm@linux-foundation.org, viro@zeniv.linux.org.uk, luisbg@osg.samsung.com Cc: linux-kernel@vger.kernel.org, salah.triki@gmail.com Subject: [PATCH 2/4] befs: check return value of iaddr2blockno Date: Wed, 10 Aug 2016 23:12:31 +0100 Message-Id: <3d14bb68d07527c4dd72c8570001e55a5b204fee.1470867071.git.salah.triki@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <8f7f9b76ead677bdc834867e549ea6c4d1c04ccd.1470867071.git.salah.triki@gmail.com> References: <8f7f9b76ead677bdc834867e549ea6c4d1c04ccd.1470867071.git.salah.triki@gmail.com> In-Reply-To: <8f7f9b76ead677bdc834867e549ea6c4d1c04ccd.1470867071.git.salah.triki@gmail.com> References: <8f7f9b76ead677bdc834867e549ea6c4d1c04ccd.1470867071.git.salah.triki@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The call of iaddr2blockno may fail, so check its return value and propagate error, if any. Signed-off-by: Salah Triki --- fs/befs/datastream.c | 30 ++++++++++++++++++++---------- fs/befs/inode.c | 10 ++++++++-- fs/befs/io.c | 3 +++ fs/befs/linuxvfs.c | 12 +++++++++++- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/fs/befs/datastream.c b/fs/befs/datastream.c index 343123c..1747f64 100644 --- a/fs/befs/datastream.c +++ b/fs/befs/datastream.c @@ -308,8 +308,11 @@ befs_find_brun_indirect(struct super_block *sb, befs_disk_block_run *array; befs_block_run indirect = data->indirect; - befs_blocknr_t indirblockno = iaddr2blockno(sb, &indirect); int arraylen = befs_iaddrs_per_block(sb); + befs_blocknr_t indirblockno = iaddr2blockno(sb, &indirect); + + if (indirblockno == BEFS_ERR) + return BEFS_ERR; befs_debug(sb, "---> %s, find %lu", __func__, (unsigned long)blockno); @@ -422,6 +425,7 @@ befs_find_brun_dblindirect(struct super_block *sb, struct buffer_head *indir_block; befs_block_run indir_run; befs_disk_inode_addr *iaddr_array; + befs_blocknr_t block; befs_blocknr_t indir_start_blk = data->max_indirect_range >> BEFS_SB(sb)->block_shift; @@ -461,15 +465,17 @@ befs_find_brun_dblindirect(struct super_block *sb, return BEFS_ERR; } - dbl_indir_block = - sb_bread(sb, iaddr2blockno(sb, &data->double_indirect) + - dbl_which_block); + block = iaddr2blockno(sb, &data->double_indirect); + + if (block == BEFS_ERR) + return BEFS_ERR; + + dbl_indir_block = sb_bread(sb, blockno + dbl_which_block); + if (dbl_indir_block == NULL) { befs_error(sb, "%s couldn't read the " "double-indirect block at blockno %lu", __func__, - (unsigned long) - iaddr2blockno(sb, &data->double_indirect) + - dbl_which_block); + (unsigned long)blockno + dbl_which_block); return BEFS_ERR; } @@ -488,12 +494,16 @@ befs_find_brun_dblindirect(struct super_block *sb, return BEFS_ERR; } - indir_block = - sb_bread(sb, iaddr2blockno(sb, &indir_run) + which_block); + blockno = iaddr2blockno(sb, &indir_run); + + if (blockno == BEFS_ERR) + return BEFS_ERR; + + indir_block = sb_bread(sb, blockno + which_block); if (indir_block == NULL) { befs_error(sb, "%s couldn't read the indirect block " "at blockno %lu", __func__, (unsigned long) - iaddr2blockno(sb, &indir_run) + which_block); + blockno + which_block); return BEFS_ERR; } diff --git a/fs/befs/inode.c b/fs/befs/inode.c index fa4b718..495d270 100644 --- a/fs/befs/inode.c +++ b/fs/befs/inode.c @@ -21,6 +21,7 @@ befs_check_inode(struct super_block *sb, befs_inode * raw_inode, u32 magic1 = fs32_to_cpu(sb, raw_inode->magic1); befs_inode_addr ino_num = fsrun_to_cpu(sb, raw_inode->inode_num); u32 flags = fs32_to_cpu(sb, raw_inode->flags); + befs_blocknr_t block; /* check magic header. */ if (magic1 != BEFS_INODE_MAGIC1) { @@ -33,10 +34,15 @@ befs_check_inode(struct super_block *sb, befs_inode * raw_inode, /* * Sanity check2: inodes store their own block address. Check it. */ - if (inode != iaddr2blockno(sb, &ino_num)) { + block = iaddr2blockno(sb, &ino_num); + + if (block == BEFS_ERR) + return BEFS_ERR; + + if (inode != block) { befs_error(sb, "inode blocknr field disagrees with vfs " "VFS: %lu, Inode %lu", (unsigned long) - inode, (unsigned long)iaddr2blockno(sb, &ino_num)); + inode, (unsigned long)block); return BEFS_BAD_INODE; } diff --git a/fs/befs/io.c b/fs/befs/io.c index 4223b77..14eef7d 100644 --- a/fs/befs/io.c +++ b/fs/befs/io.c @@ -42,6 +42,9 @@ befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr) block = iaddr2blockno(sb, &iaddr); + if (block == BEFS_ERR) + goto error; + befs_debug(sb, "%s: offset = %lu", __func__, (unsigned long)block); bh = sb_bread(sb, block); diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index c57f831..6635515 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -143,6 +143,9 @@ befs_get_block(struct inode *inode, sector_t block, disk_off = (ulong) iaddr2blockno(sb, &run); + if (disk_off == BEFS_ERR) + return -EINVAL; + map_bh(bh_result, inode->i_sb, disk_off); befs_debug(sb, "<--- %s for inode %lu, block %ld, disk address %lu", @@ -756,6 +759,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent) long ret = -EINVAL; const unsigned long sb_block = 0; const off_t x86_sb_off = 512; + befs_blocknr_t block; save_mount_options(sb, data); @@ -830,7 +834,13 @@ befs_fill_super(struct super_block *sb, void *data, int silent) /* Set real blocksize of fs */ sb_set_blocksize(sb, (ulong) befs_sb->block_size); sb->s_op = &befs_sops; - root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))); + + block = iaddr2blockno(sb, &(befs_sb->root_dir)); + + if (block == BEFS_ERR) + goto unacquire_priv_sbp; + + root = befs_iget(sb, block); if (IS_ERR(root)) { ret = PTR_ERR(root); goto unacquire_priv_sbp; -- 1.9.1