| Summary: | patch to prevent tail'ing directories | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | kbyanc <kbyanc> | ||||
| Component: | bin | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 4.0-STABLE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
|
Description
kbyanc
2000-06-26 09:40:00 UTC
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);
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 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/ 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 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"? |