diff -u upstart-0.6.7/debian/changelog upstart-0.6.7/debian/changelog --- upstart-0.6.7/debian/changelog +++ upstart-0.6.7/debian/changelog @@ -1,3 +1,10 @@ +upstart (0.6.7-4) natty; urgency=low + + * util/telinit.c: on "telinit u", don't SIGTERM init which might not be + upstart if we're in a chroot; LP: #694772. + + -- Loïc Minier Tue, 04 Jan 2011 14:59:05 +0100 + upstart (0.6.7-3) natty; urgency=low * debian/rules: make sure apparmor-profile-load is executable. only in patch2: unchanged: --- upstart-0.6.7.orig/util/telinit.c +++ upstart-0.6.7/util/telinit.c @@ -23,6 +23,7 @@ #include +#include #include #include @@ -83,6 +84,28 @@ return 0; } +/** + * init_is_chrooted: + * + * Checks whether this process is chrooted by comparing the root inode of this + * process with the one from PID 1 + * + * Returns: one if chrooted, zero if not chrooted, negative on error + **/ +int init_is_chrooted(void) { + struct stat root_stat; + struct stat init_root_stat; + + if (stat ("/", &root_stat) < 0) + return -1; + + if (stat ("/proc/1/root", &init_root_stat) < 0) + return -1; + + return (root_stat.st_dev == init_root_stat.st_dev + && root_stat.st_ino == init_root_stat.st_ino) ? 0 : 1; +} + #ifndef TEST /** @@ -174,6 +197,17 @@ break; case 'U': case 'u': + /* Don't SIGTERM a possibly non-upstart init if in a chroot */ + ret = init_is_chrooted(); + if (ret < 0) { + nih_fatal (_("Couldn't check whether chrooted")); + exit (1); + } + if (ret == 1) { + fprintf (stderr, + _("Ignoring request to restart init outside of a chroot")); + exit(0); + } ret = kill (1, SIGTERM); if (ret < 0) nih_error_raise_system ();