diff options
author | Moritz Jodeit <moritz@cvs.openbsd.org> | 2005-05-22 18:41:35 +0000 |
---|---|---|
committer | Moritz Jodeit <moritz@cvs.openbsd.org> | 2005-05-22 18:41:35 +0000 |
commit | f3483d4f860b0d709bed15c2f1865c82520ac923 (patch) | |
tree | 4a70f25f25c32b7c75dcd32b470675adff1b334e /usr.sbin | |
parent | 1142f0ed92870d762d73de59f7ac62b4054101c2 (diff) |
fix signal race in statistics output. ok cloder@ henning@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/tcpdump/addrtoname.c | 5 | ||||
-rw-r--r-- | usr.sbin/tcpdump/privsep.c | 45 | ||||
-rw-r--r-- | usr.sbin/tcpdump/tcpdump.c | 38 |
3 files changed, 37 insertions, 51 deletions
diff --git a/usr.sbin/tcpdump/addrtoname.c b/usr.sbin/tcpdump/addrtoname.c index 4083dd983a1..7c2abb0aa49 100644 --- a/usr.sbin/tcpdump/addrtoname.c +++ b/usr.sbin/tcpdump/addrtoname.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addrtoname.c,v 1.25 2004/12/13 05:37:25 itojun Exp $ */ +/* $OpenBSD: addrtoname.c,v 1.26 2005/05/22 18:41:33 moritz Exp $ */ /* * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -25,7 +25,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/addrtoname.c,v 1.25 2004/12/13 05:37:25 itojun Exp $ (LBL)"; + "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/addrtoname.c,v 1.26 2005/05/22 18:41:33 moritz Exp $ (LBL)"; #endif #include <sys/types.h> @@ -64,7 +64,6 @@ struct rtentry; #include "llc.h" #include "privsep.h" #include "savestr.h" -#include "setsignal.h" /* * hash tables for whatever-to-name translations diff --git a/usr.sbin/tcpdump/privsep.c b/usr.sbin/tcpdump/privsep.c index 046f3a49db3..cc5c6a0e62e 100644 --- a/usr.sbin/tcpdump/privsep.c +++ b/usr.sbin/tcpdump/privsep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep.c,v 1.18 2005/05/03 01:01:14 djm Exp $ */ +/* $OpenBSD: privsep.c,v 1.19 2005/05/22 18:41:33 moritz Exp $ */ /* * Copyright (c) 2003 Can Erkin Acar @@ -106,7 +106,7 @@ static struct ftab file_table[] = {{"/etc/appletalk.names", 1, 0}, int debug_level = LOG_INFO; int priv_fd = -1; -static volatile pid_t child_pid = -1; +volatile pid_t child_pid = -1; static volatile sig_atomic_t cur_state = STATE_INIT; static void parent_open_bpf(int, int *); @@ -122,8 +122,6 @@ static void parent_getprotoentries(int); static void parent_localtime(int fd); static void parent_getlines(int); -static void sig_pass_to_chld(int); -static void sig_got_chld(int); static void test_state(int, int); static void logmsg(int, const char *, ...); @@ -151,7 +149,7 @@ priv_init(int argc, char **argv) if (child_pid < 0) err(1, "fork() failed"); - if (!child_pid) { + if (child_pid) { if (getuid() == 0) { pw = getpwnam("_tcpdump"); if (pw == NULL) @@ -247,12 +245,6 @@ priv_init(int argc, char **argv) else cmdbuf = copy_argv(&argv[optind]); - /* Pass ALRM/TERM/HUP through to child, and accept CHLD */ - signal(SIGALRM, sig_pass_to_chld); - signal(SIGTERM, sig_pass_to_chld); - signal(SIGHUP, sig_pass_to_chld); - signal(SIGCHLD, sig_got_chld); - setproctitle("[priv]"); close(socks[1]); @@ -756,37 +748,6 @@ priv_getline(char *line, size_t line_len) return (read_string(priv_fd, line, line_len, __func__)); } -/* If priv parent gets a TERM or HUP, pass it through to child instead */ -static void -sig_pass_to_chld(int sig) -{ - int save_err = errno; - - if (child_pid != -1) - kill(child_pid, sig); - errno = save_err; -} - -/* When child dies, move into the shutdown state */ -static void -sig_got_chld(int sig) -{ - pid_t pid; - int status; - int save_err = errno; - - do { - pid = waitpid(child_pid, &status, WNOHANG); - if (pid > 0 && (WIFEXITED(status) || WIFSIGNALED(status))) - _exit(0); - } while (pid == -1 && errno == EINTR); - - if (pid == -1) - _exit(1); - - errno = save_err; -} - /* Read all data or return 1 for error. */ int may_read(int fd, void *buf, size_t n) diff --git a/usr.sbin/tcpdump/tcpdump.c b/usr.sbin/tcpdump/tcpdump.c index 03e01cfa1ec..b168ea4b95d 100644 --- a/usr.sbin/tcpdump/tcpdump.c +++ b/usr.sbin/tcpdump/tcpdump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcpdump.c,v 1.44 2005/03/30 22:13:54 moritz Exp $ */ +/* $OpenBSD: tcpdump.c,v 1.45 2005/05/22 18:41:34 moritz Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -26,7 +26,7 @@ static const char copyright[] = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997\n\ The Regents of the University of California. All rights reserved.\n"; static const char rcsid[] = - "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/tcpdump.c,v 1.44 2005/03/30 22:13:54 moritz Exp $ (LBL)"; + "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/tcpdump.c,v 1.45 2005/05/22 18:41:34 moritz Exp $ (LBL)"; #endif /* @@ -40,6 +40,7 @@ static const char rcsid[] = #include <sys/types.h> #include <sys/time.h> #include <sys/ioctl.h> +#include <sys/wait.h> #include <netinet/in.h> @@ -51,6 +52,7 @@ static const char rcsid[] = #include <unistd.h> #include <ctype.h> #include <err.h> +#include <errno.h> #include "interface.h" #include "addrtoname.h" @@ -89,12 +91,15 @@ char *program_name; int32_t thiszone; /* seconds offset from gmt to local time */ +extern volatile pid_t child_pid; + /* Externs */ extern void bpf_dump(struct bpf_program *, int); extern int esp_init(char *); /* Forwards */ RETSIGTYPE cleanup(int); +RETSIGTYPE gotchld(int); extern __dead void usage(void); /* Length of saved portion of packet. */ @@ -508,6 +513,7 @@ main(int argc, char **argv) setsignal(SIGTERM, cleanup); setsignal(SIGINT, cleanup); + setsignal(SIGCHLD, gotchld); /* Cooperate with nohup(1) XXX is this still necessary/working? */ if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); @@ -559,14 +565,15 @@ RETSIGTYPE cleanup(int signo) { struct pcap_stat stat; + sigset_t allsigs; char buf[1024]; + sigfillset(&allsigs); + sigprocmask(SIG_BLOCK, &allsigs, NULL); + /* Can't print the summary if reading from a savefile */ + (void)write(STDERR_FILENO, "\n", 1); if (pd != NULL && pcap_file(pd) == NULL) { -#if 0 - (void)fflush(stdout); /* XXX unsafe */ -#endif - (void)write(STDERR_FILENO, "\n", 1); if (pcap_stats(pd, &stat) < 0) { (void)snprintf(buf, sizeof buf, "pcap_stats: %s\n", pcap_geterr(pd)); @@ -583,6 +590,25 @@ cleanup(int signo) _exit(0); } +RETSIGTYPE +gotchld(int signo) +{ + pid_t pid; + int status; + int save_err = errno; + + do { + pid = waitpid(child_pid, &status, WNOHANG); + if (pid > 0 && (WIFEXITED(status) || WIFSIGNALED(status))) + cleanup(0); + } while (pid == -1 && errno == EINTR); + + if (pid == -1) + _exit(1); + + errno = save_err; +} + /* dump the buffer in `emacs-hexl' style */ void default_print_hexl(const u_char *cp, unsigned int length, unsigned int offset) |