bin/57414: /usr/bin/script fails silently if stdin is not a terminal

Jonathan Lennox lennox at cs.columbia.edu
Tue Sep 30 11:20:22 PDT 2003


>Number:         57414
>Category:       bin
>Synopsis:       /usr/bin/script fails silently if stdin is not a terminal
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Sep 30 11:20:17 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Jonathan Lennox
>Release:        FreeBSD 5.1-RELEASE-p7 i386
>Organization:
Columbia University
>Environment:
System: FreeBSD cnr.cs.columbia.edu 5.1-RELEASE-p7 FreeBSD 5.1-RELEASE-p7 #7: Wed Sep 24 18:19:12 EDT 2003 lennox at cnr.cs.columbia.edu:/usr/obj/usr/src/sys/CNR i386


	
>Description:

The /usr/bin/script utility fails silently if its standard input is not a
terminal.  It does nothing, and does not execute its argument, but exits
with a successful output status.

This is not such a big deal if the user is using 'script' directly -- it's
pretty easy to figure out what happened.  However, this can be *extremely*
surprising -- and dangerous -- if 'script' is called by some other program
which doesn't document this limitation.

In particular, the 'portupgrade' utility wraps its calls to 'make' and 'make
install' of upgraded ports in 'script'.  As a result, if portupgrade is run
with its standard input redirected, out-of-date ports will be deleted and
then not reinstalled, with no warning or indication of any problem.

>How-To-Repeat:
$ script /var/tmp/foo cat /etc/passwd < /dev/null
outputs only
Script started, output file is /var/tmp/foo

Script done, output file is /var/tmp/foo
and /var/tmp/foo is empty.

# BATCH=yes portupgrade -arRv < /dev/null > /var/tmp/portupgrade.log 2>&1 &
(which seems like a perfectly reasonable way of upgrading all one's ports,
without having to stay logged in to watch it happen)
deletes all out-of-date ports from your system, without replacing them with
up-to-date versions.

>Fix:

The following patch causes /usr/bin/script to error quickly with a non-zero
exit status if tcgetattr or ioctl fail, as they will if stdin is not a tty.

--- usr.bin/script/script.1.orig	Tue Sep 30 14:02:29 2003
+++ usr.bin/script/script.1	Tue Sep 30 14:06:29 2003
@@ -155,3 +155,7 @@
 mode, echo cancelling is far from ideal.  The slave terminal mode is checked
 for ECHO mode to check when to avoid manual echo logging.  This does not
 work when in a raw mode where the program being run is doing manual echo.
+.Pp
+The
+.Nm
+utility fails if the standard input is not a terminal.
--- usr.bin/script/script.c.orig	Tue Sep 30 14:01:46 2003
+++ usr.bin/script/script.c	Tue Sep 30 14:04:48 2003
@@ -126,8 +126,10 @@
 	if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL)
 		err(1, "%s", fname);
 
-	(void)tcgetattr(STDIN_FILENO, &tt);
-	(void)ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
+	if (tcgetattr(STDIN_FILENO, &tt) == -1)
+		err(1, "tcgetattr");
+	if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1)
+		err(1, "ioctl");
 	if (openpty(&master, &slave, NULL, &tt, &win) == -1)
 		err(1, "openpty");




>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list