Clément Pit–Claudel wrote:
the last check (len < length1) was added to "avoid overflow in computing sum of 
lengths". But I thought int overflow was undefined behaviour, so why does the len < 
length1 check make sense?

You're right, it doesn't. I fixed this by installing the attached patch into Gnulib. You should look at the Gnulib version and not the glibc version: Gnulib regex has portability and other fixes that glibc regex doesn't. I never have gotten up the energy to propagate the Gnulib fixes back into glibc.
From d2e639dd5a5586e1daad32d30624d98c2805ffb6 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Fri, 16 Dec 2016 09:34:02 -0800
Subject: [PATCH] regex: fix integer-overflow bug in never-used code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Clément Pit–Claudel in:
http://lists.gnu.org/archive/html/emacs-devel/2016-12/msg00654.html
* lib/regex_internal.h: Include intprops.h.
* lib/regexec.c (re_search_2_stub): Use it to avoid undefined
behavior on integer overflow.
* modules/regex (Depends-on): Add intprops.
---
 ChangeLog            | 8 ++++++++
 lib/regex_internal.h | 2 ++
 lib/regexec.c        | 6 ++++--
 modules/regex        | 1 +
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dd67dba..c588296 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2016-12-16  Paul Eggert  <egg...@cs.ucla.edu>
 
+       regex: fix integer-overflow bug in never-used code
+       Problem reported by Clément Pit–Claudel in:
+       http://lists.gnu.org/archive/html/emacs-devel/2016-12/msg00654.html
+       * lib/regex_internal.h: Include intprops.h.
+       * lib/regexec.c (re_search_2_stub): Use it to avoid undefined
+       behavior on integer overflow.
+       * modules/regex (Depends-on): Add intprops.
+
        fpending: fix port to MinGW on Emacs
        * lib/stdio-impl.h [__MINGW32__]: Do not include errno.h.
        Problem reported by Eli Zaretskii in:
diff --git a/lib/regex_internal.h b/lib/regex_internal.h
index 56a315a..7ac5f92 100644
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -33,6 +33,8 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+#include "intprops.h"
+
 #ifdef _LIBC
 # include <libc-lock.h>
 # define lock_define(name) __libc_lock_define (, name)
diff --git a/lib/regexec.c b/lib/regexec.c
index afdc173..f1e61af 100644
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -354,10 +354,12 @@ re_search_2_stub (struct re_pattern_buffer *bufp, const 
char *string1,
 {
   const char *str;
   regoff_t rval;
-  Idx len = length1 + length2;
+  Idx len;
   char *s = NULL;
 
-  if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
+  if (BE ((length1 < 0 || length2 < 0 || stop < 0
+           || INT_ADD_WRAPV (length1, length2, &len)),
+          0))
     return -2;
 
   /* Concatenate the strings.  */
diff --git a/modules/regex b/modules/regex
index c5ae1b2..e1c9b58 100644
--- a/modules/regex
+++ b/modules/regex
@@ -18,6 +18,7 @@ ssize_t
 alloca-opt      [test $ac_use_included_regex = yes]
 btowc           [test $ac_use_included_regex = yes]
 gettext-h       [test $ac_use_included_regex = yes]
+intprops        [test $ac_use_included_regex = yes]
 lock      [test "$ac_cv_gnu_library_2_1:$ac_use_included_regex" = no:yes]
 memcmp          [test $ac_use_included_regex = yes]
 memmove         [test $ac_use_included_regex = yes]
-- 
2.7.4

Reply via email to