summary refs log tree commit diff
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2022-12-16 12:37:51 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-03-10 09:34:10 +0100
commitadac9ac6d2e04ea0782b91a00ba10706002f3ec4 (patch)
treedbf4ea24bdcd2bbf9ea88c46d1c7586c7611f6f7
parent0e7d8e2991e5f1a8cb58b42826ef849d40718899 (diff)
downloadlinux-adac9ac6d2e04ea0782b91a00ba10706002f3ec4.tar.gz
udf: Do not bother merging very long extents
commit 53cafe1d6d8ef9f93318e5bfccc0d24f27d41ced upstream.

When merging very long extents we try to push as much length as possible
to the first extent. However this is unnecessarily complicated and not
really worth the trouble. Furthermore there was a bug in the logic
resulting in corrupting extents in the file as syzbot reproducer shows.
So just don't bother with the merging of extents that are too long
together.

CC: stable@vger.kernel.org
Reported-by: syzbot+60f291a24acecb3c2bd5@syzkaller.appspotmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/udf/inode.c19
1 files changed, 2 insertions, 17 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index f8908c1f482e..e531cd216d5b 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1094,23 +1094,8 @@ static void udf_merge_extents(struct inode *inode, struct kernel_long_ad *laarr,
 			blocksize - 1) >> blocksize_bits)))) {
 
 			if (((li->extLength & UDF_EXTENT_LENGTH_MASK) +
-				(lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
-				blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
-				lip1->extLength = (lip1->extLength -
-						  (li->extLength &
-						   UDF_EXTENT_LENGTH_MASK) +
-						   UDF_EXTENT_LENGTH_MASK) &
-							~(blocksize - 1);
-				li->extLength = (li->extLength &
-						 UDF_EXTENT_FLAG_MASK) +
-						(UDF_EXTENT_LENGTH_MASK + 1) -
-						blocksize;
-				lip1->extLocation.logicalBlockNum =
-					li->extLocation.logicalBlockNum +
-					((li->extLength &
-						UDF_EXTENT_LENGTH_MASK) >>
-						blocksize_bits);
-			} else {
+			     (lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
+			     blocksize - 1) <= UDF_EXTENT_LENGTH_MASK) {
 				li->extLength = lip1->extLength +
 					(((li->extLength &
 						UDF_EXTENT_LENGTH_MASK) +