]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
timedated: rework clock change overflow check
authorLennart Poettering <lennart@poettering.net>
Tue, 18 Feb 2025 08:37:41 +0000 (09:37 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 18 Feb 2025 10:22:34 +0000 (11:22 +0100)
Let's use explicit language constructs to test for overflow, the
previous code was ultimately relying on undefined behaviour.

src/timedate/timedated.c

index b196034a2524a5f726248f9c89a743d83b521a5e..6ee49c5975e147204765b16e4f23436c8dccedf5 100644 (file)
@@ -877,16 +877,16 @@ static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *erro
                 return sd_bus_reply_method_return(m, NULL);
 
         if (relative) {
-                usec_t n, x;
-
-                n = now(CLOCK_REALTIME);
-                x = n + utc;
-
-                if ((utc > 0 && x < n) ||
-                    (utc < 0 && x > n))
+                usec_t n = now(CLOCK_REALTIME);
+                bool valid;
+                if (utc > 0)
+                        valid = INC_SAFE(&n, (usec_t) utc);
+                else
+                        valid = DEC_SAFE(&n, (usec_t) -utc);
+                if (!valid)
                         return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Time value overflow");
 
-                timespec_store(&ts, x);
+                timespec_store(&ts, n);
         } else
                 timespec_store(&ts, (usec_t) utc);
 
@@ -909,7 +909,7 @@ static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *erro
         if (r < 0 && r != -ENODATA)
                 return r;
 
-        timespec_store(&ts, timespec_load(&ts) + (now(CLOCK_MONOTONIC) - start));
+        timespec_store(&ts, timespec_load(&ts) + usec_sub_unsigned(now(CLOCK_MONOTONIC), start));
 
         /* Set system clock */
         if (clock_settime(CLOCK_REALTIME, &ts) < 0) {