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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits