From kbyanc@kronos.alcnet.com  Mon Jun 26 01:39:24 2000
Return-Path: <kbyanc@kronos.alcnet.com>
Received: from smtp10.atl.mindspring.net (smtp10.atl.mindspring.net [207.69.200.246])
	by hub.freebsd.org (Postfix) with ESMTP id 9F69737B644
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 26 Jun 2000 01:39:22 -0700 (PDT)
	(envelope-from kbyanc@kronos.alcnet.com)
Received: from gateway.posi.net (user-33qti6u.dialup.mindspring.com [199.174.200.222])
	by smtp10.atl.mindspring.net (8.9.3/8.8.5) with ESMTP id EAA24865
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 26 Jun 2000 04:39:19 -0400 (EDT)
Received: (from kbyanc@localhost)
	by gateway.posi.net (8.9.3/8.9.3) id BAA02636;
	Mon, 26 Jun 2000 01:39:45 -0700 (PDT)
	(envelope-from kbyanc)
Message-Id: <200006260839.BAA02636@gateway.posi.net>
Date: Mon, 26 Jun 2000 01:39:45 -0700 (PDT)
From: kbyanc@posi.net
Sender: kbyanc@kronos.alcnet.com
Reply-To: kbyanc@posi.net
To: FreeBSD-gnats-submit@freebsd.org
Subject: patch to prevent tail'ing directories
X-Send-Pr-Version: 3.2

>Number:         19514
>Category:       bin
>Synopsis:       patch to prevent tail'ing directories
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jun 26 01:40:00 PDT 2000
>Closed-Date:    Thu Jun 14 06:07:46 PDT 2001
>Last-Modified:  Thu Jun 14 06:10:33 PDT 2001
>Originator:     Kelly Yancey
>Release:        FreeBSD 4.0-STABLE i386
>Organization:
>Environment:

FreeBSD vaio 4.0-STABLE FreeBSD 4.0-STABLE #6: Sun Jun 25 18:32:08 PDT
2000     kbyanc@vaio:/usr/src/sys/compile/VAIO  i386

(although tail.c is identical in -current)

>Description:

	tail(1) does not prevent the user from doing nonsensical things
	like tail'ing directories. Other commands, i.e. more(1) do. This
	patch alerts the user when they try to tail a directory. In
	addition, it also adds checks for reading symlink contents and
	whiteout entries, however I can't imagine how either of these
	scenarios would occur.

>How-To-Repeat:

	tail .

>Fix:

--- usr.bin/tail/tail.c.orig	Mon Jun 26 01:30:01 2000
+++ usr.bin/tail/tail.c	Mon Jun 26 01:38:38 2000
@@ -171,6 +171,16 @@
 				ierr();
 				continue;
 			}
+			if (sb.st_mode & S_IFDIR)
+				errx(1, "%s is a directory", fname);
+			if (sb.st_mode & S_IFLNK)
+				/* This should transparently be resolved and
+				 * thus never happen.
+				 */
+				errx(1, "%s is a symlink", fname);
+			if (sb.st_mode & S_IFWHT)
+				/* This should never happen. */
+				errx(1, "%s is a whiteout entry", fname);
 			if (argc > 1) {
 				(void)printf("%s==> %s <==\n",
 				    first ? "" : "\n", fname);

>Release-Note:
>Audit-Trail:

From: Kelly Yancey <kbyanc@posi.net>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: bin/19514: patch to prevent tail'ing directories
Date: Mon, 26 Jun 2000 22:43:10 -0700 (PDT)

   Attached is a more correct patch, please apply it instead. Thanks,
 
   Kelly
 
 Index: usr.bin/tail/tail.c
 ===================================================================
 RCS file: /home/cvs/src/usr.bin/tail/tail.c,v
 retrieving revision 1.6
 diff -u -r1.6 tail.c
 --- usr.bin/tail/tail.c	1999/07/04 17:26:03	1.6
 +++ usr.bin/tail/tail.c	2000/06/27 05:37:31
 @@ -171,6 +171,16 @@
  				ierr();
  				continue;
  			}
 +			if (S_ISDIR(sb.st_mode))
 +				errx(1, "%s is a directory", fname);
 +			if (S_ISLNK(sb.st_mode))
 +				/* This should transparently be resolved and
 +				 * thus never happen.
 +				 */
 +				errx(1, "%s is a symlink", fname);
 +			if (S_ISWHT(sb.st_mode))
 +				/* This should never happen. */
 +				errx(1, "%s is a whiteout entry", fname);
  			if (argc > 1) {
  				(void)printf("%s==> %s <==\n",
  				    first ? "" : "\n", fname);
 
 

From: Bruce Evans <bde@zeta.org.au>
To: kbyanc@posi.net
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/19514: patch to prevent tail'ing directories
Date: Tue, 27 Jun 2000 19:22:55 +1000 (EST)

 On Mon, 26 Jun 2000 kbyanc@posi.net wrote:
 
 > >Description:
 > 
 > 	tail(1) does not prevent the user from doing nonsensical things
 > 	like tail'ing directories.
 
 It is a feature of Unix utilities that they do what they are told to do.
 
 >	Other commands, i.e. more(1) do. This
 
 This is a misfeature of more(1) :-).
 
 POSIX.2 (in the old draft that I have) specifically requires "tail -c"
 to accept arbitrary data.  tail(1) without -c is only required to handle
 text files.  head(1) is only required to handle text files.  cat(1) is
 required to handle all types of files.
 
 > 	patch alerts the user when they try to tail a directory. In
 > 	addition, it also adds checks for reading symlink contents and
 > 	whiteout entries, however I can't imagine how either of these
 > 	scenarios would occur.
 
 At least the symlink case can't happen, so don't obfuscate the code
 checking for it.
 
 > --- usr.bin/tail/tail.c.orig	Mon Jun 26 01:30:01 2000
 > +++ usr.bin/tail/tail.c	Mon Jun 26 01:38:38 2000
 > @@ -171,6 +171,16 @@
 >  				ierr();
 >  				continue;
 >  			}
 > +			if (sb.st_mode & S_IFDIR)
 > +				errx(1, "%s is a directory", fname);
 
 Exiting for a non-error is a bug.  The current tail(1) doesn't even exit
 for errors on individual files.
 
 Bruce
 
 

From: Kelly Yancey <kbyanc@posi.net>
To: Bruce Evans <bde@zeta.org.au>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/19514: patch to prevent tail'ing directories
Date: Wed, 28 Jun 2000 17:01:36 -0400 (EDT)

 On Tue, 27 Jun 2000, Bruce Evans wrote:
 
 > POSIX.2 (in the old draft that I have) specifically requires "tail -c"
 > to accept arbitrary data.  tail(1) without -c is only required to handle
 > text files.  head(1) is only required to handle text files.  cat(1) is
 > required to handle all types of files.
 
   Hmm. Sounds like a misfeature of POSIX :( What sense can
 cat/head/tailing a directory possibly make.
 
 > 
 > > 	patch alerts the user when they try to tail a directory. In
 > > 	addition, it also adds checks for reading symlink contents and
 > > 	whiteout entries, however I can't imagine how either of these
 > > 	scenarios would occur.
 > 
 > At least the symlink case can't happen, so don't obfuscate the code
 > checking for it.
 
   Noted. Personally, I like leaving tidbits like that in my source code so
 I can remember why I did (or did not do) things.
 
 > 
 > > --- usr.bin/tail/tail.c.orig	Mon Jun 26 01:30:01 2000
 > > +++ usr.bin/tail/tail.c	Mon Jun 26 01:38:38 2000
 > > @@ -171,6 +171,16 @@
 > >  				ierr();
 > >  				continue;
 > >  			}
 > > +			if (sb.st_mode & S_IFDIR)
 > > +				errx(1, "%s is a directory", fname);
 > 
 > Exiting for a non-error is a bug.  The current tail(1) doesn't even exit
 > for errors on individual files.
 > 
 > Bruce
 
   Also noted. If the POSIX hadn't ruled the current (in my opinion,
 broken) behaviour to be the law, then I would fix the patch.
 
   As it stands, I regretfully have to ask for the PR be closed and declare
 this bug a feature. :(
 
   Kelly
 
 --
 Kelly Yancey  -  kbyanc@posi.net  -  Belmont, CA
 System Administrator, eGroups.com                  http://www.egroups.com/
 Maintainer, BSD Driver Database       http://www.posi.net/freebsd/drivers/
 Coordinator, Team FreeBSD        http://www.posi.net/freebsd/Team-FreeBSD/
 
 

From: Kelly Yancey <kbyanc@posi.net>
To: Bruce Evans <bde@zeta.org.au>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/19514: patch to prevent tail'ing directories
Date: Wed, 28 Jun 2000 19:32:53 -0400 (EDT)

 On Tue, 27 Jun 2000, Bruce Evans wrote:
 
 > POSIX.2 (in the old draft that I have) specifically requires "tail -c"
 > to accept arbitrary data.  tail(1) without -c is only required to handle
 > text files.  head(1) is only required to handle text files.  cat(1) is
 > required to handle all types of files.
 > 
 
   I just researched this in the SUS and found the same thing. So contrary
 to my previous post, do not close this PR yet. Instead, please apply the
 following patch instead. It keeps us SUS and POSIX compliant in this
 regards, but is still 'user-friendly'.
 
 Index: usr.bin/tail/tail.c
 ===================================================================
 RCS file: /home/cvs/src/usr.bin/tail/tail.c,v
 retrieving revision 1.6
 diff -u -r1.6 tail.c
 --- usr.bin/tail/tail.c 1999/07/04 17:26:03     1.6
 +++ usr.bin/tail/tail.c 2000/06/28 23:23:24
 @@ -69,7 +69,7 @@
 	FILE *fp;
 	long off;
 	enum STYLE style;
 -	int ch, first;
 +	int ch, first, num;
 	char *p;
  
 	/*
 @@ -164,6 +164,7 @@
 		}
 	}
  
 +	num = 0;
 	if (*argv)
 		for (first = 1; fname = *argv++;) {
 			if ((fp = fopen(fname, "r")) == NULL ||
 @@ -171,7 +172,25 @@
 				ierr();
 				continue;
 			}
 -			if (argc > 1) {
 +				if (style == FLINES || style == RLINES) {
 +				/*
 +				 * SUS says that `line' mode is only required
 +				 * to support text files. We support everything
 +				 * that `makes sense'.
 +				 */
 +				if (S_ISDIR(sb.st_mode)) {
 +					warnx("%s is a directory", fname);
 +					continue;
 +				} else if (S_ISLNK(sb.st_mode)) {
 +					warnx("%s is a symlink", fname);
 +					continue;
 +				} else if (S_ISWHT(sb.st_mode)) {
 +					warnx("%s is a whiteout entry", fname);
 +					continue;
 +				}
 +			}
 +			num++;
 +			if (num > 1) {
 				(void)printf("%s==> %s <==\n",
 				    first ? "" : "\n", fname);
 				first = 0;
 
 
   Thanks,
 
   Kelly
 
 --
 Kelly Yancey  -  kbyanc@posi.net  -  Belmont, CA
 System Administrator, eGroups.com                  http://www.egroups.com/
 Maintainer, BSD Driver Database       http://www.posi.net/freebsd/drivers/
 Coordinator, Team FreeBSD        http://www.posi.net/freebsd/Team-FreeBSD/
 
 
State-Changed-From-To: open->closed 
State-Changed-By: schweikh 
State-Changed-When: Thu Jun 14 06:07:46 PDT 2001 
State-Changed-Why:  
We think that it's better to stick to the WYGIWYAF principle 
(what you get is what you asked for). As bde points out, 
why should "head /" not do the same thing as "cat / | head"? 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=19514 
>Unformatted:
