]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
udf: fix partition descriptor append bookkeeping
authorSeohyeon Maeng <bioloidgp@gmail.com>
Tue, 10 Mar 2026 08:16:52 +0000 (17:16 +0900)
committerJan Kara <jack@suse.cz>
Thu, 19 Mar 2026 13:44:07 +0000 (14:44 +0100)
Mounting a crafted UDF image with repeated partition descriptors can
trigger a heap out-of-bounds write in part_descs_loc[].

handle_partition_descriptor() deduplicates entries by partition number,
but appended slots never record partnum. As a result duplicate
Partition Descriptors are appended repeatedly and num_part_descs keeps
growing.

Once the table is full, the growth path still sizes the allocation from
partnum even though inserts are indexed by num_part_descs. If partnum is
already aligned to PART_DESC_ALLOC_STEP, ALIGN(partnum, step) can keep
the old capacity and the next append writes past the end of the table.

Store partnum in the appended slot and size growth from the next append
count so deduplication and capacity tracking follow the same model.

Fixes: ee4af50ca94f ("udf: Fix mounting of Win7 created UDF filesystems")
Cc: stable@vger.kernel.org
Signed-off-by: Seohyeon Maeng <bioloidgp@gmail.com>
Link: https://patch.msgid.link/20260310081652.21220-1-bioloidgp@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
fs/udf/super.c

index 27f463fd1d89e8ae4844cd70c291d737aee1589e..df2b62eddfc0cac57b45ff15bb33ad9919bd8162 100644 (file)
@@ -1694,8 +1694,9 @@ static struct udf_vds_record *handle_partition_descriptor(
                        return &(data->part_descs_loc[i].rec);
        if (data->num_part_descs >= data->size_part_descs) {
                struct part_desc_seq_scan_data *new_loc;
-               unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP);
+               unsigned int new_size;
 
+               new_size = data->num_part_descs + PART_DESC_ALLOC_STEP;
                new_loc = kzalloc_objs(*new_loc, new_size);
                if (!new_loc)
                        return ERR_PTR(-ENOMEM);
@@ -1705,6 +1706,7 @@ static struct udf_vds_record *handle_partition_descriptor(
                data->part_descs_loc = new_loc;
                data->size_part_descs = new_size;
        }
+       data->part_descs_loc[data->num_part_descs].partnum = partnum;
        return &(data->part_descs_loc[data->num_part_descs++].rec);
 }