diff options
author | Xi Ruoyao <xry111@xry111.site> | 2023-09-25 19:53:26 +0800 |
---|---|---|
committer | Siddhesh Poyarekar <siddhesh@sourceware.org> | 2023-09-26 20:11:38 -0400 |
commit | 64b1a44183a3094672ed304532bedb9acc707554 (patch) | |
tree | 41131e52fd02f763e2ab83cb9967386f4c40a515 /libio/bits | |
parent | 6b695e5c628734b9801fcf53149687cb4fe6926e (diff) | |
download | glibc-64b1a44183a3094672ed304532bedb9acc707554.zip glibc-64b1a44183a3094672ed304532bedb9acc707554.tar.gz glibc-64b1a44183a3094672ed304532bedb9acc707554.tar.bz2 |
libio: Add nonnull attribute for most FILE * arguments in stdio.h
During the review of a GCC analyzer test case, we found most stdio
functions accepting a FILE * argument expect it to be nonnull and just
segfault when the argument is NULL. Add nonnull attribute for them.
fflush and fflush_unlocked are well defined when __stream is NULL so
they are not touched.
For fputs, fgets, fread, fwrite, fprintf, vfprintf, and their unlocked
version, if __stream is empty but there is nothing to read or write,
they did not segfault. But the standard disallow __stream to be empty
here, so nonnull attribute is also added for them. Note that this may
blow up some old code already subtly broken.
Also add __nonnull for _chk variants and __fortify_function versions for
them.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Diffstat (limited to 'libio/bits')
-rw-r--r-- | libio/bits/stdio2-decl.h | 15 | ||||
-rw-r--r-- | libio/bits/stdio2.h | 14 |
2 files changed, 17 insertions, 12 deletions
diff --git a/libio/bits/stdio2-decl.h b/libio/bits/stdio2-decl.h index d7ef728..3b60c72 100644 --- a/libio/bits/stdio2-decl.h +++ b/libio/bits/stdio2-decl.h @@ -47,10 +47,12 @@ extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag, #if __USE_FORTIFY_LEVEL > 1 extern int __fprintf_chk (FILE *__restrict __stream, int __flag, - const char *__restrict __format, ...); + const char *__restrict __format, ...) + __nonnull ((1)); extern int __printf_chk (int __flag, const char *__restrict __format, ...); extern int __vfprintf_chk (FILE *__restrict __stream, int __flag, - const char *__restrict __format, __gnuc_va_list __ap); + const char *__restrict __format, + __gnuc_va_list __ap) __nonnull ((1)); extern int __vprintf_chk (int __flag, const char *__restrict __format, __gnuc_va_list __ap); @@ -103,7 +105,7 @@ extern char *__REDIRECT (__fgets_chk_warn, extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n, FILE *__restrict __stream) - __wur __attr_access ((__write_only__, 1, 3)); + __wur __attr_access ((__write_only__, 1, 3)) __nonnull ((4)); extern size_t __REDIRECT (__fread_alias, (void *__restrict __ptr, size_t __size, @@ -119,7 +121,7 @@ extern size_t __REDIRECT (__fread_chk_warn, extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, - FILE *__restrict __stream) __wur; + FILE *__restrict __stream) __wur __nonnull ((5)); #ifdef __USE_GNU extern char *__REDIRECT_FORTIFY (__fgets_unlocked_alias, @@ -135,7 +137,7 @@ extern char *__REDIRECT (__fgets_unlocked_chk_warn, extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size, int __n, FILE *__restrict __stream) - __wur __attr_access ((__write_only__, 1, 3)); + __wur __attr_access ((__write_only__, 1, 3)) __nonnull ((4)); #endif #ifdef __USE_MISC @@ -154,7 +156,8 @@ extern size_t __REDIRECT (__fread_unlocked_chk_warn, extern size_t __fread_unlocked_chk (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, - FILE *__restrict __stream) __wur; + FILE *__restrict __stream) + __wur __nonnull ((5)); #endif #endif /* bits/stdio2-decl.h. */ diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h index 7122640..266dccd 100644 --- a/libio/bits/stdio2.h +++ b/libio/bits/stdio2.h @@ -73,7 +73,7 @@ __NTH (vsnprintf (char *__restrict __s, size_t __n, #if __USE_FORTIFY_LEVEL > 1 # ifdef __va_arg_pack -__fortify_function int +__fortify_function __nonnull ((1)) int fprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...) { return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, @@ -102,7 +102,7 @@ vprintf (const char *__restrict __fmt, __gnuc_va_list __ap) #endif } -__fortify_function int +__fortify_function __nonnull ((1)) int vfprintf (FILE *__restrict __stream, const char *__restrict __fmt, __gnuc_va_list __ap) { @@ -191,7 +191,8 @@ gets (char *__str) } #endif -__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char * +__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) +__nonnull ((3)) char * fgets (char *__restrict __s, int __n, FILE *__restrict __stream) { size_t sz = __glibc_objsize (__s); @@ -202,7 +203,7 @@ fgets (char *__restrict __s, int __n, FILE *__restrict __stream) return __fgets_chk (__s, sz, __n, __stream); } -__fortify_function __wur size_t +__fortify_function __wur __nonnull ((4)) size_t fread (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) { @@ -215,7 +216,8 @@ fread (void *__restrict __ptr, size_t __size, size_t __n, } #ifdef __USE_GNU -__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) char * +__fortify_function __wur __fortified_attr_access (__write_only__, 1, 2) +__nonnull ((3)) char * fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) { size_t sz = __glibc_objsize (__s); @@ -229,7 +231,7 @@ fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) #ifdef __USE_MISC # undef fread_unlocked -__fortify_function __wur size_t +__fortify_function __wur __nonnull ((4)) size_t fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) { |