Bug 2554511 - CVE-2026-89088 parted: parted: Denial of Service via heap buffer overflow during FAT16 resize [fedora-all]
Summary: CVE-2026-89088 parted: parted: Denial of Service via heap buffer overflow dur...
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: parted
Version: rawhide
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: ---
Assignee: Brian Lane
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard: {"flaws": ["5aada33a-4283-4940-a810-8...
Depends On:
Blocks: CVE-2026-89088
TreeView+ depends on / blocked
 
Reported: 2026-10-16 22:43 UTC by Marco Benatto
Modified: 2026-10-19 17:47 UTC (History)
1 user (show)

Fixed In Version: parted-3.7.13-1
Clone Of:
Environment:
Last Closed: 2026-10-19 17:47:24 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Marco Benatto 2026-10-16 22:43:01 UTC
Disclaimer: Community trackers are created by Red Hat Product Security team on a best effort basis. Package maintainers are required to ascertain if the flaw indeed affects their package, before starting the update process.

AI_ONLY_REPORT
package: parted-3.6-7.el10
------
Summary: Heap Buffer Overflow in duplicate_legacy_root_dir via Malformed  
BPB: a crafted FAT16 BPB `dir_entries` value can drive an oversized read  
into libparted's fixed heap buffer during a resize that remains on the  
FAT16 path.
Requirements to exploit: Control over a FAT16 filesystem image or block  
device carrying a malicious BPB `dir_entries` value, plus a user or  
administrative tool that uses libparted from this SRPM to open and resize  
that image while remaining on the FAT16 to FAT16 path.
Component affected: `parted` SRPM, libparted FAT resize logic in  
`libparted/fs/r/fat/bootsector.c` and `libparted/fs/r/fat/resize.c`,  
specifically `duplicate_legacy_root_dir`
Version affected: `parted-3.6-7.el10`
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Not notified.
CVSS: CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H - 5.5 (MEDIUM)
AV:L - The attacker must supply a local crafted filesystem image or  
block device to software using libparted.
AC:L - The overflow follows from a malformed BPB `dir_entries` value  
without additional race conditions or hard-to-meet preconditions.
PR:N - No privileges are needed to create or provide the crafted image  
itself.
UI:R - A user or administrative workflow must open the image and trigger  
a resize operation.
S:U - The impact is confined to the component performing the resize.
C:N - The available evidence does not show disclosure of data.
I:N - The available evidence does not show controlled modification of  
data or state.
A:H - The demonstrated outcome is a heap overflow leading to a reliable  
crash or denial of service during resize.
Impact: Moderate. This issue does not fit Critical or Important because the  
available evidence supports only a local, user-assisted attack path and  
does not establish straightforward confidentiality or integrity compromise.  
It fits Moderate because a malformed filesystem image can still trigger a  
meaningful availability failure in a supported FAT resize code path under  
realistic administrative use.
Embargo: no
Reason: The currently supported impact is denial of service in a local  
resize workflow, exploitation requires attacker-controlled FAT16 media plus  
a resize action, and practical mitigation exists by avoiding resize of  
untrusted FAT16 images until bounds checks are added.
Acknowledgement: Aisle Research
Vulnerability Details: libparted allocates a fixed FAT buffer of 1024  
sectors and later derives `root_dir_sector_count` for FAT16 directly from  
the untrusted BPB `dir_entries` field. That derived sector count is then  
used as the read length in `duplicate_legacy_root_dir` without a  
corresponding check that it fits inside the fixed heap buffer.
```c
// libparted/fs/r/fat/fat.h
#define BUFFER_SIZE  1024
```
```c
// libparted/fs/r/fat/fat.c
fs_info->buffer_sectors = BUFFER_SIZE;
fs_info->buffer = ped_malloc (fs_info->buffer_sectors * 512);
```
```c
// libparted/fs/r/fat/bootsector.c
fs_info->root_dir_entry_count = PED_LE16_TO_CPU (bs->dir_entries);
fs_info->root_dir_sector_count
= fs_info->root_dir_entry_count * sizeof (FatDirEntry)
/ (512 * fs_info->logical_sector_size);
```
```c
// libparted/fs/r/fat/resize.c
if (!ped_geometry_read (ctx->old_fs->geom, old_fs_info->buffer,
old_fs_info->root_dir_offset,
old_fs_info->root_dir_sector_count))
return 0;
```
The available evidence shows that `ped_geometry_read()` enforces geometry  
bounds, but not destination-buffer size. For a crafted FAT16 image with  
`dir_entries=0xFFFF` and 512-byte logical sectors  
(`logical_sector_size=1`), `root_dir_sector_count` becomes 4095 sectors  
while the destination buffer holds only 1024 sectors. That creates an  
attempted overwrite of 3071 sectors, approximately 1.5 MiB, past the heap  
allocation. The demonstrated impact is a reliable crash during resize;  
broader confidentiality or integrity impact is not established from the  
current evidence.
Steps to reproduce:
1. Build the package with AddressSanitizer enabled.
2. Create a FAT16 image and patch the BPB `dir_entries` field:
```bash
dd if=/dev/zero of=fat16.img bs=1M count=64
mkfs.fat -F 16 fat16.img
printf '\xff\xff' | dd of=fat16.img bs=1 seek=$((0x11)) conv=notrunc
sudo losetup --find --show fat16.img   # e.g. /dev/loop0
```
3. Run a minimal libparted harness that opens the filesystem and performs  
resize (`ped_file_system_open` then `ped_file_system_resize`) while keeping  
the target type FAT16.
4. Observe an AddressSanitizer `heap-buffer-overflow` in  
`duplicate_legacy_root_dir` during `ped_geometry_read(...)`.
Mitigation: Avoid resizing untrusted FAT16 images or block devices with  
libparted until a bounds check is added. Where such media must be handled,  
reject BPB `dir_entries` values that would make `root_dir_sector_count`  
exceed the internal buffer before invoking the resize path.
Proposed Fix: Add an explicit bounds check in `duplicate_legacy_root_dir`  
before the read and write operations so the resize fails cleanly when the  
legacy root directory would exceed the internal buffer. As an additional  
hardening step, oversized `dir_entries` values can also be rejected earlier  
in `fat_boot_sector_analyse()`.
```diff
diff --git a/libparted/fs/r/fat/resize.c b/libparted/fs/r/fat/resize.c
@@ -86,6 +86,16 @@ duplicate_legacy_root_dir (FatOpContext* ctx)
PED_ASSERT (old_fs_info->root_dir_sector_count
== new_fs_info->root_dir_sector_count);
+	if (old_fs_info->root_dir_sector_count > old_fs_info->buffer_sectors
+	    || new_fs_info->root_dir_sector_count > old_fs_info->buffer_sectors) {
+		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+			_("Legacy FAT root directory is too large for internal "
+			  "buffer (%lld sectors > %lld)."),
+			(long long) old_fs_info->root_dir_sector_count,
+			(long long) old_fs_info->buffer_sectors);
+		return 0;
+	}
+
if (!ped_geometry_read (ctx->old_fs->geom, old_fs_info->buffer,
old_fs_info->root_dir_offset,
old_fs_info->root_dir_sector_count))
```
------
This report was generated using AI technology. Always review AI-generated  
content prior to use


Note You need to log in before you can comment on or make changes to this bug.