]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
udf: Avoid excessive partition lengths
authorJan Kara <jack@suse.cz>
Thu, 20 Jun 2024 10:52:17 +0000 (12:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 12 Sep 2024 09:06:46 +0000 (11:06 +0200)
[ Upstream commit ebbe26fd54a9621994bc16b14f2ba8f84c089693 ]

Avoid mounting filesystems where the partition would overflow the
32-bits used for block number. Also refuse to mount filesystems where
the partition length is so large we cannot safely index bits in a
block bitmap.

Link: https://patch.msgid.link/20240620130403.14731-1-jack@suse.cz
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/udf/super.c

index 5d79e5d2e158b75e18bc71e2a1941789cb8b276f..ae75df43d51cb8f59eb0bb0c42c55545e9abf7ec 100644 (file)
@@ -1083,12 +1083,19 @@ static int udf_fill_partdesc_info(struct super_block *sb,
        struct udf_part_map *map;
        struct udf_sb_info *sbi = UDF_SB(sb);
        struct partitionHeaderDesc *phd;
+       u32 sum;
        int err;
 
        map = &sbi->s_partmaps[p_index];
 
        map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */
        map->s_partition_root = le32_to_cpu(p->partitionStartingLocation);
+       if (check_add_overflow(map->s_partition_root, map->s_partition_len,
+                              &sum)) {
+               udf_err(sb, "Partition %d has invalid location %u + %u\n",
+                       p_index, map->s_partition_root, map->s_partition_len);
+               return -EFSCORRUPTED;
+       }
 
        if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY))
                map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY;
@@ -1144,6 +1151,14 @@ static int udf_fill_partdesc_info(struct super_block *sb,
                bitmap->s_extPosition = le32_to_cpu(
                                phd->unallocSpaceBitmap.extPosition);
                map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
+               /* Check whether math over bitmap won't overflow. */
+               if (check_add_overflow(map->s_partition_len,
+                                      sizeof(struct spaceBitmapDesc) << 3,
+                                      &sum)) {
+                       udf_err(sb, "Partition %d is too long (%u)\n", p_index,
+                               map->s_partition_len);
+                       return -EFSCORRUPTED;
+               }
                udf_debug("unallocSpaceBitmap (part %d) @ %u\n",
                          p_index, bitmap->s_extPosition);
        }