summaryrefslogtreecommitdiffstats
path: root/src/basic
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-02-17 14:34:01 +0100
committerLennart Poettering <lennart@poettering.net>2021-02-18 22:36:34 +0100
commit75b86b564ab89d146eeed8e7df6fdbcc363a8150 (patch)
tree13861a8824db43dc6e1d7ce768adfbd537207ade /src/basic
parentupdate TODO (diff)
downloadsystemd-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.c27
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;
}