On Wed, Jun 10, 2026 at 7:51 AM Ming Hung Tsai <[email protected]> wrote: > > On Tue, Jun 9, 2026 at 8:26 AM Samuel Moelius > <[email protected]> wrote: > > > > 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 > > > > > > This patch is a half-measure. sscanf() silently wraps on overflow, so > values beyond U64_MAX still get wrapped to a u64 value, bypass the > range check, and invalidate a different block than specified. > > Also, in the single-value path, the b == U32_MAX check is redundant. > With the original end calculation, end wraps to 0 via uint32_t > overflow, and validate_cblock_range() already rejects it since begin > >= end. Neither the extra check nor the new end calculation is needed > here. > > To properly fix truncation, a rework using kstrtoull() is needed.
I am getting ready to travel and I will address this when I return in about two weeks. Thank you for understanding.
