Merge pull request #10493 from yuwata/parse-time-overflow

util: check overflow in parse_time() and parse_nsec()
This commit is contained in:
Lennart Poettering 2018-10-23 19:30:49 +02:00 committed by GitHub
commit 5d83b9f47b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 4 deletions

View file

@ -41,7 +41,7 @@ _systemd_analyze() {
)
local -A VERBS=(
[STANDALONE]='time blame plot dump unit-paths calendar'
[STANDALONE]='time blame plot dump unit-paths calendar timespan'
[CRITICAL_CHAIN]='critical-chain'
[DOT]='dot'
[LOG_LEVEL]='log-level'

View file

@ -1048,12 +1048,21 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
something = true;
k = ((usec_t) -1) / multiplier;
if ((usec_t) l + 1 >= k || (usec_t) z >= k)
return -ERANGE;
k = (usec_t) z * multiplier;
for (; n > 0; n--)
k /= 10;
r += (usec_t) l * multiplier + k;
k += (usec_t) l * multiplier;
if (k >= ((usec_t) -1) - r)
return -ERANGE;
r += k;
}
*usec = r;
@ -1185,12 +1194,22 @@ int parse_nsec(const char *t, nsec_t *nsec) {
for (i = 0; i < ELEMENTSOF(table); i++)
if (startswith(e, table[i].suffix)) {
nsec_t k = (nsec_t) z * table[i].nsec;
nsec_t k;
k = ((nsec_t) -1) / table[i].nsec;
if ((nsec_t) l + 1 >= k || (nsec_t) z >= k)
return -ERANGE;
k = (nsec_t) z * table[i].nsec;
for (; n > 0; n--)
k /= 10;
r += (nsec_t) l * table[i].nsec + k;
k += (nsec_t) l * table[i].nsec;
if (k >= ((nsec_t) -1) - r)
return -ERANGE;
r += k;
p = e + strlen(table[i].suffix);
something = true;

View file

@ -94,6 +94,9 @@ static void test_parse_time(void) {
assert_se(parse_time("5s", &u, USEC_PER_MSEC) >= 0);
assert_se(u == 5 * USEC_PER_SEC);
assert_se(parse_time("11111111111111y", &u, 1) == -ERANGE);
assert_se(parse_time("1.1111111111111y", &u, 1) == -ERANGE);
}
static void test_parse_nsec(void) {
@ -144,6 +147,8 @@ static void test_parse_nsec(void) {
assert_se(parse_nsec("3.+1s", &u) < 0);
assert_se(parse_nsec("3. 1s", &u) < 0);
assert_se(parse_nsec("3.s", &u) < 0);
assert_se(parse_nsec("1111111111111y", &u) == -ERANGE);
assert_se(parse_nsec("1.111111111111y", &u) == -ERANGE);
}
static void test_format_timespan_one(usec_t x, usec_t accuracy) {