6ca6e8
commit a88f07f71f051021339682328103a8c75559fc5f
6ca6e8
Author: Noah Goldstein <goldstein.w.n@gmail.com>
6ca6e8
Date:   Wed Jun 22 08:24:21 2022 -0700
6ca6e8
6ca6e8
    stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265]
6ca6e8
    
6ca6e8
    mbstows is defined if dst is NULL and is defined to special cased if
6ca6e8
    dst is NULL so the fortify objsize check if incorrect in that case.
6ca6e8
    
6ca6e8
    Tested on x86-64 linux.
6ca6e8
    Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
6ca6e8
    
6ca6e8
    (cherry picked from commit 464d189b9622932a75302290625de84931656ec0)
6ca6e8
6ca6e8
diff --git a/stdlib/Makefile b/stdlib/Makefile
6ca6e8
index a4ac30d1f6359561..e13f1ee33c410ae6 100644
6ca6e8
--- a/stdlib/Makefile
6ca6e8
+++ b/stdlib/Makefile
6ca6e8
@@ -217,6 +217,9 @@ CFLAGS-tst-qsort.c += $(stack-align-test-flags)
6ca6e8
 CFLAGS-tst-makecontext.c += -funwind-tables
6ca6e8
 CFLAGS-tst-makecontext2.c += $(stack-align-test-flags)
6ca6e8
 
6ca6e8
+CFLAGS-testmb.c += -D_FORTIFY_SOURCE=2 -Wall -Werror
6ca6e8
+
6ca6e8
+
6ca6e8
 # Run a test on the header files we use.
6ca6e8
 tests-special += $(objpfx)isomac.out
6ca6e8
 
6ca6e8
diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
6ca6e8
index ccacbdf76a08225a..f0918d5d798a6ac4 100644
6ca6e8
--- a/stdlib/bits/stdlib.h
6ca6e8
+++ b/stdlib/bits/stdlib.h
6ca6e8
@@ -96,6 +96,11 @@ extern size_t __mbstowcs_chk (wchar_t *__restrict __dst,
6ca6e8
 			      const char *__restrict __src,
6ca6e8
 			      size_t __len, size_t __dstlen) __THROW
6ca6e8
     __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2));
6ca6e8
+extern size_t __REDIRECT_NTH (__mbstowcs_chk_nulldst,
6ca6e8
+			      (wchar_t *__restrict __dst,
6ca6e8
+			       const char *__restrict __src,
6ca6e8
+			       size_t __len), mbstowcs_chk)
6ca6e8
+    __attr_access ((__read_only__, 2));
6ca6e8
 extern size_t __REDIRECT_NTH (__mbstowcs_alias,
6ca6e8
 			      (wchar_t *__restrict __dst,
6ca6e8
 			       const char *__restrict __src,
6ca6e8
@@ -108,16 +113,17 @@ extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn,
6ca6e8
      __warnattr ("mbstowcs called with dst buffer smaller than len "
6ca6e8
 		 "* sizeof (wchar_t)");
6ca6e8
 
6ca6e8
-__fortify_function size_t
6ca6e8
+__always_inline __fortify_function size_t
6ca6e8
 __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src,
6ca6e8
 		 size_t __len))
6ca6e8
 {
6ca6e8
-  return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t),
6ca6e8
-			    __glibc_objsize (__dst),
6ca6e8
-			    __dst, __src, __len);
6ca6e8
+  if (__builtin_constant_p (__dst == NULL) && __dst == NULL)
6ca6e8
+    return __mbstowcs_chk_nulldst (__dst, __src, __len);
6ca6e8
+  else
6ca6e8
+    return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t),
6ca6e8
+			      __glibc_objsize (__dst), __dst, __src, __len);
6ca6e8
 }
6ca6e8
 
6ca6e8
-
6ca6e8
 extern size_t __wcstombs_chk (char *__restrict __dst,
6ca6e8
 			      const wchar_t *__restrict __src,
6ca6e8
 			      size_t __len, size_t __dstlen) __THROW
6ca6e8
diff --git a/stdlib/testmb.c b/stdlib/testmb.c
6ca6e8
index 45dae7db61fb3e7b..6ac4dfd21d2d33b8 100644
6ca6e8
--- a/stdlib/testmb.c
6ca6e8
+++ b/stdlib/testmb.c
6ca6e8
@@ -16,6 +16,13 @@ main (int argc, char *argv[])
6ca6e8
       lose = 1;
6ca6e8
     }
6ca6e8
 
6ca6e8
+  i = mbstowcs (NULL, "bar", 4);
6ca6e8
+  if (!(i == 3 && w[1] == 'a'))
6ca6e8
+    {
6ca6e8
+      puts ("mbstowcs FAILED2!");
6ca6e8
+      lose = 1;
6ca6e8
+    }
6ca6e8
+
6ca6e8
   mbstowcs (w, "blah", 5);
6ca6e8
   i = wcstombs (c, w, 10);
6ca6e8
   if (i != 4)