Subject: bin/17721: missing bounds check split(1)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <xs@kittenz.org>
List: netbsd-bugs
Date: 07/25/2002 16:56:45
>Number:         17721
>Category:       bin
>Synopsis:       missing bounds check split(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 25 08:57:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        NetBSD 1.6D
>Organization:
>Environment:
/usr/src/usr.bin/split/split.c:
     $NetBSD: split.c,v 1.8 1999/11/02 10:55:47 lukem Exp $
System: NetBSD stasis 1.6D NetBSD 1.6D (STASIS) #29: Wed Jul 17 17:55:51 BST 2002 xs@stasis:/usr/src/sys/arch/i386/compile/STASIS i386
Architecture: i386
Machine: i386
>Description:

	split(1) does not assert that the prefix file name length is less
	than MAXPATHLEN - 2 (2 bytes for suffix, null.) It also does not
	explicitly null terminate fname to start with, or after it extends
	the string in newfile().

>How-To-Repeat:
	touch /tmp/test
	split /tmp/test `jot -b A $((2**17)) | tr -d '\n'`
>Fix:

Index: split.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/split/split.c,v
retrieving revision 1.8
diff -u -r1.8 split.c
--- split.c	1999/11/02 10:55:47	1.8
+++ split.c	2002/07/25 15:48:13
@@ -1,4 +1,4 @@
-/*	$NetBSD: split.c,v 1.7 1999/11/02 10:53:59 lukem Exp $	*/
+/*	$NetBSD: split.c,v 1.8 1999/11/02 10:55:47 lukem Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993, 1994
@@ -43,13 +43,14 @@
 #if 0
 static char sccsid[] = "@(#)split.c	8.3 (Berkeley) 4/25/94";
 #endif
-__RCSID("$NetBSD: split.c,v 1.7 1999/11/02 10:53:59 lukem Exp $");
+__RCSID("$NetBSD: split.c,v 1.8 1999/11/02 10:55:47 lukem Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
 
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -79,6 +80,8 @@
 	int ch;
 	char *ep, *p;
 
+	fname[0] = '\0';
+
 	while ((ch = getopt(argc, argv, "-0123456789b:l:")) != -1)
 		switch (ch) {
 		case '0': case '1': case '2': case '3': case '4':
@@ -132,7 +135,11 @@
 			++argv;
 		}
 	if (*argv != NULL)			/* File name prefix. */
-		(void)strcpy(fname, *argv++);
+		if (strlcpy(fname, *argv++, sizeof(fname))
+				>= sizeof(fname) - 2) {
+			errno = ENAMETOOLONG;
+			err(1, "%s", *(argv-1));
+		}
 	if (*argv != NULL)
 		usage();
 
@@ -280,6 +287,7 @@
 	}
 	fpnt[0] = fnum / 26 + 'a';
 	fpnt[1] = fnum % 26 + 'a';
+	fpnt[2] = '\0';
 	++fnum;
 	if (!freopen(fname, "w", stdout))
 		err(1, "%s", fname);

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