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-next>] [day] [month] [year] [list]
Date:   Thu, 29 Dec 2022 10:31:42 +0530
From:   Abdun Nihaal <abdun.nihaal@...il.com>
To:     jack@...e.com
Cc:     linux-kernel@...r.kernel.org,
        Abdun Nihaal <abdun.nihaal@...il.com>,
        syzbot+908340a8367281960537@...kaller.appspotmail.com
Subject: [PATCH] udf: Fix slab-out-of-bound write in udf_write_aext

Syzbot reports an out of bound write in udf_write_aext.
This bug can be reproduced by mounting a UDF filesystem with the
noadinicb mount option and then creating a directory inside.

The bug is caused because udf_add_entry function tries to incorrectly
round off the previous extent for the newly created inode.

Fix the bug by creating an extent before calling udf_add_entry when the
noadinicb option is used, in udf_mkdir function.

Link: https://syzkaller.appspot.com/bug?id=5870f4bbc7294f2b4405a408e35e7e96100fb284
Reported-and-tested-by: syzbot+908340a8367281960537@...kaller.appspotmail.com
Signed-off-by: Abdun Nihaal <abdun.nihaal@...il.com>
---
 fs/udf/namei.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 7c95c549dd64..796fd3be3769 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -678,6 +678,47 @@ static int udf_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
 	iinfo = UDF_I(inode);
 	inode->i_op = &udf_dir_inode_operations;
 	inode->i_fop = &udf_dir_operations;
+	if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
+		struct kernel_lb_addr eloc;
+		struct extent_position epos = {};
+		udf_pblk_t block;
+		uint32_t bsize;
+
+		block = udf_new_block(dir->i_sb, inode,
+				      iinfo->i_location.partitionReferenceNum,
+				      iinfo->i_location.logicalBlockNum, &err);
+		if (!block) {
+			inode_dec_link_count(inode);
+			discard_new_inode(inode);
+			goto out;
+		}
+		epos.block = iinfo->i_location;
+		epos.offset = udf_file_entry_alloc_offset(inode);
+		epos.bh = NULL;
+		eloc.logicalBlockNum = block;
+		eloc.partitionReferenceNum =
+			iinfo->i_location.partitionReferenceNum;
+		bsize = dir->i_sb->s_blocksize;
+		iinfo->i_lenExtents = bsize;
+		udf_add_aext(inode, &epos, &eloc, bsize, 0);
+		brelse(epos.bh);
+
+		block = udf_get_pblock(dir->i_sb, block,
+				       iinfo->i_location.partitionReferenceNum,
+				       0);
+		epos.bh = udf_tgetblk(dir->i_sb, block);
+		if (unlikely(!epos.bh)) {
+			err = -ENOMEM;
+			inode_dec_link_count(inode);
+			discard_new_inode(inode);
+			goto out;
+		}
+		lock_buffer(epos.bh);
+		memset(epos.bh->b_data, 0x00, bsize);
+		set_buffer_uptodate(epos.bh);
+		unlock_buffer(epos.bh);
+		mark_buffer_dirty_inode(epos.bh, inode);
+	}
 	fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);
 	if (!fi) {
 		inode_dec_link_count(inode);
-- 
2.38.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ