Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/ping Manipulate the signal masks so signals only arrive...



details:   https://anonhg.NetBSD.org/src/rev/50f21c24586f
branches:  trunk
changeset: 816885:50f21c24586f
user:      dholland <dholland%NetBSD.org@localhost>
date:      Sun Jul 31 18:14:36 2016 +0000

description:
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.

diffstat:

 sbin/ping/ping.c |  47 ++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 44 insertions(+), 3 deletions(-)

diffs (113 lines):

diff -r 0707556be7a7 -r 50f21c24586f sbin/ping/ping.c
--- a/sbin/ping/ping.c  Sun Jul 31 17:59:08 2016 +0000
+++ b/sbin/ping/ping.c  Sun Jul 31 18:14:36 2016 +0000
@@ -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 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 @@
 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 @@
 
        (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 @@
 #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 @@
        return 0;
 }
 
-
 static void
 doit(void)
 {
@@ -740,9 +760,14 @@
                                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 @@
        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,



Home | Main Index | Thread Index | Old Index