summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMoritz Jodeit <moritz@cvs.openbsd.org>2005-05-22 18:41:35 +0000
committerMoritz Jodeit <moritz@cvs.openbsd.org>2005-05-22 18:41:35 +0000
commitf3483d4f860b0d709bed15c2f1865c82520ac923 (patch)
tree4a70f25f25c32b7c75dcd32b470675adff1b334e
parent1142f0ed92870d762d73de59f7ac62b4054101c2 (diff)
fix signal race in statistics output. ok cloder@ henning@
-rw-r--r--usr.sbin/tcpdump/addrtoname.c5
-rw-r--r--usr.sbin/tcpdump/privsep.c45
-rw-r--r--usr.sbin/tcpdump/tcpdump.c38
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)