CVE-2026-46094
Description
In the Linux kernel, the following vulnerability has been resolved:
ext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
The bounds check for the next xattr entry in check_xattrs() uses (void *)next >= end, which allows next to point within sizeof(u32) bytes of end. On the next loop iteration, IS_LAST_ENTRY() reads 4 bytes via *(__u32 *)(entry), which can overrun the valid xattr region.
For example, if next lands at end - 1, the check passes since next < end, but IS_LAST_ENTRY() reads 4 bytes starting at end - 1, accessing 3 bytes beyond the valid region.
Fix this by changing the check to (void *)next + sizeof(u32) > end, ensuring there is always enough space for the IS_LAST_ENTRY() read on the subsequent iteration.
Affected products
1Patches
10ab6da97bc310ext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index bb4b7f2802677b..c6b14a8fe0d7a5 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
5a5314d23876ext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index d62fec12600a05..2c90217d193647 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
520986722dbfext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 7bf9ba19a89db2..c6205b405efe43 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
eceafc31ea7bext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 7bf9ba19a89db2..c6205b405efe43 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
537e06597702ext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 4ed8ddf2a60b31..6ecdcb389e1b02 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
eceafc31ea7bext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 7bf9ba19a89db2..c6205b405efe43 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
520986722dbfext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 7bf9ba19a89db2..c6205b405efe43 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
537e06597702ext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 4ed8ddf2a60b31..6ecdcb389e1b02 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
5a5314d23876ext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index d62fec12600a05..2c90217d193647 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
ab6da97bc310ext4: fix bounds check in check_xattrs() to prevent out-of-bounds access
1 file changed · +1 −2
fs/ext4/xattr.c+1 −2 modifieddiff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index bb4b7f2802677b..c6b14a8fe0d7a5 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -226,7 +226,7 @@ check_xattrs(struct inode *inode, struct buffer_head *bh, /* Find the end of the names list */ while (!IS_LAST_ENTRY(e)) { struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(e); - if ((void *)next >= end) { + if ((void *)next + sizeof(u32) > end) { err_str = "e_name out of bounds"; goto errout; } -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Insufficient bounds check in check_xattrs() allows the loop to advance to a position where the subsequent IS_LAST_ENTRY() read of 4 bytes can extend beyond the valid xattr region."
Attack vector
An attacker who can mount a crafted ext4 filesystem (or otherwise supply a malicious extended-attribute block) can trigger the bug. The function check_xattrs() in fs/ext4/xattr.c iterates over xattr entries using a while loop. The original check `(void *)next >= end` only rejects pointers that are at or past the end boundary, so if `next` points to `end - 1`, `end - 2`, or `end - 3`, the check passes. On the next iteration, IS_LAST_ENTRY() dereferences 4 bytes via `*(__u32 *)(entry)`, reading up to 3 bytes beyond the valid buffer [patch_id=2659757].
Affected code
The vulnerable function is check_xattrs() in fs/ext4/xattr.c. The defective bounds check is on the line `if ((void *)next >= end)` inside the while loop that iterates over xattr entries [patch_id=2659757].
What the fix does
The patch changes the bounds check from `(void *)next >= end` to `(void *)next + sizeof(u32) > end` in the single affected line of fs/ext4/xattr.c [patch_id=2659757]. This ensures that before the loop advances to the next entry, there is guaranteed room for the 4-byte IS_LAST_ENTRY() read that will occur on the subsequent iteration. If `next` is within `sizeof(u32)` bytes of `end`, the new check correctly rejects the entry as out of bounds, preventing the out-of-bounds access.
Preconditions
- inputAttacker must be able to mount or access a crafted ext4 filesystem with a malicious extended-attribute block.
- inputThe crafted xattr block must contain entries arranged so that EXT4_XATTR_NEXT(e) points within sizeof(u32) bytes of the end boundary.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/520986722dbf869c122252123fc161c7302eab7dnvd
- git.kernel.org/stable/c/537e065977022aa22f2c2503e8accaf16622e0fdnvd
- git.kernel.org/stable/c/5a5314d2387633a272a04d1bd8727f99058e4e68nvd
- git.kernel.org/stable/c/ab6da97bc310db35d4e4ef5354bc3ff626b0698cnvd
- git.kernel.org/stable/c/eceafc31ea7b42c984ece10d79d505c0bb6615d5nvd
News mentions
0No linked articles in our index yet.