From: Akira Patafio <kokokoala4211@gmail.com>
To: Theodore Ts'o <tytso@mit.edu>
Cc: linux-ext4@vger.kernel.org
Subject: [PATCH] libblkid: avoid undefined shifts and an unaligned read in the probes
Date: Mon, 21 Sep 2026 12:29:45 -0400 [thread overview]
Message-ID: <20260921162945.32486-1-kokokoala4211@gmail.com> (raw)
Three sites in lib/blkid/probe.c operate on values taken straight from a
superblock, which on any system that probes removable media is
attacker-supplied.
probe_jfs() uses js_l2bsize and js_l2pbsize as shift exponents on a
32-bit 1U. Both are 16-bit on-disk fields, so any value of 32 or more
makes the shift undefined. No such value can describe a valid 32-bit
block size, so reject the superblock rather than shift by it.
exfat_next_cluster() casts the result of get_buffer() to uint32_t * and
dereferences it. get_buffer() returns a pointer into a byte buffer at an
offset computed from fat_block_start, so it carries no alignment
guarantee and the offset is under the volume's control; the dereference
is undefined when that offset is not 4-byte aligned. Copy the bytes out
with memcpy() instead, which the compiler turns back into a load where
unaligned access is permitted.
Neither has a memory-safety consequence: the shifts only produce a wrong
comparison, and get_buffer() already bounds-checks the read it returns.
This is a correctness and undefined-behaviour fix.
Found with libFuzzer and UBSan (clang 18, aarch64) over a corpus of
NTFS/exFAT/JFS superblocks. util-linux made equivalent changes to its
fork of this code in 585815c1f8f7 ("libblkid: exfat - avoid undefined
shift") and 9c82a8ca123a ("libblkid: ntfs: avoid UB in signed shift").
Signed-off-by: Akira Patafio <kokokoala4211@gmail.com>
---
lib/blkid/probe.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c
index 6a3bb24..689ee6d 100644
--- a/lib/blkid/probe.c
+++ b/lib/blkid/probe.c
@@ -854,13 +854,16 @@ static int probe_jfs(struct blkid_probe *probe,
{
struct jfs_super_block *js;
const char *label = 0;
+ uint16_t l2bsize, l2pbsize;
js = (struct jfs_super_block *)buf;
- if (blkid_le32(js->js_bsize) != (1U << blkid_le16(js->js_l2bsize)))
+ l2bsize = blkid_le16(js->js_l2bsize);
+ if (l2bsize >= 32 || blkid_le32(js->js_bsize) != (1U << l2bsize))
return 1;
- if (blkid_le32(js->js_pbsize) != (1U << blkid_le16(js->js_l2pbsize)))
+ l2pbsize = blkid_le16(js->js_l2pbsize);
+ if (l2pbsize >= 32 || blkid_le32(js->js_pbsize) != (1U << l2pbsize))
return 1;
if ((blkid_le16(js->js_l2bsize) - blkid_le16(js->js_l2pbsize)) !=
@@ -1461,14 +1464,19 @@ static uint32_t exfat_next_cluster(struct blkid_probe *probe,
const struct exfat_super_block *sb,
uint32_t cluster)
{
- uint32_t *next;
+ uint32_t next;
uint64_t offset;
+ unsigned char *buf;
offset = exfat_block_to_offset(sb, sb->fat_block_start)
+ (uint64_t) cluster * sizeof (cluster);
- next = (uint32_t *)get_buffer(probe, offset, sizeof (uint32_t));
+ buf = get_buffer(probe, offset, sizeof (uint32_t));
+ if (!buf)
+ return 0;
- return next ? *next : 0;
+ memcpy(&next, buf, sizeof(next));
+
+ return next;
}
static struct exfat_entry_label *find_exfat_entry_label(
--
2.50.1
reply other threads:[~2026-09-21 16:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260921162945.32486-1-kokokoala4211@gmail.com \
--to=kokokoala4211@gmail.com \
--cc=linux-ext4@vger.kernel.org \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox