aboutsummaryrefslogtreecommitdiff
path: root/libio/bits
diff options
context:
space:
mode:
authorXi Ruoyao <xry111@xry111.site>2023-09-25 19:53:26 +0800
committerSiddhesh Poyarekar <siddhesh@sourceware.org>2023-09-26 20:11:38 -0400
commit64b1a44183a3094672ed304532bedb9acc707554 (patch)
tree41131e52fd02f763e2ab83cb9967386f4c40a515 /libio/bits
parent6b695e5c628734b9801fcf53149687cb4fe6926e (diff)
downloadglibc-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.h15
-rw-r--r--libio/bits/stdio2.h14
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)
{