Module Name:    src
Committed By:   christos
Date:           Tue Aug 23 17:09:11 UTC 2011

Modified Files:
        src/usr.sbin/makefs: cd9660.c

Log Message:
PR/45285: Martin Matuska: makefs does not properly convert ISO level 1 and 2
filenames (buffer overflow)

makefs does not properly verify the maximum filename length in the
special "." case for both ISO level 1 and ISO level 2 filename
conversion.  This creates broken images or causes a buffer overflow
(ISO level 2).

ISO level 1:
If a filename contains only dots or up to 8 characters followed by
dots the 8+3 limit check doesn't work.

ISO level 2:
If a filename contains a dot in the first 30 characters and a dot
on the 30th character, the length limit check doesn't work and the
buffer is overflowed.

$ mkdir level1
$ touch level1/12345............
$ makefs -t cd9660 -o isolevel=1 test.iso level1

$ mkdir level2
$ touch level2/1234567890.2345678901234567.....34567890123456789012345
$ makefs -t cd9660 -o isolevel=2 test.iso level2


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/usr.sbin/makefs/cd9660.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/makefs/cd9660.c
diff -u src/usr.sbin/makefs/cd9660.c:1.31 src/usr.sbin/makefs/cd9660.c:1.32
--- src/usr.sbin/makefs/cd9660.c:1.31	Sat Aug  6 19:25:19 2011
+++ src/usr.sbin/makefs/cd9660.c	Tue Aug 23 13:09:11 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: cd9660.c,v 1.31 2011/08/06 23:25:19 christos Exp $	*/
+/*	$NetBSD: cd9660.c,v 1.32 2011/08/23 17:09:11 christos Exp $	*/
 
 /*
  * Copyright (c) 2005 Daniel Watt, Walter Deignan, Ryan Gabrys, Alan
@@ -103,7 +103,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(__lint)
-__RCSID("$NetBSD: cd9660.c,v 1.31 2011/08/06 23:25:19 christos Exp $");
+__RCSID("$NetBSD: cd9660.c,v 1.32 2011/08/23 17:09:11 christos Exp $");
 #endif  /* !__lint */
 
 #include <string.h>
@@ -1637,7 +1637,7 @@
 
 	while (*oldname != '\0') {
 		/* Handle period first, as it is special */
-		if (*oldname == '.') {
+		if (*oldname == '.' && extlen < 3) {
 			if (found_ext) {
 				*newname++ = '_';
 				extlen ++;
@@ -1652,8 +1652,7 @@
 			    *oldname == ',' && strlen(oldname) == 4)
 				break;
 			/* Enforce 12.3 / 8 */
-			if (((namelen == 8) && !found_ext) ||
-			    (found_ext && extlen == 3)) {
+			if (namelen == 8 && !found_ext)
 				break;
 			}
 
@@ -1698,7 +1697,7 @@
 	int extlen = 0;
 	int found_ext = 0;
 
-	while (*oldname != '\0') {
+	while (*oldname != '\0' && namelen + extlen < 30) {
 		/* Handle period first, as it is special */
 		if (*oldname == '.') {
 			if (found_ext) {
@@ -1718,8 +1717,6 @@
 			if (diskStructure.archimedes_enabled &&
 			    *oldname == ',' && strlen(oldname) == 4)
 				break;
-			if ((namelen + extlen) == 30)
-				break;
 
 			 if (islower((unsigned char)*oldname))
 				*newname++ = toupper((unsigned char)*oldname);

Reply via email to