about summary refs log tree commit diff
path: root/string/string.h
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-05-04 11:21:50 -0600
committerMartin Sebor <msebor@redhat.com>2020-05-04 11:21:50 -0600
commit06febd8c6705c816b2f32ee7aa1f4c0184b05248 (patch)
tree71586b8485abc1c6b220cb6aba340e76286b3087 /string/string.h
parent38c67888183db1b6ac21f2f9681b8a384987dfe8 (diff)
downloadglibc-06febd8c6705c816b2f32ee7aa1f4c0184b05248.tar.gz
glibc-06febd8c6705c816b2f32ee7aa1f4c0184b05248.tar.xz
glibc-06febd8c6705c816b2f32ee7aa1f4c0184b05248.zip
improve out-of-bounds checking with GCC 10 attribute access [BZ #25219]
Adds the access attribute newly introduced in GCC 10 to the subset of
function declarations that are already covered by _FORTIFY_SOURCE and
that don't have corresponding GCC built-in equivalents.

Reviewed-by: DJ Delorie <dj@redhat.com>
Diffstat (limited to 'string/string.h')
-rw-r--r--string/string.h33
1 files changed, 21 insertions, 12 deletions
diff --git a/string/string.h b/string/string.h
index a0f2860cc2..d7ce0f4a1b 100644
--- a/string/string.h
+++ b/string/string.h
@@ -53,7 +53,7 @@ extern void *memmove (void *__dest, const void *__src, size_t __n)
 #if defined __USE_MISC || defined __USE_XOPEN || __GLIBC_USE (ISOC2X)
 extern void *memccpy (void *__restrict __dest, const void *__restrict __src,
 		      int __c, size_t __n)
-     __THROW __nonnull ((1, 2));
+    __THROW __nonnull ((1, 2)) __attr_access ((__write_only__, 1, 4));
 #endif /* Misc || X/Open.  */
 
 
@@ -108,12 +108,15 @@ extern void *rawmemchr (const void *__s, int __c)
 /* Search N bytes of S for the final occurrence of C.  */
 # ifdef __CORRECT_ISO_CPP_STRING_H_PROTO
 extern "C++" void *memrchr (void *__s, int __c, size_t __n)
-      __THROW __asm ("memrchr") __attribute_pure__ __nonnull ((1));
+      __THROW __asm ("memrchr") __attribute_pure__ __nonnull ((1))
+      __attr_access ((__read_only__, 1, 3));
 extern "C++" const void *memrchr (const void *__s, int __c, size_t __n)
-      __THROW __asm ("memrchr") __attribute_pure__ __nonnull ((1));
+      __THROW __asm ("memrchr") __attribute_pure__ __nonnull ((1))
+      __attr_access ((__read_only__, 1, 3));
 # else
 extern void *memrchr (const void *__s, int __c, size_t __n)
-      __THROW __attribute_pure__ __nonnull ((1));
+      __THROW __attribute_pure__ __nonnull ((1))
+      __attr_access ((__read_only__, 1, 3));
 # endif
 #endif
 
@@ -146,7 +149,7 @@ extern int strcoll (const char *__s1, const char *__s2)
 /* Put a transformation of SRC into no more than N bytes of DEST.  */
 extern size_t strxfrm (char *__restrict __dest,
 		       const char *__restrict __src, size_t __n)
-     __THROW __nonnull ((2));
+    __THROW __nonnull ((2)) __attr_access ((__write_only__, 1, 3));
 
 #ifdef __USE_XOPEN2K8
 /* POSIX.1-2008 extended locale interface (see locale.h).  */
@@ -158,7 +161,8 @@ extern int strcoll_l (const char *__s1, const char *__s2, locale_t __l)
 /* Put a transformation of SRC into no more than N bytes of DEST,
    using sorting rules from L.  */
 extern size_t strxfrm_l (char *__dest, const char *__src, size_t __n,
-			 locale_t __l) __THROW __nonnull ((2, 4));
+			 locale_t __l) __THROW __nonnull ((2, 4))
+     __attr_access ((__write_only__, 1, 3));
 #endif
 
 #if (defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K8	\
@@ -368,7 +372,9 @@ extern char *strcasestr (const char *__haystack, const char *__needle)
    HAYSTACK is HAYSTACKLEN bytes long.  */
 extern void *memmem (const void *__haystack, size_t __haystacklen,
 		     const void *__needle, size_t __needlelen)
-     __THROW __attribute_pure__ __nonnull ((1, 3));
+     __THROW __attribute_pure__ __nonnull ((1, 3))
+    __attr_access ((__read_only__, 1, 2))
+    __attr_access ((__read_only__, 3, 4));
 
 /* Copy N bytes of SRC to DEST, return pointer to bytes after the
    last written byte.  */
@@ -409,17 +415,18 @@ extern char *strerror (int __errnum) __THROW;
 #  ifdef __REDIRECT_NTH
 extern int __REDIRECT_NTH (strerror_r,
 			   (int __errnum, char *__buf, size_t __buflen),
-			   __xpg_strerror_r) __nonnull ((2));
+			   __xpg_strerror_r) __nonnull ((2))
+    __attr_access ((__write_only__, 2, 3));
 #  else
 extern int __xpg_strerror_r (int __errnum, char *__buf, size_t __buflen)
-     __THROW __nonnull ((2));
+     __THROW __nonnull ((2)) __attr_access ((__write_only__, 2, 3));
 #   define strerror_r __xpg_strerror_r
 #  endif
 # else
 /* If a temporary buffer is required, at most BUFLEN bytes of BUF will be
    used.  */
 extern char *strerror_r (int __errnum, char *__buf, size_t __buflen)
-     __THROW __nonnull ((2)) __wur;
+     __THROW __nonnull ((2)) __wur  __attr_access ((__write_only__, 2, 3));
 # endif
 #endif
 
@@ -433,7 +440,8 @@ extern char *strerror_l (int __errnum, locale_t __l) __THROW;
 
 /* Set N bytes of S to 0.  The compiler will not delete a call to this
    function, even if S is dead after the call.  */
-extern void explicit_bzero (void *__s, size_t __n) __THROW __nonnull ((1));
+extern void explicit_bzero (void *__s, size_t __n) __THROW __nonnull ((1))
+    __attr_access ((__write_only__, 1, 2));
 
 /* Return the next DELIM-delimited token from *STRINGP,
    terminating it with a '\0', and update *STRINGP to point past it.  */
@@ -471,7 +479,8 @@ extern int strverscmp (const char *__s1, const char *__s2)
 extern char *strfry (char *__string) __THROW __nonnull ((1));
 
 /* Frobnicate N bytes of S.  */
-extern void *memfrob (void *__s, size_t __n) __THROW __nonnull ((1));
+extern void *memfrob (void *__s, size_t __n) __THROW __nonnull ((1))
+    __attr_access ((__write_only__, 1, 2));
 
 # ifndef basename
 /* Return the file name within directory of FILENAME.  We don't