>From d468be5b5950bc5f2e0a5a4fbaeb0ea6a88c4c9f Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 10 Sep 2020 14:25:51 -0700 Subject: [PATCH] canonicalize: fix pointer indexing bugs Problem reported by Florian Weimer in: https://lists.gnu.org/r/bug-gnulib/2020-09/msg00025.html * lib/canonicalize-lgpl.c (__realpath): * lib/canonicalize.c (canonicalize_filename_mode): Do not generate a pointer past the end of the array. * lib/canonicalize.c (canonicalize_filename_mode): Do not use a pointer after passing it to realloc. --- ChangeLog | 11 +++++++++++ lib/canonicalize-lgpl.c | 2 +- lib/canonicalize.c | 19 ++++++++----------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8b6f62bb1..bf39cc512 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2020-09-10 Paul Eggert + + canonicalize: fix pointer indexing bugs + Problem reported by Florian Weimer in: + https://lists.gnu.org/r/bug-gnulib/2020-09/msg00025.html + * lib/canonicalize-lgpl.c (__realpath): + * lib/canonicalize.c (canonicalize_filename_mode): + Do not generate a pointer past the end of the array. + * lib/canonicalize.c (canonicalize_filename_mode): + Do not use a pointer after passing it to realloc. + 2020-09-09 Paul Eggert tempname: help merge with glibc diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c index 0b89d2a18..cc42662db 100644 --- a/lib/canonicalize-lgpl.c +++ b/lib/canonicalize-lgpl.c @@ -234,7 +234,7 @@ __realpath (const char *name, char *resolved) if (!ISSLASH (dest[-1])) *dest++ = '/'; - if (dest + (end - start) >= rpath_limit) + if (rpath_limit - dest <= end - start) { ptrdiff_t dest_offset = dest - rpath; char *new_rpath; diff --git a/lib/canonicalize.c b/lib/canonicalize.c index 8bb325414..aa0c3bd28 100644 --- a/lib/canonicalize.c +++ b/lib/canonicalize.c @@ -138,18 +138,15 @@ canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode) rname = xgetcwd (); if (!rname) return NULL; - dest = strchr (rname, '\0'); - if (dest - rname < PATH_MAX) + size_t rnamelen = strlen (rname); + size_t rnamesize = rnamelen; /* Lower bound on size; good enough. */ + if (rnamesize < PATH_MAX) { - char *p = xrealloc (rname, PATH_MAX); - dest = p + (dest - rname); - rname = p; - rname_limit = rname + PATH_MAX; - } - else - { - rname_limit = dest; + rnamesize = PATH_MAX; + rname = xrealloc (rname, rnamesize); } + dest = rname + rnamelen; + rname_limit = rname + rnamesize; start = name; prefix_len = FILE_SYSTEM_PREFIX_LEN (rname); } @@ -204,7 +201,7 @@ canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode) if (!ISSLASH (dest[-1])) *dest++ = '/'; - if (dest + (end - start) >= rname_limit) + if (rname_limit - dest <= end - start) { ptrdiff_t dest_offset = dest - rname; size_t new_size = rname_limit - rname; -- 2.17.1