Bug 19537

Summary: patch to prevent cat'ing directories
Product: Base System Reporter: kbyanc <kbyanc>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.0-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description kbyanc 2000-06-27 02:20:03 UTC
	Similar to my last 2 PR's (PR 19514 and PR 19536), this patch
	prevents the user from cat'ing a directory (ala more(1)). With
	true 20/20 hindsight, I should have rolled all these patches
	together, but I promise this is the last one in this series...for
	now :).

How-To-Repeat: 
	cat .
Comment 1 kbyanc 2000-06-27 06:32:59 UTC
  Actually, the following is a more correct patch, please apply it instead.

  Kelly

Index: bin/cat/cat.c
===================================================================
RCS file: /home/cvs/src/bin/cat/cat.c,v
retrieving revision 1.15
diff -u -r1.15 cat.c
--- bin/cat/cat.c	2000/04/14 21:01:35	1.15
+++ bin/cat/cat.c	2000/06/27 05:24:39
@@ -68,6 +68,7 @@
 int main __P((int argc, char *argv[]));
 void raw_args __P((char *argv[]));
 void raw_cat __P((int));
+void checkmode __P((struct stat *, char *));
 
 int
 main(argc, argv)
@@ -121,6 +122,7 @@
 cook_args(argv)
 	char **argv;
 {
+	struct stat sb;
 	register FILE *fp;
 
 	fp = stdin;
@@ -129,12 +131,14 @@
 		if (*argv) {
 			if (!strcmp(*argv, "-"))
 				fp = stdin;
-			else if ((fp = fopen(*argv, "r")) == NULL) {
+			else if ((fp = fopen(*argv, "r")) == NULL ||
+			    fstat(fileno(fp), &sb)) {
 				warn("%s", *argv);
 				rval = 1;
 				++argv;
 				continue;
 			}
+			checkmode(&sb, *argv);
 			filename = *argv++;
 		}
 		cook_buf(fp);
@@ -211,6 +215,7 @@
 raw_args(argv)
 	char **argv;
 {
+	struct stat sb;
 	register int fd;
 
 	fd = fileno(stdin);
@@ -219,12 +224,14 @@
 		if (*argv) {
 			if (!strcmp(*argv, "-"))
 				fd = fileno(stdin);
-			else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
+			else if ((fd = open(*argv, O_RDONLY, 0)) < 0 ||
+			    fstat(fd, &sb)) {
 				warn("%s", *argv);
 				rval = 1;
 				++argv;
 				continue;
 			}
+			checkmode(&sb, *argv);
 			filename = *argv++;
 		}
 		raw_cat(fd);
@@ -259,4 +266,21 @@
 		warn("%s", filename);
 		rval = 1;
 	}
+}
+
+void
+checkmode(sb, fname)
+	struct stat *sb;	
+	char *fname;
+{
+	if (S_ISDIR(sb->st_mode))
+		errx(1, "%s is a directory", fname);
+	if (S_ISLNK(sb->st_mode))
+		/* This should be transparently 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);
 }
Comment 2 kbyanc 2000-06-29 00:47:19 UTC
  BDE kindly pointed out that POSIX specifies that for cat:
	The input files can be any file type.

  That includes directories, so this PR is bogus. Please close. Thanks,

  Kelly
Comment 3 John Baldwin freebsd_committer freebsd_triage 2000-07-04 06:10:47 UTC
State Changed
From-To: open->closed

Closed at the request of the originator.