]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
calendarspec: improve overflow handling
authorDouglas Christman <DouglasChristman@gmail.com>
Tue, 20 Dec 2016 21:42:12 +0000 (16:42 -0500)
committerDouglas Christman <DouglasChristman@gmail.com>
Tue, 20 Dec 2016 22:52:55 +0000 (17:52 -0500)
Check if the parsed seconds value fits in an integer *after*
multiplying by USEC_PER_SEC, otherwise a large value can trigger
modulo by zero during normalization.

src/basic/calendarspec.c
src/test/test-calendarspec.c

index 3e249505a5a57e3840f71357b5322c21481634c6..1b1acd3e0b92a29853c5cb35e47dd1eb55095d67 100644 (file)
@@ -20,6 +20,7 @@
 #include <alloca.h>
 #include <ctype.h>
 #include <errno.h>
+#include <limits.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -96,7 +97,7 @@ static void normalize_chain(CalendarComponent **c) {
                  * While we're counting the chain, also normalize `stop`
                  * so the length of the range is a multiple of `repeat`
                  */
-                if (i->stop > i->start)
+                if (i->stop > i->start && i->repeat > 0)
                         i->stop -= (i->stop - i->start) % i->repeat;
 
         }
@@ -487,7 +488,7 @@ static int parse_weekdays(const char **p, CalendarSpec *c) {
         }
 }
 
-static int parse_component_decimal(const char **p, bool usec, unsigned long *res) {
+static int parse_component_decimal(const char **p, bool usec, int *res) {
         unsigned long value;
         const char *e = NULL;
         char *ee = NULL;
@@ -502,8 +503,6 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res
                 return -errno;
         if (ee == *p)
                 return -EINVAL;
-        if ((unsigned long) (int) value != value)
-                return -ERANGE;
         e = ee;
 
         if (usec) {
@@ -530,6 +529,9 @@ static int parse_component_decimal(const char **p, bool usec, unsigned long *res
         }
 
 finish:
+        if (value > INT_MAX)
+                return -ERANGE;
+
         *p = e;
         *res = value;
 
@@ -556,9 +558,8 @@ static int const_chain(int value, CalendarComponent **c) {
 }
 
 static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
-        unsigned long start, stop = -1, repeat = 0;
+        int r, start, stop = -1, repeat = 0;
         CalendarComponent *cc;
-        int r;
         const char *e;
 
         assert(p);
index 5fd749a6a859ef92dc1adf01e070d68fd0c1df1e..1f34a91b100d5f2cb2095009df53317727b4c083 100644 (file)
@@ -238,6 +238,8 @@ int main(int argc, char* argv[]) {
         assert_se(calendar_spec_from_string("*:05..10/6", &c) < 0);
         assert_se(calendar_spec_from_string("20/4:00", &c) < 0);
         assert_se(calendar_spec_from_string("00:00/60", &c) < 0);
+        assert_se(calendar_spec_from_string("00:00:2300", &c) < 0);
+        assert_se(calendar_spec_from_string("00:00:18446744073709551615", &c) < 0);
 
         test_timestamp();
         test_hourly_bug_4031();