lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 10 Aug 2016 23:12:31 +0100
From:	Salah Triki <salah.triki@...il.com>
To:	akpm@...ux-foundation.org, viro@...iv.linux.org.uk,
	luisbg@....samsung.com
Cc:	linux-kernel@...r.kernel.org, salah.triki@...il.com
Subject: [PATCH 2/4] befs: check return value of iaddr2blockno

The call of iaddr2blockno may fail, so check its return value and
propagate error, if any.

Signed-off-by: Salah Triki <salah.triki@...il.com>
---
 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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ