Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Aug 2015 21:55:16 +0000 (UTC)
From:      Jilles Tjoelker <jilles@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r287148 - in head/bin/sh: . tests/builtins
Message-ID:  <201508252155.t7PLtGQM079740@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jilles
Date: Tue Aug 25 21:55:15 2015
New Revision: 287148
URL: https://svnweb.freebsd.org/changeset/base/287148

Log:
  sh: Fix out of bounds read when there is no ] after a [:class:].
  
  The initial check for a matching ] was incorrect if a ] may be consumed by a
  [:class:]. The subsequent loop assumed that there must be a ].
  
  Remove the initial check and make the loop cope with a missing ].
  
  Found with afl-fuzz.
  
  MFC after:	1 week

Added:
  head/bin/sh/tests/builtins/case20.0   (contents, props changed)
Modified:
  head/bin/sh/expand.c
  head/bin/sh/tests/builtins/Makefile

Modified: head/bin/sh/expand.c
==============================================================================
--- head/bin/sh/expand.c	Tue Aug 25 20:49:05 2015	(r287147)
+++ head/bin/sh/expand.c	Tue Aug 25 21:55:15 2015	(r287148)
@@ -1464,21 +1464,11 @@ patmatch(const char *pattern, const char
 			bt_q = q;
 			break;
 		case '[': {
-			const char *endp;
+			const char *savep, *saveq;
 			int invert, found;
 			wchar_t chr;
 
-			endp = p;
-			if (*endp == '!' || *endp == '^')
-				endp++;
-			do {
-				while (*endp == CTLQUOTEMARK)
-					endp++;
-				if (*endp == 0)
-					goto dft;		/* no matching ] */
-				if (*endp == CTLESC)
-					endp++;
-			} while (*++endp != ']');
+			savep = p, saveq = q;
 			invert = 0;
 			if (*p == '!' || *p == '^') {
 				invert++;
@@ -1497,6 +1487,11 @@ patmatch(const char *pattern, const char
 				chr = (unsigned char)*q++;
 			c = *p++;
 			do {
+				if (c == '\0') {
+					p = savep, q = saveq;
+					c = '[';
+					goto dft;
+				}
 				if (c == CTLQUOTEMARK)
 					continue;
 				if (c == '[' && *p == ':') {

Modified: head/bin/sh/tests/builtins/Makefile
==============================================================================
--- head/bin/sh/tests/builtins/Makefile	Tue Aug 25 20:49:05 2015	(r287147)
+++ head/bin/sh/tests/builtins/Makefile	Tue Aug 25 21:55:15 2015	(r287148)
@@ -39,6 +39,7 @@ FILES+=		case16.0
 FILES+=		case17.0
 FILES+=		case18.0
 FILES+=		case19.0
+FILES+=		case20.0
 FILES+=		cd1.0
 FILES+=		cd2.0
 FILES+=		cd3.0

Added: head/bin/sh/tests/builtins/case20.0
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/bin/sh/tests/builtins/case20.0	Tue Aug 25 21:55:15 2015	(r287148)
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+# Shells do not agree about what this pattern should match, but it is
+# certain that it must not crash and the missing close bracket must not
+# be simply ignored.
+
+case B in
+[[:alpha:]) echo bad ;;
+esac



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508252155.t7PLtGQM079740>