diff options
| author | Karel Zak <kzak@redhat.com> | 2026-03-25 11:54:42 +0100 |
|---|---|---|
| committer | Karel Zak <kzak@redhat.com> | 2026-04-01 10:48:06 +0200 |
| commit | 699d086fa5f24651b375e5909c27e14a16ceb4b9 (patch) | |
| tree | 8e29c75943ce1ccccdee876ca36223469c4074d6 | |
| parent | e9d544d013267ea86b70ee8ff78abd280e6641af (diff) | |
| download | util-linux-master.tar.gz | |
The read_extended() function follows EBR chain links without checking
that the target offset falls within the master extended partition.
A malformed EBR link can point outside the extended area.
Add a bounds check before read_pte() to stop the chain walk when the
next EBR offset is outside [ext_start, ext_end]. This is self-defense
during parsing; it does not restrict what the user can create.
Signed-off-by: Karel Zak <kzak@redhat.com>
| -rw-r--r-- | libfdisk/src/dos.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index d1fb77315..99208c3eb 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -527,6 +527,7 @@ static void read_extended(struct fdisk_context *cxt, size_t ext) struct pte *pex, *pe; struct dos_partition *p, *q; struct fdisk_dos_label *l = self_label(cxt); + fdisk_sector_t ext_start, ext_end; if (fdisk_is_listonly(cxt) && !sysfs_devno_is_wholedisk(fdisk_get_devno(cxt))) { @@ -549,9 +550,14 @@ static void read_extended(struct fdisk_context *cxt, size_t ext) return; } + ext_start = get_abs_partition_start(pex); + ext_end = get_abs_partition_end(pex); + DBG(LABEL, ul_debug("DOS: Reading extended %zu", ext)); while (IS_EXTENDED (p->sys_ind)) { + fdisk_sector_t next; + if (cxt->label->nparts_max >= MAXIMUM_PARTS) { /* This is not a Linux restriction, but this program uses arrays of size MAXIMUM_PARTS. @@ -575,8 +581,17 @@ static void read_extended(struct fdisk_context *cxt, size_t ext) if (!pe) return; - if (read_pte(cxt, cxt->label->nparts_max, l->ext_offset + - dos_partition_get_start(p))) + next = l->ext_offset + dos_partition_get_start(p); + if (next < ext_start || next > ext_end) { + DBG(LABEL, ul_debug("DOS: EBR link %ju outside " + "extended partition <%ju-%ju> -- stop", + (uintmax_t) next, + (uintmax_t) ext_start, + (uintmax_t) ext_end)); + break; + } + + if (read_pte(cxt, cxt->label->nparts_max, next)) return; if (!l->ext_offset) |
