nixpkgs/nixos/modules
aszlig 67223ee205
nixos/stage-1: Don't kill kernel threads
Unfortunately, pkill doesn't distinguish between kernel and user space
processes, so we need to make sure we don't accidentally kill kernel
threads.

Normally, a kernel thread ignores all signals, but there are a few that
do. A quick grep on the kernel source tree (as of kernel 4.6.0) shows
the following source files which use allow_signal():

  drivers/isdn/mISDN/l1oip_core.c
  drivers/md/md.c
  drivers/misc/mic/cosm/cosm_scif_server.c
  drivers/misc/mic/cosm_client/cosm_scif_client.c
  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
  drivers/staging/rtl8188eu/core/rtw_cmd.c
  drivers/staging/rtl8712/rtl8712_cmd.c
  drivers/target/iscsi/iscsi_target.c
  drivers/target/iscsi/iscsi_target_login.c
  drivers/target/iscsi/iscsi_target_nego.c
  drivers/usb/atm/usbatm.c
  drivers/usb/gadget/function/f_mass_storage.c
  fs/jffs2/background.c
  fs/lockd/clntlock.c
  fs/lockd/svc.c
  fs/nfs/nfs4state.c
  fs/nfsd/nfssvc.c

While not all of these are necessarily kthreads and some functionality
may still be unimpeded, it's still quite harmful and can cause
unexpected side-effects, especially because some of these kthreads are
storage-related (which we obviously don't want to kill during bootup).

During discussion at #15226, @dezgeg suggested the following
implementation:

for pid in $(pgrep -v -f '@'); do
    if [ "$(cat /proc/$pid/cmdline)" != "" ]; then
        kill -9 "$pid"
    fi
done

This has a few downsides:

 * User space processes which use an empty string in their command line
   won't be killed.
 * It results in errors during bootup because some shell-related
   processes are already terminated (maybe it's pgrep itself, haven't
   checked).
 * The @ is searched within the full command line, not just at the
   beginning of the string. Of course, we already had this until now, so
   it's not a problem of his implementation.

I posted an alternative implementation which doesn't suffer from the
first point, but even that one wasn't sufficient:

for pid in $(pgrep -v -f '^@'); do
    readlink "/proc/$pid/exe" &> /dev/null || continue
    echo "$pid"
done | xargs kill -9

This one spawns a subshell, which would be included in the processes to
kill and actually kills itself during the process.

So what we have now is even checking whether the shell process itself is
in the list to kill and avoids killing it just to be sure.

Also, we don't spawn a subshell anymore and use /proc/$pid/exe to
distinguish between user space and kernel processes like in the comments
of the following StackOverflow answer:

http://stackoverflow.com/a/12231039

We don't need to take care of terminating processes, because what we
actually want IS to terminate the processes.

The only point where this (and any previous) approach falls short if we
have processes that act like fork bombs, because they might spawn
additional processes between the pgrep and the killing. We can only
address this with process/control groups and this still won't save us
because the root user can escape from that as well.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Fixes: #15226
2016-05-06 16:24:42 +02:00
..
config Revert "pulseaudio: select correct outputs" 2016-04-28 17:06:09 +03:00
hardware rtl8723bs-firmware: init, split off from rtl8723bs 2016-04-25 00:41:25 -07:00
i18n/input-method input-method module: fix folder case 2016-04-12 19:50:26 +09:00
installer installer: simple PXE bootable NixOS installer 2016-04-29 10:42:39 +01:00
misc graylog service: Initial graylog service 2016-04-28 23:27:57 +02:00
profiles treewide: Use correct output in ${config.nix.package}/bin 2016-04-25 16:44:37 +02:00
programs Merge pull request #14212 from aneeshusa/add-mosh-service 2016-04-18 14:31:59 -07:00
security grsecurity: support disabling TCP simultaneous connect 2016-05-04 03:53:24 +02:00
services Fixing nfsd service, wait on local-fs. 2016-05-06 15:03:30 +02:00
system nixos/stage-1: Don't kill kernel threads 2016-05-06 16:24:42 +02:00
tasks networking module: Add some missing literalExample 2016-04-25 18:15:52 +02:00
testing test-instrumentation.nix: Only clear $PAGER in the backdoor shell 2016-02-23 11:56:09 +01:00
virtualisation Merge branch 'pr/14911' 2016-05-05 21:28:27 +01:00
module-list.nix graylog service: Initial graylog service 2016-04-28 23:27:57 +02:00
rename.nix nixos: remove redundant services.dovecot2.package option 2016-05-06 10:10:06 +02:00