mirror of
https://git.yoctoproject.org/poky
synced 2026-10-23 19:38:18 +00:00
util-linux: fix CVE-2026-13595
This patch applies the upstream stable/v2.41 backport for CVE-2026-13595. The upstream fix merge or commit is referenced in [1], and the public CVE advisory is referenced in [2]. The individual backported commit links are recorded in the embedded patch headers when the fix expands to multiple commits. [1] https://github.com/util-linux/util-linux/commit/132d9c8aa15a8efd0a23d8ca7ed8b98f365e84fa [2] https://access.redhat.com/security/cve/CVE-2026-13595 (From OE-Core rev: 9f4a0789961def89303e6e8a211c944e41c29cab) Signed-off-by: Deepak Rathore <deeratho@cisco.com> Signed-off-by: Yoann Congal <yoann.congal@smile.fr> Signed-off-by: Paul Barker <paul@pbarker.dev>
This commit is contained in:
1 parent
865d0fd2d6
commit
fca50b3652
2 files changed
+158
No files matched your search
@@ -47,6 +47,7 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/utils/util-linux/v${MAJOR_VERSION}/util-lin
|
||||
file://CVE-2025-14104-01.patch \
|
||||
file://CVE-2025-14104-02.patch \
|
||||
file://CVE-2026-27456.patch \
|
||||
file://CVE-2026-13595.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "7b6605e48d1a49f43cc4b4cfc59f313d0dd5402fa40b96810bd572e167dfed0f"
|
||||
@@ -0,0 +1,157 @@
|
||||
From faf717ca4ed3b603eb213915fe15c6804c4b92d4 Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Thu, 7 May 2026 12:50:48 +0200
|
||||
Subject: [PATCH] libblkid: fix use-after-free in nested partition probing
|
||||
|
||||
The partitions list stores partitions in a contiguous array grown by
|
||||
realloc(). When the array is reallocated to a new address, all
|
||||
existing blkid_partition pointers (tab->parent, ls->next_parent, local
|
||||
parent variables in nested probers) become dangling.
|
||||
|
||||
Fix this by changing the storage from an array of structs to an array
|
||||
of pointers, where each partition is individually allocated via
|
||||
calloc(). This makes all blkid_partition pointers stable across
|
||||
reallocations -- only the pointer array itself may move, which is
|
||||
harmless since no code caches pointers into the pointer array.
|
||||
|
||||
This eliminates the need for callers to re-fetch parent pointers after
|
||||
every blkid_partlist_add_partition() call.
|
||||
|
||||
CVE: CVE-2026-13595
|
||||
Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/132d9c8aa15a8efd0a23d8ca7ed8b98f365e84fa]
|
||||
|
||||
Backport Changes:
|
||||
- Scarthgap util-linux 2.39.3 still uses realloc() at this allocation site,
|
||||
so this backport keeps realloc() and changes only the element size to
|
||||
sizeof(*ls->parts) instead of adopting upstream's reallocarray() style.
|
||||
- The commit text was adjusted from reallocarray() to realloc() to match the
|
||||
target source context.
|
||||
|
||||
Reported-by: Thai Duong <thaidn@gmail.com>
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
(cherry picked from commit c0186f14fbdb02f64c8e0ba701ce727ea764ff4c)
|
||||
(cherry picked from commit 132d9c8aa15a8efd0a23d8ca7ed8b98f365e84fa)
|
||||
Signed-off-by: Deepak Rathore <deeratho@cisco.com>
|
||||
---
|
||||
libblkid/src/partitions/partitions.c | 36 ++++++++++++++++++----------
|
||||
1 file changed, 22 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/libblkid/src/partitions/partitions.c b/libblkid/src/partitions/partitions.c
|
||||
index 8ebf480f5..6089028a8 100644
|
||||
--- a/libblkid/src/partitions/partitions.c
|
||||
+++ b/libblkid/src/partitions/partitions.c
|
||||
@@ -197,7 +197,7 @@ struct blkid_struct_partlist {
|
||||
|
||||
int nparts; /* number of partitions */
|
||||
int nparts_max; /* max.number of partitions */
|
||||
- blkid_partition parts; /* array of partitions */
|
||||
+ blkid_partition *parts; /* array of pointers to partitions */
|
||||
|
||||
struct list_head l_tabs; /* list of partition tables */
|
||||
};
|
||||
@@ -356,13 +356,16 @@ static void reset_partlist(blkid_partlist ls)
|
||||
free_parttables(ls);
|
||||
|
||||
if (ls->next_partno) {
|
||||
- /* already initialized - reset */
|
||||
- int tmp_nparts = ls->nparts_max;
|
||||
- blkid_partition tmp_parts = ls->parts;
|
||||
+ /* already initialized - free individually allocated partitions */
|
||||
+ int i, tmp_nparts_max = ls->nparts_max;
|
||||
+ blkid_partition *tmp_parts = ls->parts;
|
||||
+
|
||||
+ for (i = 0; i < ls->nparts; i++)
|
||||
+ free(ls->parts[i]);
|
||||
|
||||
memset(ls, 0, sizeof(struct blkid_struct_partlist));
|
||||
|
||||
- ls->nparts_max = tmp_nparts;
|
||||
+ ls->nparts_max = tmp_nparts_max;
|
||||
ls->parts = tmp_parts;
|
||||
}
|
||||
|
||||
@@ -397,6 +400,7 @@ static void partitions_free_data(blkid_probe pr __attribute__((__unused__)),
|
||||
void *data)
|
||||
{
|
||||
blkid_partlist ls = (blkid_partlist) data;
|
||||
+ int i;
|
||||
|
||||
if (!ls)
|
||||
return;
|
||||
@@ -404,6 +408,8 @@ static void partitions_free_data(blkid_probe pr __attribute__((__unused__)),
|
||||
free_parttables(ls);
|
||||
|
||||
/* deallocate partitions and partlist */
|
||||
+ for (i = 0; i < ls->nparts; i++)
|
||||
+ free(ls->parts[i]);
|
||||
free(ls->parts);
|
||||
free(ls);
|
||||
}
|
||||
@@ -436,16 +442,18 @@ static blkid_partition new_partition(blkid_partlist ls, blkid_parttable tab)
|
||||
/* Linux kernel has DISK_MAX_PARTS=256, but it's too much for
|
||||
* generic Linux machine -- let start with 32 partitions.
|
||||
*/
|
||||
- void *tmp = realloc(ls->parts, (ls->nparts_max + 32) *
|
||||
- sizeof(struct blkid_struct_partition));
|
||||
+ void *tmp = realloc(ls->parts, (ls->nparts_max + 32) *
|
||||
+ sizeof(*ls->parts));
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
ls->parts = tmp;
|
||||
ls->nparts_max += 32;
|
||||
}
|
||||
|
||||
- par = &ls->parts[ls->nparts++];
|
||||
- memset(par, 0, sizeof(struct blkid_struct_partition));
|
||||
+ par = calloc(1, sizeof(struct blkid_struct_partition));
|
||||
+ if (!par)
|
||||
+ return NULL;
|
||||
+ ls->parts[ls->nparts++] = par;
|
||||
|
||||
ref_parttable(tab);
|
||||
par->tab = tab;
|
||||
@@ -849,7 +857,7 @@ int blkid_probe_is_covered_by_pt(blkid_probe pr,
|
||||
|
||||
/* check if the partition table fits into the device */
|
||||
for (i = 0; i < nparts; i++) {
|
||||
- blkid_partition par = &ls->parts[i];
|
||||
+ blkid_partition par = ls->parts[i];
|
||||
|
||||
if (par->start + par->size > (pr->size >> 9)) {
|
||||
DBG(LOWPROBE, ul_debug("partition #%d overflows "
|
||||
@@ -861,7 +869,7 @@ int blkid_probe_is_covered_by_pt(blkid_probe pr,
|
||||
|
||||
/* check if the requested area is covered by PT */
|
||||
for (i = 0; i < nparts; i++) {
|
||||
- blkid_partition par = &ls->parts[i];
|
||||
+ blkid_partition par = ls->parts[i];
|
||||
|
||||
if (start >= par->start && end <= par->start + par->size) {
|
||||
rc = 1;
|
||||
@@ -960,7 +968,7 @@ blkid_partition blkid_partlist_get_partition(blkid_partlist ls, int n)
|
||||
if (n < 0 || n >= ls->nparts)
|
||||
return NULL;
|
||||
|
||||
- return &ls->parts[n];
|
||||
+ return ls->parts[n];
|
||||
}
|
||||
|
||||
blkid_partition blkid_partlist_get_partition_by_start(blkid_partlist ls, uint64_t start)
|
||||
@@ -1072,7 +1080,7 @@ blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno
|
||||
* and an entry in partition table.
|
||||
*/
|
||||
for (i = 0; i < ls->nparts; i++) {
|
||||
- blkid_partition par = &ls->parts[i];
|
||||
+ blkid_partition par = ls->parts[i];
|
||||
|
||||
if (partno != blkid_partition_get_partno(par))
|
||||
continue;
|
||||
@@ -1088,7 +1096,7 @@ blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno
|
||||
DBG(LOWPROBE, ul_debug("searching by offset/size"));
|
||||
|
||||
for (i = 0; i < ls->nparts; i++) {
|
||||
- blkid_partition par = &ls->parts[i];
|
||||
+ blkid_partition par = ls->parts[i];
|
||||
|
||||
if ((uint64_t)blkid_partition_get_start(par) == start &&
|
||||
(uint64_t)blkid_partition_get_size(par) == size)
|
||||
Reference in new issue
Block a user