VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45991

CVE-2026-45991

Description

In the Linux kernel, the following vulnerability has been resolved:

udf: fix partition descriptor append bookkeeping

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.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A heap out-of-bounds write in Linux kernel UDF filesystem code occurs when a crafted image with repeated partition descriptors is mounted.

Vulnerability

In the Linux kernel, the UDF filesystem's handle_partition_descriptor() function mishandles bookkeeping for appended partition descriptors. When a crafted UDF image with repeated partition descriptors is mounted, the function deduplicates by partition number but fails to record the partition number in appended slots. This causes duplicate descriptors to be appended repeatedly, incrementing num_part_descs beyond the allocated size of the part_descs_loc[] array. The growth path sizes reallocation based on partnum instead of the next append count, and if partnum is already aligned to PART_DESC_ALLOC_STEP, the capacity may not increase, leading to a heap out-of-bounds write. The issue affects all versions of the kernel up to the fix commit [1].

Exploitation

An attacker must present a crafted UDF filesystem image to the system and trigger a mount operation (either by inserting a physical disc or mounting an image file). No authentication or special privileges are required if the attacker can cause the kernel to mount the malicious image (e.g., via a removable medium or a user mounting the image). The exploitation sequence involves the kernel parsing the image, calling handle_partition_descriptor() multiple times with the repeated descriptors, leading to the heap overflow when the table is full and the allocation sizing is incorrect [1].

Impact

A successful exploit results in a heap out-of-bounds write, which can corrupt kernel memory. This likely leads to system crash (denial of service) and may allow an attacker to escalate privileges or execute arbitrary code in kernel context, depending on the memory layout. The vulnerability is classified as high severity with a CVSS score of 7.8, indicating potential for local privilege escalation or denial of service [1].

Mitigation

The fix is included in the Linux kernel stable commit b5597bb83fc37b5b5da74a4453fa920b932cf39a [1]. Affected systems should apply the patch or update to a kernel version that includes the fix. As of the publication date (2026-05-27), no workaround is available; the only mitigation is to avoid mounting untrusted UDF images or to update the kernel. The vulnerability is not listed on CISA's Known Exploited Vulnerabilities (KEV) catalog.

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

8
08fa5d818e5b

udf: fix partition descriptor append bookkeeping

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitSeohyeon MaengMar 10, 2026Fixed in 7.0.4via kernel-cna
1 file changed · +3 2
  • fs/udf/super.c+3 2 modified
    diff --git a/fs/udf/super.c b/fs/udf/super.c
    index 27f463fd1d89e8..df2b62eddfc0ca 100644
    --- a/fs/udf/super.c
    +++ b/fs/udf/super.c
    @@ -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);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
08841b06fa64

udf: fix partition descriptor append bookkeeping

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitSeohyeon MaengMar 10, 2026Fixed in 7.1-rc1via kernel-cna
1 file changed · +3 2
  • fs/udf/super.c+3 2 modified
    diff --git a/fs/udf/super.c b/fs/udf/super.c
    index 27f463fd1d89e8..df2b62eddfc0ca 100644
    --- a/fs/udf/super.c
    +++ b/fs/udf/super.c
    @@ -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);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
058b451b1039

udf: fix partition descriptor append bookkeeping

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitSeohyeon MaengFixed in 6.6.140via kernel-cna
1 file changed · +3 2
  • fs/udf/super.c+3 2 modified
    diff --git a/fs/udf/super.c b/fs/udf/super.c
    index cb13a07a4aa852..dbf5faf079128f 100644
    --- a/fs/udf/super.c
    +++ b/fs/udf/super.c
    @@ -1656,8 +1656,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 = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
     		if (!new_loc)
     			return ERR_PTR(-ENOMEM);
    @@ -1667,6 +1668,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);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
b5597bb83fc3

udf: fix partition descriptor append bookkeeping

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitSeohyeon MaengFixed in 6.12.88via kernel-cna
1 file changed · +3 2
  • fs/udf/super.c+3 2 modified
    diff --git a/fs/udf/super.c b/fs/udf/super.c
    index b2f168b0a0d18e..1518b37f259406 100644
    --- a/fs/udf/super.c
    +++ b/fs/udf/super.c
    @@ -1695,8 +1695,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 = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
     		if (!new_loc)
     			return ERR_PTR(-ENOMEM);
    @@ -1706,6 +1707,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);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
08841b06fa64

udf: fix partition descriptor append bookkeeping

1 file changed · +3 2
  • fs/udf/super.c+3 2 modified
    diff --git a/fs/udf/super.c b/fs/udf/super.c
    index 27f463fd1d89e8..df2b62eddfc0ca 100644
    --- a/fs/udf/super.c
    +++ b/fs/udf/super.c
    @@ -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);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
08fa5d818e5b

udf: fix partition descriptor append bookkeeping

1 file changed · +3 2
  • fs/udf/super.c+3 2 modified
    diff --git a/fs/udf/super.c b/fs/udf/super.c
    index 27f463fd1d89e8..df2b62eddfc0ca 100644
    --- a/fs/udf/super.c
    +++ b/fs/udf/super.c
    @@ -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);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
058b451b1039

udf: fix partition descriptor append bookkeeping

1 file changed · +3 2
  • fs/udf/super.c+3 2 modified
    diff --git a/fs/udf/super.c b/fs/udf/super.c
    index cb13a07a4aa852..dbf5faf079128f 100644
    --- a/fs/udf/super.c
    +++ b/fs/udf/super.c
    @@ -1656,8 +1656,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 = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
     		if (!new_loc)
     			return ERR_PTR(-ENOMEM);
    @@ -1667,6 +1668,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);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
b5597bb83fc3

udf: fix partition descriptor append bookkeeping

1 file changed · +3 2
  • fs/udf/super.c+3 2 modified
    diff --git a/fs/udf/super.c b/fs/udf/super.c
    index b2f168b0a0d18e..1518b37f259406 100644
    --- a/fs/udf/super.c
    +++ b/fs/udf/super.c
    @@ -1695,8 +1695,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 = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
     		if (!new_loc)
     			return ERR_PTR(-ENOMEM);
    @@ -1706,6 +1707,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);
     }
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing assignment of partnum in appended partition descriptor slots causes deduplication to fail and the growth path to size allocations from partnum instead of the actual append count, leading to a heap out-of-bounds write."

Attack vector

An attacker mounts a crafted UDF filesystem image containing repeated Partition Descriptors with partition numbers that are already aligned to PART_DESC_ALLOC_STEP. Because handle_partition_descriptor() never stores partnum in appended slots, deduplication fails and num_part_descs grows unbounded. When the table is full, the reallocation sizes the new buffer using ALIGN(partnum, PART_DESC_ALLOC_STEP) instead of the actual number of appended entries, which can compute the same capacity as before. The next append then writes past the end of the heap-allocated part_descs_loc[] array [patch_id=2660633].

Affected code

The vulnerable function is handle_partition_descriptor() in fs/udf/super.c [patch_id=2660633]. The bug involves the part_descs_loc[] array, the num_part_descs counter, and the size_part_descs capacity field within the partition descriptor scan data structure.

What the fix does

The patch makes two changes in handle_partition_descriptor() in fs/udf/super.c [patch_id=2660633]. First, the reallocation size is changed from ALIGN(partnum, PART_DESC_ALLOC_STEP) to data->num_part_descs + PART_DESC_ALLOC_STEP, so capacity grows based on the actual number of appended descriptors rather than the partition number. Second, a line is added to store partnum in the newly appended slot (data->part_descs_loc[data->num_part_descs].partnum = partnum), which ensures that subsequent deduplication scans will find the existing entry and stop appending duplicates.

Preconditions

  • inputAttacker must supply a crafted UDF filesystem image with repeated Partition Descriptors whose partition numbers are aligned to PART_DESC_ALLOC_STEP.
  • authThe attacker must have the ability to mount the crafted UDF image (typically requires local access or a mechanism to trigger kernel mount of a malicious block device).

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.