update-rc.d: enabling or disabling S runlevel services incorrectly modifies runlevel

Bug #1827172 reported by Matthew Ruffell
12
This bug affects 1 person
Affects Status Importance Assigned to Milestone
sysvinit (Ubuntu)
Won't Fix
Medium
Matthew Ruffell
Trusty
Fix Released
Medium
Matthew Ruffell

Bug Description

[Impact]

 * update-rc.d, in sysv-rc-2.88dsf-41ubuntu6.3 is broken in trusty.

 * update-rc.d incorrectly modifies symlinks when enabling or disabling
   services which are started on the "S" runlevel.

 * This can lead to services being changed from S runlevel from where they
   would be started on boot, to "0" runlevel, and are run on halt, which is
   incorrect.

 * The bug is caused by trying to use the runlevel to index into an integer
   array of runlevels. When the runlevel in question is "S", an error is
   printed

   Argument "S" isn't numeric in array element at /usr/sbin/update-rc.d line
   232.

   Perl then sets the index to default to 0, which changes the runlevel.

 * The fix is to check if the runlevel is "S", and if it is, set the index to
   99 which conforms with other expected usages for the "S" runlevel in the
   script. See the "startstop" and "makelinks" subroutines.

[Test Case]

* You can reproduce this with any service that is started on the "S"
  runlevel. We will use open-iscsi for an example.

1) Install open-iscsi

$ sudo apt install open-iscsi

2) Check to see symlinks for init.d scripts are set to defaults:

root@trusty-openiscsi:/etc# ls -l /etc/rc[0123456S].d/*iscsi*
/etc/rc0.d/K80umountiscsi.sh -> ../init.d/umountiscsi.sh
/etc/rc0.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rc1.d/K80umountiscsi.sh -> ../init.d/umountiscsi.sh
/etc/rc1.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rc6.d/K80umountiscsi.sh -> ../init.d/umountiscsi.sh
/etc/rc6.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rcS.d/S45open-iscsi -> ../init.d/open-iscsi

3) Use update-rc.d to enable open-iscsi service

root@trusty-openiscsi:/etc# update-rc.d open-iscsi enable
update-rc.d: warning: start runlevel arguments (none) do not match open-iscsi Default-Start values (S)
update-rc.d: warning: stop runlevel arguments (none) do not match open-iscsi Default-Stop values (0 1 6)
Argument "S" isn't numeric in array element at /usr/sbin/update-rc.d line 232.
Enabling system startup links for /etc/init.d/open-iscsi ...
Removing any system startup links for /etc/init.d/open-iscsi ...
/etc/rc0.d/K81open-iscsi
/etc/rc1.d/K81open-iscsi
/etc/rc6.d/K81open-iscsi
/etc/rcS.d/S45open-iscsi
Adding system startup for /etc/init.d/open-iscsi ...
/etc/rc0.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rc1.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rc6.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rc0.d/S45open-iscsi -> ../init.d/open-iscsi

* The problem is the "/etc/rcS.d/S45open-iscsi" symlink is incorrectly
  changed to "/etc/rc0.d/S45open-iscsi".

* Instead, the correct behaviour is to keep the symlink in /etc/rcS.d/
  intact:

root@trusty-openiscsi:/etc# update-rc.d open-iscsi enable
update-rc.d: warning: start runlevel arguments (none) do not match open-iscsi Default-Start values (S)
update-rc.d: warning: stop runlevel arguments (none) do not match open-iscsi Default-Stop values (0 1 6)
Enabling system startup links for /etc/init.d/open-iscsi ...
Removing any system startup links for /etc/init.d/open-iscsi ...
/etc/rc0.d/K81open-iscsi
/etc/rc1.d/K81open-iscsi
/etc/rc6.d/K81open-iscsi
/etc/rcS.d/S45open-iscsi
Adding system startup for /etc/init.d/open-iscsi ...
/etc/rc0.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rc1.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rc6.d/K81open-iscsi -> ../init.d/open-iscsi
/etc/rcS.d/S45open-iscsi -> ../init.d/open-iscsi

[Regression Potential]

 * There is only one file modified, which is the update-rc.d perl script.
   Worst case scenario is that users cannot enable or disable their services,
   or a symlink is changed such that a service is started / stopped on an
   incorrect runlevel.

 * If a regression happens, any damage should be easily spotted by a
   sysadmin and can be manually repaired by making manual symlinks with
   "ln -s".

 * I have built and tested the change in a PPA, which you can find here:
   https://launchpad.net/~mruffell/+archive/ubuntu/sysvinit-testing

 * My only cause for concern is that if a regression does happen, it may
   impact packages that run "update-rc.d <service> [en|dis]able" in a
   postinstall module, although I haven't managed to find an example that
   does this, since most use the "defaults" command instead.

[Other Info]

 * trusty is the last Ubuntu release to use sysvinit, and this bug is not
   present in newer versions since they use systemd, and the code in question
   is removed from update-rc.d.

 * The bug exists in debian squeeze, which is now unsupported, and the code
   in question is not in any newer versions.

 * The bug was introduced in 2009-06-29 and somehow evaded anyone noticing
   it.

Tags: patch sts
Changed in sysvinit (Ubuntu Trusty):
importance: Undecided → Medium
assignee: nobody → Matthew Ruffell (mruffell)
description: updated
Changed in sysvinit (Ubuntu Trusty):
status: New → In Progress
Revision history for this message
Matthew Ruffell (mruffell) wrote :

I have developed a patch which I believe fixes the problem.

https://paste.ubuntu.com/p/QRw4XTkXkV/

description: updated
Revision history for this message
Matthew Ruffell (mruffell) wrote :

This debdiff contains the patch for trusty. I have tested it, built it in a ppa and run autopkgtest, and things look fine to me.

Revision history for this message
Ubuntu Foundations Team Bug Bot (crichton) wrote :

The attachment "sysvinit debdiff for trusty" seems to be a debdiff. The ubuntu-sponsors team has been subscribed to the bug report so that they can review and hopefully sponsor the debdiff. If the attachment isn't a patch, please remove the "patch" flag from the attachment, remove the "patch" tag, and if you are member of the ~ubuntu-sponsors, unsubscribe the team.

[This is an automated message performed by a Launchpad user owned by ~brian-murray, for any issue please contact him.]

tags: added: patch
tags: added: sts-sponsor
Dan Streetman (ddstreet)
tags: added: sts-sponsor-ddstreet
Revision history for this message
Matthew Ruffell (mruffell) wrote :

Attached is the final debdiff for release, mostly for having a record of it.

I have built it in a personal ppa, tested it and verified it works.

Dan Streetman (ddstreet)
tags: removed: sts-sponsor sts-sponsor-ddstreet
Revision history for this message
Matthew Ruffell (mruffell) wrote :

The fix was released in sysv-rc 2.88dsf-41ubuntu6.3+esm1 for Trusty ESM.

Changed in sysvinit (Ubuntu Trusty):
status: In Progress → Fix Released
Changed in sysvinit (Ubuntu):
status: New → Won't Fix
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.