[PATCH] dm cache: reject oversized invalidate_cblocks values

Samuel Moelius <[email protected]>
Newsgroups dev.linux.lists.dm-devel,org.kernel.vger.linux-kernel
Message-ID <20260609001636.1235504.7288d2831f6d.dm-cache-invalidate-cblock-truncation@trailofbits.com>
invalidate_cblocks parses the cache block number into an unsigned long
long, but then stores it in a narrower cblock_t.  Values that do not fit
in the target type are silently truncated before the cache block is
invalidated.

That can make a request for one cache block invalidate a different
block.  It also makes the userspace-visible control file accept input
that cannot be represented by the mapping it is about to update.

Reject cache block numbers that do not round-trip through cblock_t
before using them.

Assisted-by: Codex:gpt-5.5-cyber-preview
Signed-off-by: Samuel Moelius <[email protected]>
---
 drivers/md/dm-cache-target.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index 097315a9bf0f..5f1a019a9a8d 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -3330,6 +3330,9 @@ static int parse_cblock_range(struct cache *cache, const char *str,
 	r = sscanf(str, "%llu-%llu%c", &b, &e, &dummy);
 
 	if (r == 2) {
+		if (b > U32_MAX || e > U32_MAX)
+			return -EINVAL;
+
 		result->begin = to_cblock(b);
 		result->end = to_cblock(e);
 		return 0;
@@ -3341,8 +3344,11 @@ static int parse_cblock_range(struct cache *cache, const char *str,
 	r = sscanf(str, "%llu%c", &b, &dummy);
 
 	if (r == 1) {
+		if (b > U32_MAX || b == U32_MAX)
+			return -EINVAL;
+
 		result->begin = to_cblock(b);
-		result->end = to_cblock(from_cblock(result->begin) + 1u);
+		result->end = to_cblock(b + 1);
 		return 0;
 	}
 
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.