]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
udf: Do not bother merging very long extents
authorJan Kara <jack@suse.cz>
Fri, 16 Dec 2022 11:37:51 +0000 (12:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 11 Mar 2023 15:26:45 +0000 (16:26 +0100)
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>
fs/udf/inode.c

index 022cd00ae473900f6785421532517f42b56c3cf5..f435b5d146a775c5726d81e3a7569622236ae8c9 100644 (file)
@@ -1089,23 +1089,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) +