This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix the UB in regex caused by long decimal string


LibFuzzer found a signed integer overflow UB in the regex library!

Here is the fix. Bootstrapped and tested on x86_64-linux-gnu.


Thanks!

-- 
Regards,
Tim Shen
diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc
index a6d8016d87f..b0aed277cf3 100644
--- a/libstdc++-v3/include/bits/regex_compiler.tcc
+++ b/libstdc++-v3/include/bits/regex_compiler.tcc
@@ -601,9 +601,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _M_cur_int_value(int __radix)
     {
       long __v = 0;
+      __glibcxx_assert(__radix > 1);
       for (typename _StringT::size_type __i = 0;
 	   __i < _M_value.length(); ++__i)
-	__v =__v * __radix + _M_traits.value(_M_value[__i], __radix);
+	{
+	  if (__v > std::numeric_limits<long>::max() / __radix)
+	    __throw_regex_error(
+		regex_constants::error_complexity,
+		"Brace expression contains a number that's too large");
+	  __v = __v * __radix + _M_traits.value(_M_value[__i], __radix);
+	}
       return __v;
     }
 
diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex
index 777edd96d73..df363d3dca4 100644
--- a/libstdc++-v3/include/std/regex
+++ b/libstdc++-v3/include/std/regex
@@ -41,6 +41,7 @@
 # include <iosfwd>
 #endif
 #include <iterator>
+#include <limits>
 #include <locale>
 #include <memory>
 #include <sstream>
diff --git a/libstdc++-v3/testsuite/28_regex/regression.cc b/libstdc++-v3/testsuite/28_regex/regression.cc
index ee4d3e1e6f8..8ab2d5c1cca 100644
--- a/libstdc++-v3/testsuite/28_regex/regression.cc
+++ b/libstdc++-v3/testsuite/28_regex/regression.cc
@@ -93,6 +93,22 @@ test06()
   }
 }
 
+// Huge brace expression number.
+void
+test07()
+{
+  bool thrown = false;
+  try
+    {
+      std::basic_regex<char> r("a{444444444444444444444444444}");
+    }
+  catch (const std::regex_error &e)
+    {
+      thrown = true;
+    }
+  VERIFY(thrown);
+}
+
 int
 main()
 {
@@ -102,6 +118,7 @@ main()
   test04();
   test05();
   test06();
+  test07();
   return 0;
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]