Module Name:    src
Committed By:   dholland
Date:           Sun Jul 31 18:14:36 UTC 2016

Modified Files:
        src/sbin/ping: ping.c

Log Message:
Manipulate the signal masks so signals only arrive while we're waiting,
so they can't illegally reenter libc.

Fixes the problem Greg A. Woods describes in PR 51267, which might or
might not be the original submitter's problem.


To generate a diff of this commit:
cvs rdiff -u -r1.110 -r1.111 src/sbin/ping/ping.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/ping/ping.c
diff -u src/sbin/ping/ping.c:1.110 src/sbin/ping/ping.c:1.111
--- src/sbin/ping/ping.c:1.110	Sun Jul 31 17:59:08 2016
+++ src/sbin/ping/ping.c	Sun Jul 31 18:14:36 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ping.c,v 1.110 2016/07/31 17:59:08 dholland Exp $	*/
+/*	$NetBSD: ping.c,v 1.111 2016/07/31 18:14:36 dholland Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -58,7 +58,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: ping.c,v 1.110 2016/07/31 17:59:08 dholland Exp $");
+__RCSID("$NetBSD: ping.c,v 1.111 2016/07/31 18:14:36 dholland Exp $");
 #endif
 
 #include <stdio.h>
@@ -160,6 +160,8 @@ static struct sockaddr_in loc_addr;		/* 
 static int datalen;				/* How much data */
 static int phdrlen;
 
+static sigset_t blockmask, enablemask;		/* signal masks */
+
 #ifndef __NetBSD__
 static char *progname;
 #define	getprogname()		(progname)
@@ -210,6 +212,8 @@ __dead static void doit(void);
 static void prefinish(int);
 static void prtsig(int);
 __dead static void finish(int);
+static void blocksignals(void);
+static void enablesignals(void);
 static void summary(int);
 static void pinger(void);
 static void fill(void);
@@ -669,6 +673,21 @@ main(int argc, char *argv[])
 
 	(void)signal(SIGINT, prefinish);
 
+	/*
+	 * Set up two signal masks:
+	 *    - blockmask blocks the signals we catch
+	 *    - enablemask does not
+	 */
+
+	sigemptyset(&enablemask);
+	sigemptyset(&blockmask);
+	sigaddset(&blockmask, SIGINT);
+#ifdef SIGINFO
+	sigaddset(&blockmask, SIGINFO);
+#else
+	sigaddset(&blockmask, SIGQUIT);
+#endif
+
 #ifdef SIGINFO
 	sa.sa_handler = prtsig;
 	sa.sa_flags = SA_NOKERNINFO;
@@ -679,6 +698,8 @@ main(int argc, char *argv[])
 #endif
 	(void)signal(SIGCONT, prtsig);
 
+	blocksignals();
+
 	/* fire off them quickies */
 	for (i = 0; i < preload; i++) {
 		clock_gettime(CLOCK_MONOTONIC, &now);
@@ -689,7 +710,6 @@ main(int argc, char *argv[])
 	return 0;
 }
 
-
 static void
 doit(void)
 {
@@ -740,9 +760,14 @@ doit(void)
 				break;
 		}
 
+
 		fdmaskp[0].fd = s;
 		fdmaskp[0].events = POLLIN;
+
+		enablesignals();
 		cc = prog_poll(fdmaskp, 1, (int)(sec * 1000));
+		blocksignals();
+
 		if (cc <= 0) {
 			if (cc < 0) {
 				if (errno == EINTR)
@@ -1430,6 +1455,22 @@ finish(int dummy)
 	exit(nreceived > 0 ? 0 : 2);
 }
 
+static void
+blocksignals(void)
+{
+	if (sigprocmask(SIG_SETMASK, &blockmask, NULL) == -1) {
+		err(EXIT_FAILURE, "blocksignals: sigprocmask");
+	}
+}
+
+static void
+enablesignals(void)
+{
+	if (sigprocmask(SIG_SETMASK, &enablemask, NULL) == -1) {
+		err(EXIT_FAILURE, "enablesignals: sigprocmask");
+	}
+}
+
 
 static int				/* 0=do not print it */
 ck_pr_icmph(struct icmp *icp,

Reply via email to