FAILED: patch "[PATCH] ima: fix out-of-bounds read in xattr_verify()" failed to apply to 5.10-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 5ff232d31106f45ac87c3b64e1d35a0667777797
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026081311-refutable-kiln-56fe@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 5ff232d31106f45ac87c3b64e1d35a0667777797 Mon Sep 17 00:00:00 2001
From: Lincoln Wallace <[email protected]>
Date: Mon, 3 Aug 2026 10:50:21 -0300
Subject: [PATCH] ima: fix out-of-bounds read in xattr_verify()
The digest-length check in xattr_verify() mixes int and size_t:
if (xattr_len - sizeof(xattr_value->type) - hash_start >= iint->ima_hash->length)
sizeof() yields size_t, so the usual arithmetic conversions promote the whole left-hand side to unsigned 64-bit before the subtraction runs. For a truncated xattr this underflows instead of going negative:
a 1-byte IMA_XATTR_DIGEST_NG xattr (xattr_len == 1, hash_start == 1) turns "1 - 1 - 1" into SIZE_MAX, which is trivially >= ima_hash->length. The check then passes and the following memcmp() reads iint->ima_hash->length bytes starting past the end of the buffer vfs_getxattr_alloc() allocated for it.
Nothing upstream clamps xattr_len back into a safe range first:ima_get_hash_algo() only special-cases xattr_len < 2 to pick a default algorithm, and evm_verifyxattr() returns INTEGRITY_UNKNOWN rather than failing when no HMAC key is loaded, so a truncated security.ima value reaches the length check as-is.
Rewrite the comparison so every operand stays a signed int and no implicit conversion to size_t can occur.
security/integrity/ima/ima_appraise.c +7 -2
@@ -274,8 +274,13 @@ static int xattr_verify(enum ima_hooks func, struct ima_iint_cache *iint, }else {set_bit (IMA_DIGSIG , &iint->atomic_flags); } -if (xattr_len -sizeof (xattr_value->type) - hash_start >= - iint->ima_hash->length) +/* +* Use addition, not subtraction: sizeof() forces unsigned +* math and a short xattr_len would wrap around, bypassing +* this bounds check. +*/ +if (xattr_len >= (int )sizeof (xattr_value->type) + hash_start + + (int )iint->ima_hash->length)/* * xattr length may be longer. md5 hash in previous * version occupied 20 bytes in xattr, instead of 16
PATCH 1/1 ima: fix out-of-bounds read in xattr_verify()
The digest-length check in xattr_verify() mixes int and size_t:
if (xattr_len - sizeof(xattr_value->type) - hash_start >= iint->ima_hash->length)
sizeof() yields size_t, so the usual arithmetic conversions promote the whole left-hand side to unsigned 64-bit before the subtraction runs. For a truncated xattr this underflows instead of going negative:
a 1-byte IMA_XATTR_DIGEST_NG xattr (xattr_len == 1, hash_start == 1) turns "1 - 1 - 1" into SIZE_MAX, which is trivially >= ima_hash->length. The check then passes and the following memcmp() reads iint->ima_hash->length bytes starting past the end of the buffer vfs_getxattr_alloc() allocated for it.
Nothing upstream clamps xattr_len back into a safe range first:ima_get_hash_algo() only special-cases xattr_len < 2 to pick a default algorithm, and evm_verifyxattr() returns INTEGRITY_UNKNOWN rather than failing when no HMAC key is loaded, so a truncated security.ima value reaches the length check as-is.
Rewrite the comparison so every operand stays a signed int and no implicit conversion to size_t can occur.
---
Context conflict only: the IMA_XATTR_DIGEST case was restructured after 5.10 by commit 7aa5783d9564 ("ima: Allow imasig requirement to be satisfied by EVM portable signatures"). The fix itself is identical to upstream.
security/integrity/ima/ima_appraise.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
security/integrity/ima/ima_appraise.c +7 -2
@@ -242,8 +242,13 @@ static int xattr_verify(enum ima_hooks func, struct integrity_iint_cache *iint,break ; }clear_bit (IMA_DIGSIG , &iint->atomic_flags); -if (xattr_len -sizeof (xattr_value->type) - hash_start >= - iint->ima_hash->length) +/* +* Use addition, not subtraction: sizeof() forces unsigned +* math and a short xattr_len would wrap around, bypassing +* this bounds check. +*/ +if (xattr_len >= (int )sizeof (xattr_value->type) + hash_start + + (int )iint->ima_hash->length)/* * xattr length may be longer. md5 hash in previous * version occupied 20 bytes in xattr, instead of 16
Signature · 1 line
2.53.0
Re: [PATCH 5.10.y] ima: fix out-of-bounds read in xattr_verify()
Quoted 8 lines
The digest-length check in
xattr_verify()mixes int andsize_t:if (xattr_len - sizeof(xattr_value->type) - hash_start >= iint->ima_hash->length)
sizeof()yieldssize_t, so the usual arithmetic conversions promote the whole left-hand side to unsigned 64-bit before the subtraction runs.
Queued for 5.10, thanks.
Signature · 2 lines
Thanks, Sasha