From: Paul Eggert Date: Wed, 30 Dec 2020 01:08:11 +0000 (-0800) Subject: canonicalize: fix ptrdiff_t overflow bug X-Git-Tag: v1.0~3274 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=6a5be910cc575aa9f48bf0a31280f8a72e533063;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index d03007b3eb..0ef300f0b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2020-12-29 Paul Eggert + + 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 havelib: Fix for Solaris 11 OpenIndiana and Solaris 11 OmniOS. diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c index 04fe95253f..e8b10f0e7d 100644 --- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #ifdef _LIBC @@ -85,6 +86,10 @@ # 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)) diff --git a/lib/canonicalize.c b/lib/canonicalize.c index a4d3aab96e..eee3dbee6e 100644 --- a/lib/canonicalize.c +++ b/lib/canonicalize.c @@ -29,6 +29,7 @@ #include #include +#include #include #include "attribute.h" @@ -43,6 +44,10 @@ # 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)) diff --git a/modules/canonicalize b/modules/canonicalize index 5003f26827..a6cf76f17f 100644 --- a/modules/canonicalize +++ b/modules/canonicalize @@ -19,6 +19,7 @@ free-posix getcwd hash-triple-simple idx +intprops memmove mempcpy nocrash diff --git a/modules/canonicalize-lgpl b/modules/canonicalize-lgpl index a96f9011ee..b8e87a607b 100644 --- a/modules/canonicalize-lgpl +++ b/modules/canonicalize-lgpl @@ -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]