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
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to