about summary refs log tree commit diff
path: root/posix
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 /posix
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 'posix')
-rw-r--r--posix/bits/unistd.h58
-rw-r--r--posix/unistd.h65
2 files changed, 76 insertions, 47 deletions
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
index b8a8211d83..725a83eb0d 100644
--- a/posix/bits/unistd.h
+++ b/posix/bits/unistd.h
@@ -21,9 +21,11 @@
 #endif
 
 extern ssize_t __read_chk (int __fd, void *__buf, size_t __nbytes,
-			   size_t __buflen) __wur;
+			   size_t __buflen)
+  __wur __attr_access ((__write_only__, 2, 3));
 extern ssize_t __REDIRECT (__read_alias, (int __fd, void *__buf,
-					  size_t __nbytes), read) __wur;
+					  size_t __nbytes), read)
+  __wur __attr_access ((__write_only__, 2, 3));
 extern ssize_t __REDIRECT (__read_chk_warn,
 			   (int __fd, void *__buf, size_t __nbytes,
 			    size_t __buflen), __read_chk)
@@ -46,15 +48,19 @@ read (int __fd, void *__buf, size_t __nbytes)
 
 #ifdef __USE_UNIX98
 extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes,
-			    __off_t __offset, size_t __bufsize) __wur;
+			    __off_t __offset, size_t __bufsize)
+  __wur __attr_access ((__write_only__, 2, 3));
 extern ssize_t __pread64_chk (int __fd, void *__buf, size_t __nbytes,
-			      __off64_t __offset, size_t __bufsize) __wur;
+			      __off64_t __offset, size_t __bufsize)
+  __wur __attr_access ((__write_only__, 2, 3));
 extern ssize_t __REDIRECT (__pread_alias,
 			   (int __fd, void *__buf, size_t __nbytes,
-			    __off_t __offset), pread) __wur;
+			    __off_t __offset), pread)
+  __wur __attr_access ((__write_only__, 2, 3));
 extern ssize_t __REDIRECT (__pread64_alias,
 			   (int __fd, void *__buf, size_t __nbytes,
-			    __off64_t __offset), pread64) __wur;
+			    __off64_t __offset), pread64)
+  __wur __attr_access ((__write_only__, 2, 3));
 extern ssize_t __REDIRECT (__pread_chk_warn,
 			   (int __fd, void *__buf, size_t __nbytes,
 			    __off_t __offset, size_t __bufsize), __pread_chk)
@@ -123,11 +129,11 @@ pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
 extern ssize_t __readlink_chk (const char *__restrict __path,
 			       char *__restrict __buf, size_t __len,
 			       size_t __buflen)
-     __THROW __nonnull ((1, 2)) __wur;
+     __THROW __nonnull ((1, 2)) __wur __attr_access ((__write_only__, 2, 3));
 extern ssize_t __REDIRECT_NTH (__readlink_alias,
 			       (const char *__restrict __path,
 				char *__restrict __buf, size_t __len), readlink)
-     __nonnull ((1, 2)) __wur;
+     __nonnull ((1, 2)) __wur __attr_access ((__write_only__, 2, 3));
 extern ssize_t __REDIRECT_NTH (__readlink_chk_warn,
 			       (const char *__restrict __path,
 				char *__restrict __buf, size_t __len,
@@ -155,12 +161,12 @@ __NTH (readlink (const char *__restrict __path, char *__restrict __buf,
 extern ssize_t __readlinkat_chk (int __fd, const char *__restrict __path,
 				 char *__restrict __buf, size_t __len,
 				 size_t __buflen)
-     __THROW __nonnull ((2, 3)) __wur;
+     __THROW __nonnull ((2, 3)) __wur __attr_access ((__write_only__, 3, 4));
 extern ssize_t __REDIRECT_NTH (__readlinkat_alias,
 			       (int __fd, const char *__restrict __path,
 				char *__restrict __buf, size_t __len),
 			       readlinkat)
-     __nonnull ((2, 3)) __wur;
+     __nonnull ((2, 3)) __wur __attr_access ((__write_only__, 3, 4));
 extern ssize_t __REDIRECT_NTH (__readlinkat_chk_warn,
 			       (int __fd, const char *__restrict __path,
 				char *__restrict __buf, size_t __len,
@@ -187,9 +193,10 @@ __NTH (readlinkat (int __fd, const char *__restrict __path,
 #endif
 
 extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen)
-     __THROW __wur;
+     __THROW __wur __attr_access ((__write_only__, 1, 2));
 extern char *__REDIRECT_NTH (__getcwd_alias,
-			     (char *__buf, size_t __size), getcwd) __wur;
+			     (char *__buf, size_t __size), getcwd)
+  __wur __attr_access ((__write_only__, 1, 2));
 extern char *__REDIRECT_NTH (__getcwd_chk_warn,
 			     (char *__buf, size_t __size, size_t __buflen),
 			     __getcwd_chk)
@@ -212,7 +219,7 @@ __NTH (getcwd (char *__buf, size_t __size))
 
 #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
 extern char *__getwd_chk (char *__buf, size_t buflen)
-     __THROW __nonnull ((1)) __wur;
+     __THROW __nonnull ((1)) __wur __attr_access ((__write_only__, 1, 2));
 extern char *__REDIRECT_NTH (__getwd_warn, (char *__buf), getwd)
      __nonnull ((1)) __wur __warnattr ("please use getcwd instead, as getwd "
 				       "doesn't specify buffer size");
@@ -227,9 +234,11 @@ __NTH (getwd (char *__buf))
 #endif
 
 extern size_t __confstr_chk (int __name, char *__buf, size_t __len,
-			     size_t __buflen) __THROW;
+			     size_t __buflen) __THROW
+  __attr_access ((__write_only__, 2, 3));
 extern size_t __REDIRECT_NTH (__confstr_alias, (int __name, char *__buf,
-						size_t __len), confstr);
+						size_t __len), confstr)
+   __attr_access ((__write_only__, 2, 3));
 extern size_t __REDIRECT_NTH (__confstr_chk_warn,
 			      (int __name, char *__buf, size_t __len,
 			       size_t __buflen), __confstr_chk)
@@ -252,9 +261,9 @@ __NTH (confstr (int __name, char *__buf, size_t __len))
 
 
 extern int __getgroups_chk (int __size, __gid_t __list[], size_t __listlen)
-     __THROW __wur;
+  __THROW __wur __attr_access ((__write_only__, 2, 1));
 extern int __REDIRECT_NTH (__getgroups_alias, (int __size, __gid_t __list[]),
-			   getgroups) __wur;
+			   getgroups) __wur __attr_access ((__write_only__, 2, 1));
 extern int __REDIRECT_NTH (__getgroups_chk_warn,
 			   (int __size, __gid_t __list[], size_t __listlen),
 			   __getgroups_chk)
@@ -277,7 +286,8 @@ __NTH (getgroups (int __size, __gid_t __list[]))
 
 
 extern int __ttyname_r_chk (int __fd, char *__buf, size_t __buflen,
-			    size_t __nreal) __THROW __nonnull ((2));
+			    size_t __nreal) __THROW __nonnull ((2))
+   __attr_access ((__write_only__, 2, 3));
 extern int __REDIRECT_NTH (__ttyname_r_alias, (int __fd, char *__buf,
 					       size_t __buflen), ttyname_r)
      __nonnull ((2));
@@ -304,7 +314,7 @@ __NTH (ttyname_r (int __fd, char *__buf, size_t __buflen))
 
 #ifdef __USE_POSIX199506
 extern int __getlogin_r_chk (char *__buf, size_t __buflen, size_t __nreal)
-     __nonnull ((1));
+     __nonnull ((1)) __attr_access ((__write_only__, 1, 2));
 extern int __REDIRECT (__getlogin_r_alias, (char *__buf, size_t __buflen),
 		       getlogin_r) __nonnull ((1));
 extern int __REDIRECT (__getlogin_r_chk_warn,
@@ -331,9 +341,10 @@ getlogin_r (char *__buf, size_t __buflen)
 
 #if defined __USE_MISC || defined __USE_UNIX98
 extern int __gethostname_chk (char *__buf, size_t __buflen, size_t __nreal)
-     __THROW __nonnull ((1));
+     __THROW __nonnull ((1)) __attr_access ((__write_only__, 1, 2));
 extern int __REDIRECT_NTH (__gethostname_alias, (char *__buf, size_t __buflen),
-			   gethostname) __nonnull ((1));
+			   gethostname)
+  __nonnull ((1)) __attr_access ((__write_only__, 1, 2));
 extern int __REDIRECT_NTH (__gethostname_chk_warn,
 			   (char *__buf, size_t __buflen, size_t __nreal),
 			   __gethostname_chk)
@@ -358,10 +369,11 @@ __NTH (gethostname (char *__buf, size_t __buflen))
 
 #if defined __USE_MISC || (defined __USE_XOPEN && !defined __USE_UNIX98)
 extern int __getdomainname_chk (char *__buf, size_t __buflen, size_t __nreal)
-     __THROW __nonnull ((1)) __wur;
+     __THROW __nonnull ((1)) __wur __attr_access ((__write_only__, 1, 2));
 extern int __REDIRECT_NTH (__getdomainname_alias, (char *__buf,
 						   size_t __buflen),
-			   getdomainname) __nonnull ((1)) __wur;
+			   getdomainname) __nonnull ((1))
+  __wur __attr_access ((__write_only__, 1, 2));
 extern int __REDIRECT_NTH (__getdomainname_chk_warn,
 			   (char *__buf, size_t __buflen, size_t __nreal),
 			   __getdomainname_chk)
diff --git a/posix/unistd.h b/posix/unistd.h
index 0dd4200ad6..32b8161619 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -357,13 +357,15 @@ extern int close (int __fd);
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
-extern ssize_t read (int __fd, void *__buf, size_t __nbytes) __wur;
+extern ssize_t read (int __fd, void *__buf, size_t __nbytes) __wur
+    __attr_access ((__write_only__, 2, 3));
 
 /* Write N bytes of BUF to FD.  Return the number written, or -1.
 
    This function is a cancellation point and therefore not marked with
    __THROW.  */
-extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur;
+extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur
+    __attr_access ((__read_only__, 2, 3));
 
 #if defined __USE_UNIX98 || defined __USE_XOPEN2K8
 # ifndef __USE_FILE_OFFSET64
@@ -374,7 +376,8 @@ extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur;
    This function is a cancellation point and therefore not marked with
    __THROW.  */
 extern ssize_t pread (int __fd, void *__buf, size_t __nbytes,
-		      __off_t __offset) __wur;
+		      __off_t __offset) __wur
+    __attr_access ((__write_only__, 2, 3));
 
 /* Write N bytes of BUF to FD at the given position OFFSET without
    changing the file pointer.  Return the number written, or -1.
@@ -382,15 +385,19 @@ extern ssize_t pread (int __fd, void *__buf, size_t __nbytes,
    This function is a cancellation point and therefore not marked with
    __THROW.  */
 extern ssize_t pwrite (int __fd, const void *__buf, size_t __n,
-		       __off_t __offset) __wur;
+		       __off_t __offset) __wur
+    __attr_access ((__read_only__, 2, 3));
+
 # else
 #  ifdef __REDIRECT
 extern ssize_t __REDIRECT (pread, (int __fd, void *__buf, size_t __nbytes,
 				   __off64_t __offset),
-			   pread64) __wur;
+			   pread64) __wur
+    __attr_access ((__write_only__, 2, 3));
 extern ssize_t __REDIRECT (pwrite, (int __fd, const void *__buf,
 				    size_t __nbytes, __off64_t __offset),
-			   pwrite64) __wur;
+			   pwrite64) __wur
+    __attr_access ((__read_only__, 2, 3));
 #  else
 #   define pread pread64
 #   define pwrite pwrite64
@@ -402,11 +409,13 @@ extern ssize_t __REDIRECT (pwrite, (int __fd, const void *__buf,
    changing the file pointer.  Return the number read, -1 for errors
    or 0 for EOF.  */
 extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes,
-			__off64_t __offset) __wur;
+			__off64_t __offset) __wur
+    __attr_access ((__write_only__, 2, 3));
 /* Write N bytes of BUF to FD at the given position OFFSET without
    changing the file pointer.  Return the number written, or -1.  */
 extern ssize_t pwrite64 (int __fd, const void *__buf, size_t __n,
-			 __off64_t __offset) __wur;
+			 __off64_t __offset) __wur
+    __attr_access ((__read_only__, 2, 3));
 # endif
 #endif
 
@@ -508,7 +517,8 @@ extern int fchdir (int __fd) __THROW __wur;
    an array is allocated with `malloc'; the array is SIZE
    bytes long, unless SIZE == 0, in which case it is as
    big as necessary.  */
-extern char *getcwd (char *__buf, size_t __size) __THROW __wur;
+extern char *getcwd (char *__buf, size_t __size) __THROW __wur
+    __attr_access ((__write_only__, 1, 2));
 
 #ifdef	__USE_GNU
 /* Return a malloc'd string containing the current directory name.
@@ -523,7 +533,8 @@ extern char *get_current_dir_name (void) __THROW;
    If successful, return BUF.  If not, put an error message in
    BUF and return NULL.  BUF should be at least PATH_MAX bytes long.  */
 extern char *getwd (char *__buf)
-     __THROW __nonnull ((1)) __attribute_deprecated__ __wur;
+     __THROW __nonnull ((1)) __attribute_deprecated__ __wur
+    __attr_access ((__write_only__, 1));
 #endif
 
 
@@ -620,7 +631,8 @@ extern long int sysconf (int __name) __THROW;
 
 #ifdef	__USE_POSIX2
 /* Get the value of the string-valued system variable NAME.  */
-extern size_t confstr (int __name, char *__buf, size_t __len) __THROW;
+extern size_t confstr (int __name, char *__buf, size_t __len) __THROW
+    __attr_access ((__write_only__, 2, 3));
 #endif
 
 
@@ -686,8 +698,8 @@ extern __gid_t getegid (void) __THROW;
 /* If SIZE is zero, return the number of supplementary groups
    the calling process is in.  Otherwise, fill in the group IDs
    of its supplementary groups in LIST and return the number written.  */
-extern int getgroups (int __size, __gid_t __list[]) __THROW __wur;
-
+extern int getgroups (int __size, __gid_t __list[]) __THROW __wur
+    __attr_access ((__write_only__, 2, 1));
 #ifdef	__USE_GNU
 /* Return nonzero iff the calling process is in group GID.  */
 extern int group_member (__gid_t __gid) __THROW;
@@ -772,7 +784,7 @@ extern char *ttyname (int __fd) __THROW;
 /* Store at most BUFLEN characters of the pathname of the terminal FD is
    open on in BUF.  Return 0 on success, otherwise an error number.  */
 extern int ttyname_r (int __fd, char *__buf, size_t __buflen)
-     __THROW __nonnull ((2)) __wur;
+     __THROW __nonnull ((2)) __wur __attr_access ((__write_only__, 2, 3));
 
 /* Return 1 if FD is a valid descriptor associated
    with a terminal, zero if not.  */
@@ -807,7 +819,8 @@ extern int symlink (const char *__from, const char *__to)
    Returns the number of characters read, or -1 for errors.  */
 extern ssize_t readlink (const char *__restrict __path,
 			 char *__restrict __buf, size_t __len)
-     __THROW __nonnull ((1, 2)) __wur;
+     __THROW __nonnull ((1, 2)) __wur __attr_access ((__write_only__, 2, 3));
+
 #endif /* Use POSIX.1-2001.  */
 
 #ifdef __USE_ATFILE
@@ -818,7 +831,7 @@ extern int symlinkat (const char *__from, int __tofd,
 /* Like readlink but a relative PATH is interpreted relative to FD.  */
 extern ssize_t readlinkat (int __fd, const char *__restrict __path,
 			   char *__restrict __buf, size_t __len)
-     __THROW __nonnull ((2, 3)) __wur;
+     __THROW __nonnull ((2, 3)) __wur __attr_access ((__read_only__, 3, 4));
 #endif
 
 /* Remove the link NAME.  */
@@ -853,7 +866,8 @@ extern char *getlogin (void);
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern int getlogin_r (char *__name, size_t __name_len) __nonnull ((1));
+extern int getlogin_r (char *__name, size_t __name_len) __nonnull ((1))
+    __attr_access ((__write_only__, 1, 2));
 #endif
 
 #ifdef	__USE_MISC
@@ -874,7 +888,8 @@ extern int setlogin (const char *__name) __THROW __nonnull ((1));
 /* Put the name of the current host in no more than LEN bytes of NAME.
    The result is null-terminated if LEN is large enough for the full
    name and the terminator.  */
-extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1));
+extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1))
+    __attr_access ((__write_only__, 1, 2));
 #endif
 
 
@@ -882,7 +897,7 @@ extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1));
 /* Set the name of the current host to NAME, which is LEN bytes long.
    This call is restricted to the super-user.  */
 extern int sethostname (const char *__name, size_t __len)
-     __THROW __nonnull ((1)) __wur;
+     __THROW __nonnull ((1)) __wur __attr_access ((__read_only__, 1, 2));
 
 /* Set the current machine's Internet number to ID.
    This call is restricted to the super-user.  */
@@ -893,10 +908,9 @@ extern int sethostid (long int __id) __THROW __wur;
    Called just like `gethostname' and `sethostname'.
    The NIS domain name is usually the empty string when not using NIS.  */
 extern int getdomainname (char *__name, size_t __len)
-     __THROW __nonnull ((1)) __wur;
+     __THROW __nonnull ((1)) __wur __attr_access ((__write_only__, 1, 2));
 extern int setdomainname (const char *__name, size_t __len)
-     __THROW __nonnull ((1)) __wur;
-
+     __THROW __nonnull ((1)) __wur __attr_access ((__read_only__, 1, 2));
 
 /* Revoke access permissions to all processes currently communicating
    with the control terminal, and then send a SIGHUP signal to the process
@@ -1131,7 +1145,9 @@ extern char *crypt (const char *__key, const char *__salt)
    range [FROM - N + 1, FROM - 1].  If N is odd the first byte in FROM
    is without partner.  */
 extern void swab (const void *__restrict __from, void *__restrict __to,
-		  ssize_t __n) __THROW __nonnull ((1, 2));
+		  ssize_t __n) __THROW __nonnull ((1, 2))
+    __attr_access ((__read_only__, 1, 3))
+    __attr_access ((__write_only__, 2, 3));
 #endif
 
 
@@ -1158,7 +1174,8 @@ extern int pthread_atfork (void (*__prepare) (void),
 #ifdef __USE_MISC
 /* Write LENGTH bytes of randomness starting at BUFFER.  Return 0 on
    success or -1 on error.  */
-int getentropy (void *__buffer, size_t __length) __wur;
+int getentropy (void *__buffer, size_t __length) __wur
+    __attr_access ((__write_only__, 1, 2));
 #endif
 
 /* Define some macros helping to catch buffer overflows.  */