Check GETTY_SPACING against the monotonic clock.
authorcheloha <cheloha@openbsd.org>
Wed, 31 Jan 2018 15:57:44 +0000 (15:57 +0000)
committercheloha <cheloha@openbsd.org>
Wed, 31 Jan 2018 15:57:44 +0000 (15:57 +0000)
Ensures that we can use the check if the system clock is set backwards.

While here, move time retrieval into the child process in start_getty(),
and only get the time if se_started has been set.

ok millert@ tb@

sbin/init/init.c

index 5440d13..16e12c2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: init.c,v 1.66 2018/01/06 16:26:12 millert Exp $       */
+/*     $OpenBSD: init.c,v 1.67 2018/01/31 15:57:44 cheloha Exp $       */
 /*     $NetBSD: init.c,v 1.22 1996/05/15 23:29:33 jtc Exp $    */
 
 /*-
@@ -143,7 +143,7 @@ void setctty(char *);
 typedef struct init_session {
        int     se_index;               /* index of entry in ttys file */
        pid_t   se_process;             /* controlling process */
-       time_t  se_started;             /* used to avoid thrashing */
+       struct  timespec se_started;    /* used to avoid thrashing */
        int     se_flags;               /* status of session */
 #define        SE_SHUTDOWN     0x1             /* session won't be restarted */
 #define        SE_PRESENT      0x2             /* session is in /etc/ttys */
@@ -1007,7 +1007,7 @@ start_getty(session_t *sp)
 {
        pid_t pid;
        sigset_t mask;
-       time_t current_time = time(NULL);
+       struct timespec current_time, elapsed;
        int p[2], new = 1;
 
        if (sp->se_flags & SE_DEVEXISTS)
@@ -1060,11 +1060,15 @@ start_getty(session_t *sp)
                sleep(1);
        }
 
-       if (current_time > sp->se_started &&
-           current_time - sp->se_started < GETTY_SPACING) {
-               warning("getty repeating too quickly on port %s, sleeping",
-                   sp->se_device);
-               sleep(GETTY_SLEEP);
+       if (timespecisset(&sp->se_started)) {
+               clock_gettime(CLOCK_MONOTONIC, &current_time);
+               timespecsub(&current_time, &sp->se_started, &elapsed);
+               if (elapsed.tv_sec < GETTY_SPACING) {
+                       warning(
+                           "getty repeating too quickly on port %s, sleeping",
+                           sp->se_device);
+                       sleep(GETTY_SLEEP);
+               }
        }
 
        if (sp->se_window) {
@@ -1121,7 +1125,7 @@ collect_child(pid_t pid)
        }
 
        sp->se_process = pid;
-       sp->se_started = time(NULL);
+       clock_gettime(CLOCK_MONOTONIC, &sp->se_started);
        add_session(sp);
 }
 
@@ -1188,7 +1192,7 @@ f_multi_user(void)
                        break;
                }
                sp->se_process = pid;
-               sp->se_started = time(NULL);
+               clock_gettime(CLOCK_MONOTONIC, &sp->se_started);
                add_session(sp);
        }