This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[patch] Close fds before execute a cmd
- From: Lai Jiangshan <laijs at cn dot fujitsu dot com>
- To: systemtap at sourceware dot org
- Date: Fri, 12 Oct 2007 09:43:16 +0900
- Subject: [patch] Close fds before execute a cmd
Hi, all
case 1:
stap -c 'sleep 100' -e 'probe begin{}'
# killing SIGUSR1 to "sleep 100" does not work as expected
case 2:
trap "" SIGSEGV # set SIGSEGV's handler as SIG_IGN
stap -c 'sleep 100' -e 'probe begin{}'
# killing SIGSEGV still works.
The bug reasons of case1 and case2 are same: the signal
handlers are not restored before exec().
It's not a serious bug, but it's not friendly to users.
This bug can be fixed by the patch below(Restore signals except
SIGINT).
There is also another good way: unblock all signals and
set signals' handlers as SIG_DFL **EXPLICITLY** before exec().
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
diff -Nur src/runtime/staprun/common.c src.new/runtime/staprun/common.c
--- src/runtime/staprun/common.c 2007-08-20 23:02:47.000000000 +0900
+++ src.new/runtime/staprun/common.c 2007-10-12 09:05:21.000000000 +0900
@@ -251,6 +251,12 @@
_exit(1);
}
+#ifdef SINGLE_THREADED
+#define sig_mask sigprocmask
+#else
+#define sig_mask pthread_sigmask
+#endif
+
void setup_signals(void)
{
sigset_t s;
@@ -258,11 +264,7 @@
/* blocking all signals while we set things up */
sigfillset(&s);
-#ifdef SINGLE_THREADED
- sigprocmask(SIG_SETMASK, &s, NULL);
-#else
- pthread_sigmask(SIG_SETMASK, &s, NULL);
-#endif
+ sig_mask(SIG_SETMASK, &s, NULL);
/* set some of them to be ignored */
memset(&a, 0, sizeof(a));
sigfillset(&a.sa_mask);
@@ -282,13 +284,41 @@
/* unblock all signals */
sigemptyset(&s);
-#ifdef SINGLE_THREADED
- sigprocmask(SIG_SETMASK, &s, NULL);
-#else
- pthread_sigmask(SIG_SETMASK, &s, NULL);
-#endif
+ sig_mask(SIG_SETMASK, &s, NULL);
+}
+
+static sigset_t saved_sigmask;
+static int saved_sig[] = {SIGTERM, SIGHUP, SIGQUIT,
+ SIGCHLD, SIGUSR1, SIGUSR2, SIGPIPE, SIGBUS,
+ SIGFPE, SIGILL, SIGSEGV, SIGXCPU, SIGXFSZ};
+static struct sigaction saved_sa[sizeof(saved_sig) / sizeof(saved_sig[0])];
+
+int save_signals(void)
+{
+ if(sig_mask(SIG_SETMASK, NULL, &saved_sigmask))
+ return -1;
+ int i = sizeof(saved_sig) / sizeof(saved_sig[0]);
+ while (i--) {
+ if (sigaction(saved_sig[i], NULL, &saved_sa[i]))
+ return -1;
+ }
+ return 0;
}
+int restore_signals(void)
+{
+ if(sig_mask(SIG_SETMASK, &saved_sigmask, NULL))
+ return -1;
+ int i = sizeof(saved_sig) / sizeof(saved_sig[0]);
+ while (i--) {
+ if (sigaction(saved_sig[i], &saved_sa[i], NULL))
+ return -1;
+ }
+ return 0;
+}
+
+#undef sig_mask
+
/**
* send_request - send request to kernel over control channel
* @type: the relay-app command id
diff -Nur src/runtime/staprun/mainloop.c src.new/runtime/staprun/mainloop.c
--- src/runtime/staprun/mainloop.c 2007-09-15 01:11:12.000000000 +0900
+++ src.new/runtime/staprun/mainloop.c 2007-10-10 16:04:40.000000000 +0900
@@ -90,6 +90,7 @@
/* wait here until signaled */
sigwait(&usrset, &signum);
+ restore_signals();
if (execl("/bin/sh", "sh", "-c", target_cmd, NULL) < 0)
perror(target_cmd);
@@ -112,6 +113,7 @@
_perr("fork");
} else if (pid == 0) {
setpriority (PRIO_PROCESS, 0, 0);
+ restore_signals();
if (execl("/bin/sh", "sh", "-c", cmd, NULL) < 0)
perr("%s", cmd);
_exit(1);
diff -Nur src/runtime/staprun/stapio.c src.new/runtime/staprun/stapio.c
--- src/runtime/staprun/stapio.c 2007-08-15 00:23:59.000000000 +0900
+++ src.new/runtime/staprun/stapio.c 2007-10-10 16:03:28.000000000 +0900
@@ -26,6 +26,7 @@
int main(int argc, char **argv)
{
+ save_signals();
setup_signals();
parse_args(argc, argv);
diff -Nur src/runtime/staprun/staprun.c src.new/runtime/staprun/staprun.c
--- src/runtime/staprun/staprun.c 2007-08-16 02:37:21.000000000 +0900
+++ src.new/runtime/staprun/staprun.c 2007-10-10 16:05:17.000000000 +0900
@@ -55,6 +55,8 @@
}
}
+ restore_signals();
+
/* Actually run the command. */
if (execv(path, argv) < 0)
perror(path);
@@ -149,6 +151,7 @@
{
int rc;
+ save_signals();
if (atexit(exit_cleanup)) {
_perr("cannot set exit function");
exit(1);
diff -Nur src/runtime/staprun/staprun.h src.new/runtime/staprun/staprun.h
--- src/runtime/staprun/staprun.h 2007-08-15 00:23:59.000000000 +0900
+++ src.new/runtime/staprun/staprun.h 2007-10-10 16:00:38.000000000 +0900
@@ -151,6 +151,8 @@
void usage(char *prog);
void parse_modpath(const char *);
void setup_signals(void);
+int save_signals(void);
+int restore_signals(void);
/*
* variables