From e1f150d41516c192e3b78f360a7fb2dd9879abda Mon Sep 17 00:00:00 2001 From: SJ Park Date: Fri, 10 Jul 2026 06:46:36 -0700 Subject: mm/damon/core: use abs_diff() instead of abs() Use of abs() in damon_merge_regions_of() could cause a silent integer overflow since the macro casts unsigned int to signed int. It is unlikely to have such a large value for nr_accesses. Even though it happens, the user impact is just degraded monitoring results. Users showing bad monitoring results for weird setup is quite trivial. But the code is obviously wrong. Use abs_diff() instead. The issue was discovered [1] by Sashiko. Link: https://lore.kernel.org/20260710134651.18084-8-sj@kernel.org Link: https://lore.kernel.org/20260705213817.100841-1-sj@kernel.org/ [1] Signed-off-by: SJ Park Cc: David Hildenbrand Cc: Jonathan Corbet Cc: Liam R. Howlett Cc: Lorenzo Stoakes Cc: Michal Hocko Cc: Mike Rapoport Cc: Suren Baghdasaryan Cc: Vlastimil Babka Signed-off-by: Andrew Morton --- mm/damon/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index fea97399b575..4c7e8a12a9b6 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -3261,7 +3261,7 @@ static void damon_merge_regions_of(struct damon_target *t, unsigned int thres, struct damon_region *r, *prev = NULL, *next; damon_for_each_region_safe(r, next, t) { - if (abs(r->nr_accesses - r->last_nr_accesses) > thres) + if (abs_diff(r->nr_accesses, r->last_nr_accesses) > thres) r->age = 0; else if ((r->nr_accesses == 0) != (r->last_nr_accesses == 0)) r->age = 0; @@ -3269,7 +3269,7 @@ static void damon_merge_regions_of(struct damon_target *t, unsigned int thres, r->age++; if (prev && prev->ar.end == r->ar.start && - abs(prev->nr_accesses - r->nr_accesses) <= thres && + abs_diff(prev->nr_accesses, r->nr_accesses) <= thres && damon_sz_region(prev) + damon_sz_region(r) <= sz_limit) damon_merge_two_regions(t, prev, r); else -- cgit v1.2.3