csh spawns unkillable processes when /usr/bin/script is invoked from within /etc/csh.login

Solution Verified - Updated -

Environment

  • Red Hat Enterprise Linux 6
  • util-linux-ng
  • tcsh

Issue

  • When invoked from within /etc/csh.login, script spawns a csh shell that spawns programs that cannot be killed with a SIGTERM. This is because csh has a documented behaviour wherein it disables all signals when processing the /etc/csh.* files.
  • The 'script' thus inherits the ignored SIGTERM and passes it on to the child shell, which then passes that handler to all of its child processes.

Resolution

Root Cause

  • Interrupts are intentionally disabled when the files in /etc are processed so that the process of initialization cannot be interrupted. So in this context, starting up the script program with SIGTERM ignored is correct and documented behaviour (see 'onintr' in 'man csh'). Add to it the fact that any child shells inherit the SIGTERM behavior from their parent process, which in this case is the script program and you have a shell that has the default action of SIG_IGN for SIGTERM (see Signal handling in 'man csh').

  • Since tcsh is behaving as documented, this could possibly be fixed inside /usr/bin/script by resetting the signal handler for SIGTERM to SIG_DFL just before it executes the shell.

Diagnostic Steps

  • To Reproduce the problem for a user foo:
  1. Set shell as /bin/csh in /etc/passwd
  2. Add the line 'script' at the end of /etc/csh.login
  3. Login as foo
  4. yes > /dev/null &
  5. killall yes
  • Notice that 'yes' is not killed.

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments