#738855 initscripts: Skip killing root-owned process starting with @

Package:
initscripts
Source:
sysvinit
Submitter:
Dmitrijs Ledkovs
Date:
2025-02-11 13:09:02 UTC
Severity:
normal
Tags:
#738855#5
Date:
2014-02-13 13:58:23 UTC
From:
To:
Dear Maintainer,

There is convention starting that processes whos name starts with '@'
shouldn't be killed. It is used to indicate that process is needed to
manage root device / cleanly unmount the root filesystem.

At least mdadm supports it for it's 'mdmon' process which is daemon
needed to manage containers (aka fakeraid controllers - Intel Matrix
Raid and DDF).

I've implemented a patch using pgrep, thus it's optional code in
sendsigs if pgrep is not available.

Regards,

Dimitri.

#738855#10
Date:
2014-02-13 15:05:23 UTC
From:
To:
Hi Dimitri,

Are you sure that the described behaviour is desirable at all?

I argue that evading sendsigs should be a privileged operation. If it
isn't, I can simply rename my process to start with an '@' and block
umounting filesystems possibly causing data loss (due to failing
umount). I am not sure that the drafted scenario can actually happen in
practise, but from a first glance it seems to be the case. Thus applying
your patch would open up the possibility for data loss.

Do you concur with this reasoning?

 Yes -> Please close this bug.
 No -> Please explain in what way my argument is flawed.

Maybe mdmon should use the existing mechanism and write its PID to
/run/sendsigs.omit.d/mdmon instead?

Thanks

Helmut

#738855#15
Date:
2014-02-13 20:58:33 UTC
From:
To:
Yes, but no don't close this bug-report.

How about limiting it to processes running as root?

E.g. pgrep -u root -f "^@" ?

That way there is no loop-hole opened, since those processes could
have written to /run/sendsigs.omit.d/ already.

This is what is currently done in mdadm/stop init script.

Writing out a pidfile (and or otherwise copying them around is ok) but
it is debian [derivative] specific as far as I can tell.
Where is "@" convention is supported by a larger amount of
distributions and other initsystems (e.g. systemd).
( http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/ )
Writing out a pid-file should be avoided, especially since that is
optional across all init systems and un-desirable for newer ones.
Also, processes could be started off-root (e.g. initramfs) and/or
otherwise not hold-up unmounting root.
Thus I find "@" convention useful and lightweight self-identification.

#738855#20
Date:
2014-02-13 21:18:19 UTC
From:
To:
Control: retitle -1 initscripts: Skip killing root-owned process starting with @

I concur with this remedy. Can you update your patch or remove the patch
tag?

Thanks for pointing out the rationale and documentation. Did you notice
that the referenced documentation explicitly restricts the technique to
root-owned processes?

Thanks for not introducing a security issue. :)

Helmut

#738855#27
Date:
2014-02-14 00:28:52 UTC
From:
To:
Control: tags -1 pending

Updated patch, pushed to master. Tagging pending.

Yes, yes, yes I did *cough* =)

Thanks a lot for the review!

#738855#34
Date:
2014-02-14 08:18:19 UTC
From:
To:
Hmm. Maybe you can hold this patch off for a little longer?

Pulling in oss-sec, because I am no longer sure that the remedy
addresses all relevant aspects. Summary of previous discussion follows
for oss-sec:

Dimitri Ledkov asked for the initscripts package to exempt root-owned
processes whose process name starts with an '@' from being killed in the
sendsigs script during shutdown. This support would make initscripts a
little more compatible with systemd, which is a good thing! The relevant
systemd documentation can be found at:
http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/

However, I doubt that the proposed restriction (effective UID of process
equals 0) is sufficient. For example in a SELinux context being root may
mean significantly less. Russel Coker runs a machine where you can log
into as root remotely, see http://www.coker.com.au/selinux/play.html. In
this context allowing user processes to not be killed merely by changing
their name could cause data loss during shutdown by blocking umount. I
do not understand the consequences of the above technique in other
security extension contexts, so I am asking here for help.

The alternative mechanism currently used by initscripts is to allow
daemons to write their PID to /run/sendsigs.omit.d/$daemon. Being a
file-based approach, it can be easily controlled in the SELinux context
using restorecon.

Another aspect of interest could be processes running as root with their
capability bounding set cleared or reduced.

So dear oss-sec readers, do you think that allowing processes whose
effective UID is 0 to not being killed during shutdown is a good idea?

If the answer is no, then please assign a CVE identifier for systemd
(version 38+, src/core/killall.c).

Helmut

#738855#39
Date:
2014-02-15 19:20:12 UTC
From:
To:
I am not convinced this is something we should implement in
init.d/sendsigs.  If we are going to implement this systemd
compatibility, it might be better to implement it as a option for
killall5, instead of faking omitpid values.  Anyone willing to write
such implementation?  killall5 already know about all processes and
their names, and asking it to ignore processes matching some regular
expression should not be very hard.

#738855#44
Date:
2014-02-16 13:38:55 UTC
From:
To:
Discussion on oss-sec is inconclusive. Specifically there is no strong
opinion that the approach is considered to be a vulnerability or
weakness. Please move forward with your patch (barring other reviews).

For all participants in this bug, please do *not* Cc oss-sec unless you
intend to discuss security aspects.

Helmut

#738855#49
Date:
2014-02-16 13:26:49 UTC
From:
To:
Usually, user processes are killed by sendsigs and that is why they
cannot block umount. For instance, if a processes ends up being
unkillable (e.g. due to a kernel oops), you can experience data loss
(been there, done that). What is new here is that systemd proposed a
generic exemption mechanism for processes with effective UID 0.

Judging from the responses received so far, I think that the consensus
is that effective UID 0 should be considered fully privileged no matter
how restricted such a process is. That is a perfectly fine choice
(especially in the presence of user namespaces), but we'll have to keep
it in mind when looking at other system components that may violate this
assumption (e.g. SELinux, Linux capabilities).

I conclude that the implementation in systemd is not considered
vulnerable.

Helmut

#738855#54
Date:
2014-03-27 23:20:12 UTC
From:
To:
I am still unsure about this approach, and have decided to revert the
change in git to have more time to consider it while still being able
to upload newer versions from git.  This was the change I removed:
--- a/debian/changelog
+++ b/debian/changelog
@@ -11,10 +11,6 @@ sysvinit (2.88dsf-52) UNRELEASED; urgency=low
     stopping using start-stop-daemon, and add $START_ARGS and $STOP_ARGS
     to allow init.d scripts to add arguments to the start-stop-daemon calls.

-  [ Dimitri John Ledkov ]
-  * In sendsigs, skip killing any root user process which name starts with
-    '@' character. (Closes: #738855)
-
  -- Petter Reinholdtsen <pere@debian.org>  Thu, 13 Feb 2014 13:23:35 +0100

 sysvinit (2.88dsf-51) unstable; urgency=low
diff --git a/debian/src/initscripts/etc/init.d/sendsigs b/debian/src/initscripts/etc/init.d/sendsigs
index cdf3384..04bd03c 100755
--- a/debian/src/initscripts/etc/init.d/sendsigs
+++ b/debian/src/initscripts/etc/init.d/sendsigs
@@ -58,20 +58,6 @@ do_stop () {
                done
        fi

-       # A convention introduced by systemd and documented in
-       # http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons/
-       # is that process whos name starts with '@' shouldn't be killed during
-       # shutdown, as typically those processes are started to manage the
-       # filesystems.  Skip killing those as well before umounting file systems.
-       #
-       # TODO: don't use pgrep...
-       #
-       if [ -x /usr/bin/pgrep ]; then
-           for pid in $(pgrep -u root -f '^@'); do
-               OMITPIDS="${OMITPIDS:+$OMITPIDS }-o $pid"
-           done
-       fi
-
        # Flush the kernel I/O buffer before we start to kill
        # processes, to make sure the IO of already stopped services to
        # not slow down the remaining processes to a point where they