[libcxx] r316191 - Fix an unsigned integer overflow in regex that lead to a bad memory access. Found by OSS-Fuzz

Marshall Clow via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 19 15:10:41 PDT 2017


Author: marshall
Date: Thu Oct 19 15:10:41 2017
New Revision: 316191

URL: http://llvm.org/viewvc/llvm-project?rev=316191&view=rev
Log:
Fix an unsigned integer overflow in regex that lead to a bad memory access. Found by OSS-Fuzz

Modified:
    libcxx/trunk/include/regex
    libcxx/trunk/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp

Modified: libcxx/trunk/include/regex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/regex?rev=316191&r1=316190&r2=316191&view=diff
==============================================================================
--- libcxx/trunk/include/regex (original)
+++ libcxx/trunk/include/regex Thu Oct 19 15:10:41 2017
@@ -4327,8 +4327,12 @@ basic_regex<_CharT, _Traits>::__parse_de
             unsigned __v = *__first - '0';
             for (++__first;
                     __first != __last && '0' <= *__first && *__first <= '9'; ++__first)
+                {
+                if (__v >= std::numeric_limits<unsigned>::max() / 10)
+                    __throw_regex_error<regex_constants::error_backref>();
                 __v = 10 * __v + *__first - '0';
-            if (__v > mark_count())
+                }
+            if (__v == 0 || __v > mark_count())
                 __throw_regex_error<regex_constants::error_backref>();
             __push_back_ref(__v);
         }
@@ -5455,15 +5459,17 @@ match_results<_BidirectionalIterator, _A
                     if ('0' <= __fmt_first[1] && __fmt_first[1] <= '9')
                     {
                         ++__fmt_first;
-                        size_t __i = *__fmt_first - '0';
+                        size_t __idx = *__fmt_first - '0';
                         if (__fmt_first + 1 != __fmt_last &&
                             '0' <= __fmt_first[1] && __fmt_first[1] <= '9')
                         {
                             ++__fmt_first;
-                            __i = 10 * __i + *__fmt_first - '0';
+                            if (__idx >= std::numeric_limits<size_t>::max() / 10)
+                                __throw_regex_error<regex_constants::error_escape>();
+                            __idx = 10 * __idx + *__fmt_first - '0';
                         }
-                        __output = _VSTD::copy((*this)[__i].first,
-                                            (*this)[__i].second, __output);
+                        __output = _VSTD::copy((*this)[__idx].first,
+                                            (*this)[__idx].second, __output);
                     }
                     else
                     {

Modified: libcxx/trunk/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp?rev=316191&r1=316190&r2=316191&view=diff
==============================================================================
--- libcxx/trunk/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp (original)
+++ libcxx/trunk/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp Thu Oct 19 15:10:41 2017
@@ -34,6 +34,7 @@ int main()
 {
     assert(error_badbackref_thrown("\\1abc"));      // no references
     assert(error_badbackref_thrown("ab(c)\\2def")); // only one reference
+    assert(error_badbackref_thrown("\\800000000000000000000000000000")); // overflows
 
 //  this should NOT throw, because we only should look at the '1'
 //  See https://bugs.llvm.org/show_bug.cgi?id=31387




More information about the cfe-commits mailing list