[PATCH] udf: Fix slab-out-of-bound write in udf_write_aext

Abdun Nihaal posted 1 patch 2 years, 8 months ago
fs/udf/namei.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
[PATCH] udf: Fix slab-out-of-bound write in udf_write_aext
Posted by Abdun Nihaal 2 years, 8 months ago
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@syzkaller.appspotmail.com
Signed-off-by: Abdun Nihaal <abdun.nihaal@gmail.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
Re: [PATCH] udf: Fix slab-out-of-bound write in udf_write_aext
Posted by Abdun Nihaal 2 years, 8 months ago
Hello Jan,

I just realized that I have been working with an older tree and the
patch I sent does not apply. Please ignore my previous mail.

I'll check if the bug still exists in your latest tree and
I'll send a newer version of the patch if the bug is still present.

Regards,
Abdun nihaal