diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-02-17 14:34:01 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-02-18 22:36:34 +0100 |
commit | 75b86b564ab89d146eeed8e7df6fdbcc363a8150 (patch) | |
tree | 13861a8824db43dc6e1d7ce768adfbd537207ade /src/basic | |
parent | update TODO (diff) | |
download | systemd-75b86b564ab89d146eeed8e7df6fdbcc363a8150.tar.xz systemd-75b86b564ab89d146eeed8e7df6fdbcc363a8150.zip |
limits-util: tweak overflow checks for (physical_memory|system_tasks)_max_scale()
Also, shortcut two special cases for passing through values as-is, so
that we are not needlessly subjected to overflow issues for them.
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/limits-util.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/basic/limits-util.c b/src/basic/limits-util.c index 259c311a67..9f8e26d46a 100644 --- a/src/basic/limits-util.c +++ b/src/basic/limits-util.c @@ -77,7 +77,13 @@ uint64_t physical_memory(void) { } uint64_t physical_memory_scale(uint64_t v, uint64_t max) { - uint64_t p, m, ps, r; + uint64_t p, m, ps; + + /* Shortcut two special cases */ + if (v == 0) + return 0; + if (v == max) + return physical_memory(); assert(max > 0); @@ -90,17 +96,16 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) { p = physical_memory() / ps; assert(p > 0); - m = p * v; - if (m / p != v) + if (v > UINT64_MAX / p) return UINT64_MAX; + m = p * v; m /= max; - r = m * ps; - if (r / ps != m) + if (m > UINT64_MAX / ps) return UINT64_MAX; - return r; + return m * ps; } uint64_t system_tasks_max(void) { @@ -138,6 +143,12 @@ uint64_t system_tasks_max(void) { uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) { uint64_t t, m; + /* Shortcut two special cases */ + if (v == 0) + return 0; + if (v == max) + return system_tasks_max(); + assert(max > 0); /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages @@ -146,9 +157,9 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) { t = system_tasks_max(); assert(t > 0); - m = t * v; - if (m / t != v) /* overflow? */ + if (v > UINT64_MAX / t) /* overflow? */ return UINT64_MAX; + m = t * v; return m / max; } |