Fix race condition in utmp writing. Patch from Gil Kloepfer via
authorPetter Reinholdtsen <pere@hungry.com>
Sun, 22 Nov 2009 21:03:03 +0000 (21:03 +0000)
committerPetter Reinholdtsen <pere@hungry.com>
Sun, 22 Nov 2009 21:03:03 +0000 (21:03 +0000)
Mike Frysinger and Gentoo.

git-svn-id: svn://svn.sv.gnu.org/sysvinit/sysvinit/trunk@18 456724a4-4300-0410-8514-c89748c515a2

doc/Changelog
src/init.c

index 89f5bb3d9f0bf6d17435f422a9302948bbd76647..18cd20becf85468790a9f188f8b29f6caa44de26 100644 (file)
@@ -17,6 +17,8 @@ sysvinit (2.88dsf) UNRELEASED; urgency=low
     Patch from Mike Frysinger and Gentoo.
   * Sync shutdown manual page and usage information.  Patch from Mike
     Frysinger and Gentoo.
+  * Fix race condition in utmp writing.  Patch from Gil Kloepfer via
+    Mike Frysinger and Gentoo.
 
  -- Petter Reinholdtsen <pere@hungry.com>  Sun, 12 Jul 2009 19:58:10 +0200
 
index 81ecf4c6cdac6026067191bd09ccf246fc099633..30592da1a1f15732af79b6f13c1e6d5c328aa618 100644 (file)
@@ -967,6 +967,25 @@ int spawn(CHILD *ch, int *res)
 
                sigprocmask(SIG_SETMASK, &omask, NULL);
 
+               /*
+                * Update utmp/wtmp file prior to starting
+                * any child.  This MUST be done right here in
+                * the child process in order to prevent a race
+                * condition that occurs when the child
+                * process' time slice executes before the
+                * parent (can and does happen in a uniprocessor
+                * environment).  If the child is a getty and
+                * the race condition happens, then init's utmp
+                * update will happen AFTER the getty runs
+                * and expects utmp to be updated already!
+                *
+                * Do NOT log if process field starts with '+'
+                * FIXME: that's for compatibility with *very*
+                * old getties - probably it can be taken out.
+                */
+               if (ch->action == RESPAWN && ch->process[0] != '+')
+                       write_utmp_wtmp("", ch->id, getpid(), INIT_PROCESS, "");
+
                /*
                 *      In sysinit, boot, bootwait or single user mode:
                 *      for any wait-type subprocess we _force_ the console
@@ -1109,15 +1128,7 @@ void startup(CHILD *ch)
                case ONDEMAND:
                case RESPAWN:
                        ch->flags |= RUNNING;
-                       if (spawn(ch, &(ch->pid)) < 0) break;
-                       /*
-                        *      Do NOT log if process field starts with '+'
-                        *      FIXME: that's for compatibility with *very*
-                        *      old getties - probably it can be taken out.
-                        */
-                       if (ch->process[0] != '+')
-                               write_utmp_wtmp("", ch->id, ch->pid,
-                                       INIT_PROCESS, "");
+                       (void)spawn(ch, &(ch->pid));
                        break;
        }
 }