[PATCH 6/6] Cygwin: Suppress false positive use-after-free warnings in __set_lc_time_from_win()

Jon Turney jon.turney@dronecode.org.uk
Sun Aug 4 21:48:27 GMT 2024


Supress new use-after-free warnings about realloc(), seen with gcc 12, e.g.:

> In function ‘void rebase_locale_buf(const void*, const void*, const char*, const char*, const char*)’,
>     inlined from ‘int __set_lc_time_from_win(const char*, const lc_time_T*, lc_time_T*, char**, wctomb_p, const char*)’ at ../../../../src/winsup/cygwin/nlsfuncs.cc:705:25:
> ../../../../src/winsup/cygwin/nlsfuncs.cc:338:24: error: pointer ‘new_lc_time_buf’ may be used after ‘void* realloc(void*, size_t)’ [-Werror=use-after-free]
>   338 |       *ptrs += newbase - oldbase;
>       |                ~~~~~~~~^~~~~~~~~
> ../../../../src/winsup/cygwin/nlsfuncs.cc: In function ‘int __set_lc_time_from_win(const char*, const lc_time_T*, lc_time_T*, char**, wctomb_p, const char*)’:
> ../../../../src/winsup/cygwin/nlsfuncs.cc:699:44: note: call to ‘void* realloc(void*, size_t)’ here
>   699 |               char *tmp = (char *) realloc (new_lc_time_buf, len);

We do some calculations using the pointer passed to realloc(), but do
not not dereference it, so this seems safe?

Because use-after-free is a new warning in gcc 12, we only disable it on
gcc 12 or later, to avoid warnings about unknown diagnostic options on
earlier gcc versions.
---
 winsup/cygwin/nlsfuncs.cc | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/winsup/cygwin/nlsfuncs.cc b/winsup/cygwin/nlsfuncs.cc
index b32fecc8e..cf0e96d2d 100644
--- a/winsup/cygwin/nlsfuncs.cc
+++ b/winsup/cygwin/nlsfuncs.cc
@@ -324,6 +324,10 @@ locale_cmp (const void *a, const void *b)
    structures consist entirely of pointers so they are practically pointer
    arrays.  What we do here is just treat the lc_foo pointers as char ** and
    rebase all char * pointers within, up to the given size of the structure. */
+#pragma GCC diagnostic push
+#if __GNUC__ >= 12
+#pragma GCC diagnostic ignored "-Wuse-after-free"
+#endif
 static void
 rebase_locale_buf (const void *ptrv, const void *ptrvend, const char *newbase,
 		   const char *oldbase, const char *oldend)
@@ -333,6 +337,7 @@ rebase_locale_buf (const void *ptrv, const void *ptrvend, const char *newbase,
     if (*ptrs >= oldbase && *ptrs < oldend)
       *ptrs += newbase - oldbase;
 }
+#pragma GCC diagnostic pop
 
 static wchar_t *
 __getlocaleinfo (wchar_t *loc, LCTYPE type, char **ptr, size_t size)
@@ -699,7 +704,12 @@ __set_lc_time_from_win (const char *name,
 		  if (tmp != new_lc_time_buf)
 		    rebase_locale_buf (_time_locale, _time_locale + 1, tmp,
 				       new_lc_time_buf, lc_time_ptr);
+#pragma GCC diagnostic push
+#if __GNUC__ >= 12
+#pragma GCC diagnostic ignored "-Wuse-after-free"
+#endif
 		  lc_time_ptr = tmp + (lc_time_ptr - new_lc_time_buf);
+#pragma GCC diagnostic pop
 		  new_lc_time_buf = tmp;
 		  lc_time_end = new_lc_time_buf + len;
 		}
-- 
2.45.1



More information about the Cygwin-patches mailing list