pax(1): Honour the restrict in sigaction().
authorzrj <rimvydas.jasinskas@gmail.com>
Wed, 24 Jan 2018 14:07:16 +0000 (16:07 +0200)
committerzrj <zrj@dragonflybsd.org>
Wed, 24 Jan 2018 17:40:42 +0000 (19:40 +0200)
Use a setup_sig() helper and make it fail when either of sigaction fails.

While there, do not leak fds for "." + minor cleanup.

Taken-from: OpenBSD

bin/pax/pax.c

index 9e75eb7..052213d 100644 (file)
@@ -33,7 +33,6 @@
  * @(#) Copyright (c) 1992, 1993 The Regents of the University of California.  All rights reserved.
  * @(#)pax.c   8.2 (Berkeley) 4/18/94
  * $FreeBSD: src/bin/pax/pax.c,v 1.13.2.4 2002/11/07 15:29:53 imp Exp $
- * $DragonFly: src/bin/pax/pax.c,v 1.6 2006/09/27 21:58:08 pavalos Exp $
  */
 
 #include <sys/types.h>
@@ -52,7 +51,7 @@
 #include <unistd.h>
 #include "pax.h"
 #include "extern.h"
-static int gen_init (void);
+static int gen_init(void);
 
 /*
  * PAX main routines, general globals and some simple start up routines
@@ -98,7 +97,7 @@ char  *tempbase;              /* basename of tempfile to use for mkstemp(3) */
 /*
  *     PAX - Portable Archive Interchange
  *
- *     A utility to read, write, and write lists of the members of archive
+ *     A utility to read, write, and write lists of the members of archive
  *     files and copy directory hierarchies. A variety of archive formats
  *     are supported (some are described in POSIX 1003.1 10.1):
  *
@@ -216,9 +215,9 @@ char        *tempbase;              /* basename of tempfile to use for mkstemp(3) */
  */
 
 int
-main(int argc, char **argv)
+main(int argc, char *argv[])
 {
-       char *tmpdir;
+       const char *tmpdir;
        size_t tdlen;
 
        setlocale(LC_ALL, "");
@@ -226,7 +225,7 @@ main(int argc, char **argv)
        /*
         * Keep a reference to cwd, so we can always come back home.
         */
-       cwdfd = open(".", O_RDONLY);
+       cwdfd = open(".", O_RDONLY | O_CLOEXEC);
        if (cwdfd < 0) {
                syswarn(0, errno, "Can't open current working directory.");
                return(exit_val);
@@ -238,7 +237,7 @@ main(int argc, char **argv)
        if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
                tmpdir = _PATH_TMP;
        tdlen = strlen(tmpdir);
-       while(tdlen > 0 && tmpdir[tdlen - 1] == '/')
+       while (tdlen > 0 && tmpdir[tdlen - 1] == '/')
                tdlen--;
        tempfile = malloc(tdlen + 1 + sizeof(_TFILE_BASE));
        if (tempfile == NULL) {
@@ -260,7 +259,7 @@ main(int argc, char **argv)
        /*
         * select a primary operation mode
         */
-       switch(act) {
+       switch (act) {
        case EXTRACT:
                extract();
                break;
@@ -313,6 +312,25 @@ sig_cleanup(int which_sig)
        exit(1);
 }
 
+/*
+ * setup_sig()
+ *     set a signal to be caught, but only if it isn't being ignored already
+ */
+
+static int
+setup_sig(int sig, const struct sigaction *n_hand)
+{
+       struct sigaction o_hand;
+
+       if (sigaction(sig, NULL, &o_hand) < 0)
+               return (-1);
+
+       if (o_hand.sa_handler == SIG_IGN)
+               return (0);
+
+       return (sigaction(sig, n_hand, NULL));
+}
+
 /*
  * gen_init()
  *     general setup routines. Not all are required, but they really help
@@ -324,7 +342,6 @@ gen_init(void)
 {
        struct rlimit reslimit;
        struct sigaction n_hand;
-       struct sigaction o_hand;
 
        /*
         * Really needed to handle large archives. We can run out of memory for
@@ -378,34 +395,16 @@ gen_init(void)
        n_hand.sa_flags = 0;
        n_hand.sa_handler = sig_cleanup;
 
-       if ((sigaction(SIGHUP, &n_hand, &o_hand) < 0) &&
-           (o_hand.sa_handler == SIG_IGN) &&
-           (sigaction(SIGHUP, &o_hand, &o_hand) < 0))
-               goto out;
-
-       if ((sigaction(SIGTERM, &n_hand, &o_hand) < 0) &&
-           (o_hand.sa_handler == SIG_IGN) &&
-           (sigaction(SIGTERM, &o_hand, &o_hand) < 0))
-               goto out;
-
-       if ((sigaction(SIGINT, &n_hand, &o_hand) < 0) &&
-           (o_hand.sa_handler == SIG_IGN) &&
-           (sigaction(SIGINT, &o_hand, &o_hand) < 0))
-               goto out;
-
-       if ((sigaction(SIGQUIT, &n_hand, &o_hand) < 0) &&
-           (o_hand.sa_handler == SIG_IGN) &&
-           (sigaction(SIGQUIT, &o_hand, &o_hand) < 0))
-               goto out;
-
-       if ((sigaction(SIGXCPU, &n_hand, &o_hand) < 0) &&
-           (o_hand.sa_handler == SIG_IGN) &&
-           (sigaction(SIGXCPU, &o_hand, &o_hand) < 0))
+       if (setup_sig(SIGHUP,  &n_hand) ||
+           setup_sig(SIGTERM, &n_hand) ||
+           setup_sig(SIGINT,  &n_hand) ||
+           setup_sig(SIGQUIT, &n_hand) ||
+           setup_sig(SIGXCPU, &n_hand))
                goto out;
 
        n_hand.sa_handler = SIG_IGN;
-       if ((sigaction(SIGPIPE, &n_hand, &o_hand) < 0) ||
-           (sigaction(SIGXFSZ, &n_hand, &o_hand) < 0))
+       if ((sigaction(SIGPIPE, &n_hand, NULL) < 0) ||
+           (sigaction(SIGXFSZ, &n_hand, NULL) < 0))
                goto out;
        return(0);