Bug 5564

Summary: ash does not handle terminating signals correctly
Product: Busybox Reporter: Dennis Groenen <tj.groenen>
Component: Standard ComplianceAssignee: unassigned
Status: NEW ---    
Severity: normal CC: busybox-cvs
Priority: P5    
Version: 1.19.x   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:
Attachments: Two patches to implement the mentioned signal handler in ash

Description Dennis Groenen 2012-09-22 10:29:59 UTC
Created attachment 4562 [details]
Two patches to implement the mentioned signal handler in ash

There seem to be two bugs in ash with regards to handling terminating signals.
1) When launching an application in the background from a shell, it won't get
SIGHUPped when the parent shell receives a terminating signal.
2) When ash receives a terminating signal it won't call exitshell(), resulting
in its history not being written out when FEATURE_EDITING_SAVE_ON_EXIT is set.

Bash fixes these two issues by installing a signal handler for all terminating
signals. Also see sig.c in the bash source, search for terminating_signals[] for
the complete list of terminating signals and termsig_handler for the handler.

Attached are two patches that'll introduce a similar signal handler for ash. The
signal handler re-uses pkill* to signal children and exits the shell cleanly
afterwards. Pgrep had to be patched slightly to allow it to be called from other
applets. The signal handler is installed only for SIGHUP when ash is
interactive, but this can be extended easily to more terminating signals.

My main concerns with it at the moment are the use of unsafe functions in the
signal handler. However, as far as I can see, bash calls (indirectly) large
amounts of code from their terminating signal handler as well, though I haven't
done an extensive code analysis. I'm not sure what the negative implications are
of my (or their) code wrt shell applications, so all feedback is much appreciated.

* Calling kill() or killpg() instead of re-using pkill did not result in the
loop application being killed as in the steps to reproduce below.

---Steps to reproduce (busybox 1.20.2)
Note: loop is a C application that simply loops forever
[term1 ~] busybox ash
[term1 ~] echo $$
19619
[term1 ~] ./loop &

[term2 ~] pstree -p 19619
busybox(19619)---loop(19624)
[term2 ~] kill -1 19619
[term2 ~] pidof loop # loop does not get killed
19624
[term2 ~] cat ~/.ash_history # shell does not exit cleanly, e.g. no history
cat: /home/dennis/.ash_history: No such file or directory

--Expected results (bash 4.2.37-2)
Note: loop is a C application that simply loops forever
[term1 ~]$ bash
[term1 ~]$ echo $$
19561
[term1 ~]$ ./loop &
[1] 19562

[term2 ~]$ pstree -p 19561
bash(19561)---loop(19562)
[term2 ~]$ kill -1 19561
[term2 ~]$ pidof loop # loop gets killed
[term2 ~] cat ~/.bash_history | tail -2 # history gets saved
echo $$
./loop &