From: Greg Kroah-Hartman Date: Thu, 7 Sep 2023 15:00:22 +0000 (+0100) Subject: 5.10-stable patches X-Git-Tag: v6.1.53~129 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7e0748da25dc52cfe9240788d86e663b1ec3611b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: udf-check-consistency-of-space-bitmap-descriptor.patch udf-handle-error-when-adding-extent-to-a-file.patch --- diff --git a/queue-5.10/series b/queue-5.10/series index cc8255ee81a..99195728d65 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -59,3 +59,5 @@ alsa-seq-oss-fix-racy-open-close-of-midi-devices.patch tracing-introduce-pipe_cpumask-to-avoid-race-on-trac.patch platform-mellanox-fix-mlxbf-tmfifo-not-handling-all-.patch net-avoid-address-overwrite-in-kernel_connect.patch +udf-check-consistency-of-space-bitmap-descriptor.patch +udf-handle-error-when-adding-extent-to-a-file.patch diff --git a/queue-5.10/udf-check-consistency-of-space-bitmap-descriptor.patch b/queue-5.10/udf-check-consistency-of-space-bitmap-descriptor.patch new file mode 100644 index 00000000000..728729e62e9 --- /dev/null +++ b/queue-5.10/udf-check-consistency-of-space-bitmap-descriptor.patch @@ -0,0 +1,86 @@ +From 1e0d4adf17e7ef03281d7b16555e7c1508c8ed2d Mon Sep 17 00:00:00 2001 +From: Vladislav Efanov +Date: Thu, 2 Feb 2023 17:04:56 +0300 +Subject: udf: Check consistency of Space Bitmap Descriptor + +From: Vladislav Efanov + +commit 1e0d4adf17e7ef03281d7b16555e7c1508c8ed2d upstream. + +Bits, which are related to Bitmap Descriptor logical blocks, +are not reset when buffer headers are allocated for them. As the +result, these logical blocks can be treated as free and +be used for other blocks.This can cause usage of one buffer header +for several types of data. UDF issues WARNING in this situation: + +WARNING: CPU: 0 PID: 2703 at fs/udf/inode.c:2014 + __udf_add_aext+0x685/0x7d0 fs/udf/inode.c:2014 + +RIP: 0010:__udf_add_aext+0x685/0x7d0 fs/udf/inode.c:2014 +Call Trace: + udf_setup_indirect_aext+0x573/0x880 fs/udf/inode.c:1980 + udf_add_aext+0x208/0x2e0 fs/udf/inode.c:2067 + udf_insert_aext fs/udf/inode.c:2233 [inline] + udf_update_extents fs/udf/inode.c:1181 [inline] + inode_getblk+0x1981/0x3b70 fs/udf/inode.c:885 + +Found by Linux Verification Center (linuxtesting.org) with syzkaller. + +[JK: Somewhat cleaned up the boundary checks] + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Vladislav Efanov +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman +--- + fs/udf/balloc.c | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +--- a/fs/udf/balloc.c ++++ b/fs/udf/balloc.c +@@ -36,18 +36,41 @@ static int read_block_bitmap(struct supe + unsigned long bitmap_nr) + { + struct buffer_head *bh = NULL; +- int retval = 0; ++ int i; ++ int max_bits, off, count; + struct kernel_lb_addr loc; + + loc.logicalBlockNum = bitmap->s_extPosition; + loc.partitionReferenceNum = UDF_SB(sb)->s_partition; + + bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block)); ++ bitmap->s_block_bitmap[bitmap_nr] = bh; + if (!bh) +- retval = -EIO; ++ return -EIO; + +- bitmap->s_block_bitmap[bitmap_nr] = bh; +- return retval; ++ /* Check consistency of Space Bitmap buffer. */ ++ max_bits = sb->s_blocksize * 8; ++ if (!bitmap_nr) { ++ off = sizeof(struct spaceBitmapDesc) << 3; ++ count = min(max_bits - off, bitmap->s_nr_groups); ++ } else { ++ /* ++ * Rough check if bitmap number is too big to have any bitmap ++ * blocks reserved. ++ */ ++ if (bitmap_nr > ++ (bitmap->s_nr_groups >> (sb->s_blocksize_bits + 3)) + 2) ++ return 0; ++ off = 0; ++ count = bitmap->s_nr_groups - bitmap_nr * max_bits + ++ (sizeof(struct spaceBitmapDesc) << 3); ++ count = min(count, max_bits); ++ } ++ ++ for (i = 0; i < count; i++) ++ if (udf_test_bit(i + off, bh->b_data)) ++ return -EFSCORRUPTED; ++ return 0; + } + + static int __load_block_bitmap(struct super_block *sb, diff --git a/queue-5.10/udf-handle-error-when-adding-extent-to-a-file.patch b/queue-5.10/udf-handle-error-when-adding-extent-to-a-file.patch new file mode 100644 index 00000000000..64475b6dfc2 --- /dev/null +++ b/queue-5.10/udf-handle-error-when-adding-extent-to-a-file.patch @@ -0,0 +1,124 @@ +From 19fd80de0a8b5170ef34704c8984cca920dffa59 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 19 Dec 2022 20:10:35 +0100 +Subject: udf: Handle error when adding extent to a file + +From: Jan Kara + +commit 19fd80de0a8b5170ef34704c8984cca920dffa59 upstream. + +When adding extent to a file fails, so far we've silently squelshed the +error. Make sure to propagate it up properly. + +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman +--- + fs/udf/inode.c | 41 +++++++++++++++++++++++++++-------------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +--- a/fs/udf/inode.c ++++ b/fs/udf/inode.c +@@ -57,15 +57,15 @@ static int udf_update_inode(struct inode + static int udf_sync_inode(struct inode *inode); + static int udf_alloc_i_data(struct inode *inode, size_t size); + static sector_t inode_getblk(struct inode *, sector_t, int *, int *); +-static int8_t udf_insert_aext(struct inode *, struct extent_position, +- struct kernel_lb_addr, uint32_t); ++static int udf_insert_aext(struct inode *, struct extent_position, ++ struct kernel_lb_addr, uint32_t); + static void udf_split_extents(struct inode *, int *, int, udf_pblk_t, + struct kernel_long_ad *, int *); + static void udf_prealloc_extents(struct inode *, int, int, + struct kernel_long_ad *, int *); + static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *); +-static void udf_update_extents(struct inode *, struct kernel_long_ad *, int, +- int, struct extent_position *); ++static int udf_update_extents(struct inode *, struct kernel_long_ad *, int, ++ int, struct extent_position *); + static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); + + static void __udf_clear_extent_cache(struct inode *inode) +@@ -887,7 +887,9 @@ static sector_t inode_getblk(struct inod + /* write back the new extents, inserting new extents if the new number + * of extents is greater than the old number, and deleting extents if + * the new number of extents is less than the old number */ +- udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); ++ *err = udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); ++ if (*err < 0) ++ goto out_free; + + newblock = udf_get_pblock(inode->i_sb, newblocknum, + iinfo->i_location.partitionReferenceNum, 0); +@@ -1155,21 +1157,30 @@ static void udf_merge_extents(struct ino + } + } + +-static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, +- int startnum, int endnum, +- struct extent_position *epos) ++static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, ++ int startnum, int endnum, ++ struct extent_position *epos) + { + int start = 0, i; + struct kernel_lb_addr tmploc; + uint32_t tmplen; ++ int err; + + if (startnum > endnum) { + for (i = 0; i < (startnum - endnum); i++) + udf_delete_aext(inode, *epos); + } else if (startnum < endnum) { + for (i = 0; i < (endnum - startnum); i++) { +- udf_insert_aext(inode, *epos, laarr[i].extLocation, +- laarr[i].extLength); ++ err = udf_insert_aext(inode, *epos, ++ laarr[i].extLocation, ++ laarr[i].extLength); ++ /* ++ * If we fail here, we are likely corrupting the extent ++ * list and leaking blocks. At least stop early to ++ * limit the damage. ++ */ ++ if (err < 0) ++ return err; + udf_next_aext(inode, epos, &laarr[i].extLocation, + &laarr[i].extLength, 1); + start++; +@@ -1181,6 +1192,7 @@ static void udf_update_extents(struct in + udf_write_aext(inode, epos, &laarr[i].extLocation, + laarr[i].extLength, 1); + } ++ return 0; + } + + struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block, +@@ -2215,12 +2227,13 @@ int8_t udf_current_aext(struct inode *in + return etype; + } + +-static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, +- struct kernel_lb_addr neloc, uint32_t nelen) ++static int udf_insert_aext(struct inode *inode, struct extent_position epos, ++ struct kernel_lb_addr neloc, uint32_t nelen) + { + struct kernel_lb_addr oeloc; + uint32_t oelen; + int8_t etype; ++ int err; + + if (epos.bh) + get_bh(epos.bh); +@@ -2230,10 +2243,10 @@ static int8_t udf_insert_aext(struct ino + neloc = oeloc; + nelen = (etype << 30) | oelen; + } +- udf_add_aext(inode, &epos, &neloc, nelen, 1); ++ err = udf_add_aext(inode, &epos, &neloc, nelen, 1); + brelse(epos.bh); + +- return (nelen >> 30); ++ return err; + } + + int8_t udf_delete_aext(struct inode *inode, struct extent_position epos)