]> Savannah Git Hosting - gnulib.git/commitdiff
canonicalize: fix ptrdiff_t overflow bug
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 30 Dec 2020 01:08:11 +0000 (17:08 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 30 Dec 2020 01:12:25 +0000 (17:12 -0800)
Problem reported by Adhemerval Zanella in:
https://sourceware.org/pipermail/libc-alpha/2020-December/121182.html
* lib/canonicalize-lgpl.c, lib/canonicalize.c:
Include intprops.h.
(NARROW_ADDRESSES): New constant.
* lib/canonicalize-lgpl.c (realpath_stk):m
* lib/canonicalize.c (canonicalize_filename_mode_stk):
Work even if strlen (END) does not fit in idx_t, or if adding
N to it overflows.
* modules/canonicalize, modules/canonicalize-lgpl (Depends-on):
Add intprops.

ChangeLog
lib/canonicalize-lgpl.c
lib/canonicalize.c
modules/canonicalize
modules/canonicalize-lgpl

index d03007b3ebc587959b6859c3affd03a337aae34e..0ef300f0b02cf8b98508c53f54c9022993321325 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2020-12-29  Paul Eggert  <eggert@cs.ucla.edu>
+
+       canonicalize: fix ptrdiff_t overflow bug
+       Problem reported by Adhemerval Zanella in:
+       https://sourceware.org/pipermail/libc-alpha/2020-December/121182.html
+       * lib/canonicalize-lgpl.c, lib/canonicalize.c:
+       Include intprops.h.
+       (NARROW_ADDRESSES): New constant.
+       * lib/canonicalize-lgpl.c (realpath_stk):m
+       * lib/canonicalize.c (canonicalize_filename_mode_stk):
+       Work even if strlen (END) does not fit in idx_t, or if adding
+       N to it overflows.
+       * modules/canonicalize, modules/canonicalize-lgpl (Depends-on):
+       Add intprops.
+
 2020-12-28  Bruno Haible  <bruno@clisp.org>
 
        havelib: Fix for Solaris 11 OpenIndiana and Solaris 11 OmniOS.
index 04fe95253f94a537c4ef63690fb8243566fdc744..e8b10f0e7d150bf7ce054f21c648fce681f8b6f9 100644 (file)
@@ -40,6 +40,7 @@
 #include <eloop-threshold.h>
 #include <filename.h>
 #include <idx.h>
+#include <intprops.h>
 #include <scratch_buffer.h>
 
 #ifdef _LIBC
 # define IF_LINT(Code) /* empty */
 #endif
 
+/* True if adding two valid object sizes might overflow idx_t.
+   As a practical matter, this cannot happen on 64-bit machines.  */
+enum { NARROW_ADDRESSES = IDX_MAX >> 31 >> 31 == 0 };
+
 #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
 # define DOUBLE_SLASH_IS_DISTINCT_ROOT false
 #endif
@@ -338,7 +343,12 @@ realpath_stk (const char *name, char *resolved,
               idx_t end_idx IF_LINT (= 0);
               if (end_in_extra_buffer)
                 end_idx = end - extra_buf;
-              idx_t len = strlen (end);
+              size_t len = strlen (end);
+              if (NARROW_ADDRESSES && INT_ADD_OVERFLOW (len, n))
+                {
+                  __set_errno (ENOMEM);
+                  goto error;
+                }
               while (extra_buffer.length <= len + n)
                 {
                   if (!scratch_buffer_grow_preserve (&extra_buffer))
index a4d3aab96e1efa2b654911821f6a976e5e3788a7..eee3dbee6e062562c6e9fbb88a7867dda9ab5853 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <filename.h>
 #include <idx.h>
+#include <intprops.h>
 #include <scratch_buffer.h>
 
 #include "attribute.h"
 # define IF_LINT(Code) /* empty */
 #endif
 
+/* True if adding two valid object sizes might overflow idx_t.
+   As a practical matter, this cannot happen on 64-bit machines.  */
+enum { NARROW_ADDRESSES = IDX_MAX >> 31 >> 31 == 0 };
+
 #ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
 # define DOUBLE_SLASH_IS_DISTINCT_ROOT false
 #endif
@@ -389,7 +394,12 @@ canonicalize_filename_mode_stk (const char *name, canonicalize_mode_t can_mode,
               idx_t end_idx IF_LINT (= 0);
               if (end_in_extra_buffer)
                 end_idx = end - extra_buf;
-              idx_t len = strlen (end);
+              size_t len = strlen (end);
+              if (NARROW_ADDRESSES && INT_ADD_OVERFLOW (len, n))
+                {
+                  errno = ENOMEM;
+                  goto error;
+                }
               while (extra_buffer.length <= len + n)
                 {
                   if (!scratch_buffer_grow_preserve (&extra_buffer))
index 5003f268275202e38aec34c98772714100474e91..a6cf76f17fd54101161287be423bbc0113165199 100644 (file)
@@ -19,6 +19,7 @@ free-posix
 getcwd
 hash-triple-simple
 idx
+intprops
 memmove
 mempcpy
 nocrash
index a96f9011eebef3c8223b4d7860be9296feaa276d..b8e87a607bc4e0aa822582e7bbb30de9692dc1fa 100644 (file)
@@ -18,6 +18,7 @@ fcntl-h           [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONI
 filename          [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1]
 free-posix        [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1]
 idx               [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1]
+intprops          [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1]
 libc-config       [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1]
 malloc-posix      [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1]
 memmove           [test $HAVE_CANONICALIZE_FILE_NAME = 0 || test $REPLACE_CANONICALIZE_FILE_NAME = 1]