Source-Changes-HG archive

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

[src/trunk]: src/bin/dd Avoid corrupting the dd(1) IO streams. This would ha...



details:   https://anonhg.NetBSD.org/src/rev/d2809d60a1c4
branches:  trunk
changeset: 555354:d2809d60a1c4
user:      dsainty <dsainty%NetBSD.org@localhost>
date:      Sat Nov 15 12:44:54 2003 +0000

description:
Avoid corrupting the dd(1) IO streams.  This would happen by accidentally
outputting to the files being manipulated by opening a file in the standard IO
descriptor space.  In particular, an output file unlucky enough to be sitting
on descriptor 2 (stderr) is certain to be corrupted.

Addresses PR bin/8521, and passes the recently committed regression test
"bin/dd".

diffstat:

 bin/dd/dd.c |  44 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 42 insertions(+), 2 deletions(-)

diffs (86 lines):

diff -r 2a5e51f68733 -r d2809d60a1c4 bin/dd/dd.c
--- a/bin/dd/dd.c       Sat Nov 15 11:54:34 2003 +0000
+++ b/bin/dd/dd.c       Sat Nov 15 12:44:54 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dd.c,v 1.33 2003/09/14 19:20:19 jschauma Exp $ */
+/*     $NetBSD: dd.c,v 1.34 2003/11/15 12:44:54 dsainty Exp $  */
 
 /*-
  * Copyright (c) 1991, 1993, 1994
@@ -43,7 +43,7 @@
 #if 0
 static char sccsid[] = "@(#)dd.c       8.5 (Berkeley) 4/2/94";
 #else
-__RCSID("$NetBSD: dd.c,v 1.33 2003/09/14 19:20:19 jschauma Exp $");
+__RCSID("$NetBSD: dd.c,v 1.34 2003/11/15 12:44:54 dsainty Exp $");
 #endif
 #endif /* not lint */
 
@@ -69,6 +69,7 @@
 static void dd_close(void);
 static void dd_in(void);
 static void getfdtype(IO *);
+static int redup_clean_fd(int);
 static void setup(void);
 
 int main(int, char *[]);
@@ -129,6 +130,9 @@
                if (in.fd < 0)
                        err(EXIT_FAILURE, "%s", in.name);
                        /* NOTREACHED */
+
+               /* Ensure in.fd is outside the stdio descriptor range */
+               in.fd = redup_clean_fd(in.fd);
        }
 
        getfdtype(&in);
@@ -159,6 +163,9 @@
                        err(EXIT_FAILURE, "%s", out.name);
                        /* NOTREACHED */
                }
+
+               /* Ensure out.fd is outside the stdio descriptor range */
+               out.fd = redup_clean_fd(out.fd);
        }
 
        getfdtype(&out);
@@ -249,6 +256,39 @@
                io->flags |= ISPIPE;            /* XXX fixed in 4.4BSD */
 }
 
+/*
+ * Move the parameter file descriptor to a descriptor that is outside the
+ * stdio descriptor range, if necessary.  This is required to avoid
+ * accidentally outputting completion or error messages into the
+ * output file that were intended for the tty.
+ */
+static int
+redup_clean_fd(int fd)
+{
+       int newfd;
+
+       if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
+           fd != STDERR_FILENO)
+               /* File descriptor is ok, return immediately. */
+               return fd;
+
+       newfd = dup(fd);
+       if (newfd < 0) {
+               err(EXIT_FAILURE, "dup IO");
+               /* NOTREACHED */
+       }
+
+       /*
+        * Recurse, to ensure that the new descriptor is clean.  Don't
+        * free the old descriptor(s) until we've allocated a clean
+        * one.
+        */
+       newfd = redup_clean_fd(newfd);
+       close(fd);
+
+       return newfd;
+}
+
 static void
 dd_in(void)
 {



Home | Main Index | Thread Index | Old Index