diff options
| author | SJ Park <sj@kernel.org> | 2026-07-10 06:46:39 -0700 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2026-08-04 19:18:51 -0700 |
| commit | 23c0623f802bf5bda6523d57ee8716711d1ecf29 (patch) | |
| tree | ea2c13bcedea8ca4f824e374ceaab600c1a0ae41 | |
| parent | 93508425db111473a6ce734d1918b0cb5ea823d9 (diff) | |
| download | linux-23c0623f802bf5bda6523d57ee8716711d1ecf29.tar.gz linux-23c0623f802bf5bda6523d57ee8716711d1ecf29.zip | |
mm/damon/core: validate params for probe hits weighted sum overflow
damon_probe_hits_wsum() could overflow in weird setups. Users could set
the weight unreasonably high. They could also set the aggregation
interval unreasonably high compared to the sampling interval. Such user
setup is unlikely. Even if such setup is used, damon_has_probe_weights()
always returns false, so the overflow cannot happen. The function may be
completed in future, though. Even if the overflow happens, the
consequence is degraded monitoring results for the unreasonable setup. It
is just a trivial user experience issue.
It is still better to be prevented unless the cost is expensive. Avoid
the overflow by adding the parameter validation in the core layer
parameters validation function.
Link: https://lore.kernel.org/20260710134651.18084-11-sj@kernel.org
Signed-off-by: SJ Park <sj@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
| -rw-r--r-- | mm/damon/core.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/mm/damon/core.c b/mm/damon/core.c index 4f1425e56950..a0e6a5129fbf 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -1335,6 +1335,9 @@ static void damos_set_filters_default_reject(struct damos *s) static bool damon_valid_probe_params(struct damon_ctx *ctx) { unsigned long sample_interval; + unsigned char max_probe_hits; + struct damon_probe *probe; + unsigned int wsum, wsum_to_add; if (!damon_has_probe_weights(ctx)) return true; @@ -1342,6 +1345,18 @@ static bool damon_valid_probe_params(struct damon_ctx *ctx) sample_interval = ctx->attrs.sample_interval ? : 1; if (ctx->attrs.aggr_interval / sample_interval > U8_MAX) return false; + + /* invalid if probe hits weighted sum can overflow */ + max_probe_hits = damon_nr_samples_per_aggr(&ctx->attrs); + wsum = 0; + damon_for_each_probe(probe, ctx) { + if (probe->weight > UINT_MAX / max_probe_hits) + return false; + wsum_to_add = probe->weight * max_probe_hits; + if (UINT_MAX - wsum < wsum_to_add) + return false; + wsum += wsum_to_add; + } return true; } |
