chiark / gitweb /
timedated: extra overflow safety check when doing relative time changes
authorLennart Poettering <lennart@poettering.net>
Fri, 22 Mar 2013 20:35:53 +0000 (21:35 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 22 Mar 2013 20:38:49 +0000 (21:38 +0100)
Ensure clients don't overflow usec_t when doing relative time changes.
This is mostly just paranoia and protection against accidents, after all
clients are already authenticated, and they can se the time to any
value they wish anyway, but better be safe than sorry.

https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1152187/comments/14

src/timedate/timedated.c

index 85506f4fc67d57f599030bb31592ac0c222ea9f7..16fffd08440cade294b4d9681c7fd568f5df44fe 100644 (file)
@@ -816,15 +816,24 @@ static DBusHandlerResult timedate_message_handler(
                         struct timespec ts;
                         struct tm* tm;
 
+                        if (relative) {
+                                usec_t n, x;
+
+                                n = now(CLOCK_REALTIME);
+                                x = n + utc;
+
+                                if ((utc > 0 && x < n) ||
+                                    (utc < 0 && x > n))
+                                        return bus_send_error_reply(connection, message, NULL, -EOVERFLOW);
+
+                                timespec_store(&ts, x);
+                        } else
+                                timespec_store(&ts, (usec_t) utc);
+
                         r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-time", interactive, NULL, &error);
                         if (r < 0)
                                 return bus_send_error_reply(connection, message, &error, r);
 
-                        if (relative)
-                                timespec_store(&ts, now(CLOCK_REALTIME) + utc);
-                        else
-                                timespec_store(&ts, utc);
-
                         /* Set system clock */
                         if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
                                 log_error("Failed to set local time: %m");