summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog53
-rw-r--r--debug/tst-chk1.c22
-rw-r--r--libio/bits/stdio2.h82
-rw-r--r--misc/sys/cdefs.h13
-rw-r--r--posix/bits/unistd.h224
-rw-r--r--socket/bits/socket2.h36
-rw-r--r--stdlib/bits/stdlib.h65
-rw-r--r--wcsmbs/bits/wchar2.h228
8 files changed, 601 insertions, 122 deletions
diff --git a/ChangeLog b/ChangeLog
index 682c2e3d1f..ed21b4f857 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2007-09-26 Jakub Jelinek <jakub@redhat.com>
+
+ * misc/sys/cdefs.h (__warndecl, __errordecl): For GCC 4.3+ define
+ with __warning__/__error__ attributes.
+ (__warnattr): Define.
+ * stdlib/bits/stdlib.h (__realpath_chk_warn, __ptsname_r_chk_warn,
+ __mbstowcs_chk_warn, __wcstombs_chk_warn): New aliases with
+ __warnattr.
+ (realpath, ptsname_r, mbstowcs, wcstombs): Call __*_chk_warn instead
+ of __*_chk if compile time detectable overflow is found.
+ * libio/bits/stdio2.h (__fgets_chk_warn, __fread_chk_warn,
+ __fgets_unlocked_chk_warn, __fread_unlocked_chk_warn): New aliases
+ with __warnattr.
+ (fgets, fread, fgets_unlocked, fread_unlocked): Call __*_chk_warn
+ instead of __*_chk if compile time detectable overflow is found.
+ (__gets_alias): Rename to...
+ (__gets_warn): ... this. Add __warnattr.
+ (gets): Call __gets_warn instead of __gets_alias.
+ * socket/bits/socket2.h (__recv_chk_warn, __recvfrom_chk_warn): New
+ aliases with __warnattr.
+ (recv, recvfrom): Call __*_chk_warn instead of __*_chk if compile
+ time detectable overflow is found.
+ * posix/bits/unistd.h (__read_chk_warn, __pread_chk_warn,
+ __pread64_chk_warn, __readlink_chk_warn, __readlinkat_chk_warn,
+ __getcwd_chk_warn, __confstr_chk_warn, __getgroups_chk_warn,
+ __ttyname_r_chk_warn, __getlogin_r_chk_warn, __gethostname_chk_warn,
+ __getdomainname_chk_warn): New aliases with __warnattr.
+ (read, pread, pread64, readlink, readlinkat, getcwd, confstr,
+ getgroups, ttyname_r, getlogin_r, gethostname, getdomainname): Call
+ __*_chk_warn instead of __*_chk if compile time detectable overflow
+ is found.
+ (__getgroups_chk): Rename argument to __listlen from listlen.
+ (__getwd_alias): Rename to...
+ (__getwd_warn): ... this. Add __warnattr.
+ (getwd): Call __getwd_warn instead of __getwd_alias.
+ * wcsmbs/bits/wchar2.h (__wmemcpy_chk_warn, __wmemmove_chk_warn,
+ __wmempcpy_chk_warn, __wmemset_chk_warn, __wcsncpy_chk_warn,
+ __wcpncpy_chk_warn, __fgetws_chk_warn, __fgetws_unlocked_chk_warn,
+ __mbsrtowcs_chk_warn, __wcsrtombs_chk_warn, __mbsnrtowcs_chk_warn,
+ __wcsnrtombs_chk_warn): New aliases with __warnattr.
+ (wmemcpy, wmemmove, wmempcpy, wmemset, mbsrtowcs, wcsrtombs,
+ mbsnrtowcs, wcsnrtombs): Call __*_chk_warn instead of __*_chk if
+ compile time detectable overflow is found.
+ (wcsncpy, wcpncpy): Likewise. For constant __n fix check whether
+ to use __*_chk or not.
+ (fgetws, fgetws_unlocked): Divide __bos by sizeof (wchar_t), both
+ in comparisons which function should be called and in __*_chk*
+ arguments. Call __*_chk_warn instead of __*_chk if compile time
+ detectable overflow is found.
+ (swprintf, vswprintf): Divide __bos by sizeof (wchar_t) in
+ __*_chk argument.
+ * debug/tst-chk1.c (do_test): Add a few more tests.
+
2007-09-24 Ulrich Drepper <drepper@redhat.com>
[BZ #5058]
diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
index 78a61be53b..487b071026 100644
--- a/debug/tst-chk1.c
+++ b/debug/tst-chk1.c
@@ -317,6 +317,14 @@ do_test (void)
CHK_FAIL_START
snprintf (buf + 8, l0 + 3, "%d", num2);
CHK_FAIL_END
+
+ CHK_FAIL_START
+ swprintf (wbuf + 8, 3, L"%d", num1);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ swprintf (wbuf + 8, l0 + 3, L"%d", num1);
+ CHK_FAIL_END
# endif
memcpy (buf, str1 + 2, l0 + 9);
@@ -514,11 +522,15 @@ do_test (void)
CHK_FAIL_END
CHK_FAIL_START
+ wmemcpy (wbuf + 9, L"abcdefghij", l0 + 10);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
CHK_FAIL_END
CHK_FAIL_START
- wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
+ wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
CHK_FAIL_END
CHK_FAIL_START
@@ -538,6 +550,14 @@ do_test (void)
CHK_FAIL_END
CHK_FAIL_START
+ wcsncpy (wbuf + 9, L"XABCDEFGH", 8);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
+ wcpncpy (wbuf + 9, L"XABCDEFGH", 8);
+ CHK_FAIL_END
+
+ CHK_FAIL_START
wcpncpy (wbuf + 6, L"cd", l0 + 5);
CHK_FAIL_END
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
index 841a0ff6aa..8889540689 100644
--- a/libio/bits/stdio2.h
+++ b/libio/bits/stdio2.h
@@ -131,14 +131,16 @@ vfprintf (FILE *__restrict __stream,
#endif
extern char *__gets_chk (char *__str, size_t) __wur;
-extern char *__REDIRECT (__gets_alias, (char *__str), gets) __wur;
+extern char *__REDIRECT (__gets_warn, (char *__str), gets)
+ __wur __warnattr ("please use fgets or getline instead, gets can't "
+ "specify buffer size");
__extern_always_inline __wur char *
gets (char *__str)
{
if (__bos (__str) != (size_t) -1)
return __gets_chk (__str, __bos (__str));
- return __gets_alias (__str);
+ return __gets_warn (__str);
}
extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
@@ -146,13 +148,23 @@ extern char *__fgets_chk (char *__restrict __s, size_t __size, int __n,
extern char *__REDIRECT (__fgets_alias,
(char *__restrict __s, int __n,
FILE *__restrict __stream), fgets) __wur;
+extern char *__REDIRECT (__fgets_chk_warn,
+ (char *__restrict __s, size_t __size, int __n,
+ FILE *__restrict __stream), __fgets_chk)
+ __wur __warnattr ("fgets called with bigger size than length "
+ "of destination buffer");
__extern_always_inline __wur char *
fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
{
- if (__bos (__s) != (size_t) -1
- && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
- return __fgets_chk (__s, __bos (__s), __n, __stream);
+ if (__bos (__s) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__n) || __n <= 0)
+ return __fgets_chk (__s, __bos (__s), __n, __stream);
+
+ if ((size_t) __n > __bos (__s))
+ return __fgets_chk_warn (__s, __bos (__s), __n, __stream);
+ }
return __fgets_alias (__s, __n, __stream);
}
@@ -163,17 +175,28 @@ extern size_t __REDIRECT (__fread_alias,
(void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream),
fread) __wur;
+extern size_t __REDIRECT (__fread_chk_warn,
+ (void *__restrict __ptr, size_t __ptrlen,
+ size_t __size, size_t __n,
+ FILE *__restrict __stream),
+ __fread_chk)
+ __wur __warnattr ("fread called with bigger size * nmemb than length "
+ "of destination buffer");
__extern_always_inline __wur size_t
fread (void *__restrict __ptr, size_t __size, size_t __n,
FILE *__restrict __stream)
{
- if (__bos0 (__ptr) != (size_t) -1
- && (!__builtin_constant_p (__size)
+ if (__bos0 (__ptr) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__size)
|| !__builtin_constant_p (__n)
- || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))
- || __size * __n > __bos0 (__ptr)))
- return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
+ || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)))
+ return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
+
+ if (__size * __n > __bos0 (__ptr))
+ return __fread_chk_warn (__ptr, __bos0 (__ptr), __size, __n, __stream);
+ }
return __fread_alias (__ptr, __size, __n, __stream);
}
@@ -183,13 +206,23 @@ extern char *__fgets_unlocked_chk (char *__restrict __s, size_t __size,
extern char *__REDIRECT (__fgets_unlocked_alias,
(char *__restrict __s, int __n,
FILE *__restrict __stream), fgets_unlocked) __wur;
+extern char *__REDIRECT (__fgets_unlocked_chk_warn,
+ (char *__restrict __s, size_t __size, int __n,
+ FILE *__restrict __stream), __fgets_unlocked_chk)
+ __wur __warnattr ("fgets_unlocked called with bigger size than length "
+ "of destination buffer");
__extern_always_inline __wur char *
fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
{
- if (__bos (__s) != (size_t) -1
- && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
- return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream);
+ if (__bos (__s) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__n) || __n <= 0)
+ return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream);
+
+ if ((size_t) __n > __bos (__s))
+ return __fgets_unlocked_chk_warn (__s, __bos (__s), __n, __stream);
+ }
return __fgets_unlocked_alias (__s, __n, __stream);
}
#endif
@@ -203,17 +236,30 @@ extern size_t __REDIRECT (__fread_unlocked_alias,
(void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream),
fread_unlocked) __wur;
+extern size_t __REDIRECT (__fread_unlocked_chk_warn,
+ (void *__restrict __ptr, size_t __ptrlen,
+ size_t __size, size_t __n,
+ FILE *__restrict __stream),
+ __fread_unlocked_chk)
+ __wur __warnattr ("fread_unlocked called with bigger size * nmemb than "
+ "length of destination buffer");
__extern_always_inline __wur size_t
fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
FILE *__restrict __stream)
{
- if (__bos0 (__ptr) != (size_t) -1
- && (!__builtin_constant_p (__size)
+ if (__bos0 (__ptr) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__size)
|| !__builtin_constant_p (__n)
- || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))
- || __size * __n > __bos0 (__ptr)))
- return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
+ || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)))
+ return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n,
+ __stream);
+
+ if (__size * __n > __bos0 (__ptr))
+ return __fread_unlocked_chk_warn (__ptr, __bos0 (__ptr), __size, __n,
+ __stream);
+ }
# ifdef __USE_EXTERN_INLINES
if (__builtin_constant_p (__size)
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index 26b9490bad..4650d5f74e 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -131,9 +131,18 @@
/* Fortify support. */
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
#define __bos0(ptr) __builtin_object_size (ptr, 0)
-#define __warndecl(name, msg) extern void name (void)
-#define __errordecl(name, msg) extern void name (void)
+#if __GNUC_PREREQ (4,3)
+# define __warndecl(name, msg) \
+ extern void name (void) __attribute__((__warning__ (msg)))
+# define __warnattr(msg) __attribute__((__warning__ (msg)))
+# define __errordecl(name, msg) \
+ extern void name (void) __attribute__((__error__ (msg)))
+#else
+# define __warndecl(name, msg) extern void name (void)
+# define __warnattr(msg)
+# define __errordecl(name, msg) extern void name (void)
+#endif
/* Support for flexible arrays. */
#if __GNUC_PREREQ (2,97)
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
index 331e8ea3b9..efd7f75a50 100644
--- a/posix/bits/unistd.h
+++ b/posix/bits/unistd.h
@@ -25,13 +25,23 @@ extern ssize_t __read_chk (int __fd, void *__buf, size_t __nbytes,
size_t __buflen) __wur;
extern ssize_t __REDIRECT (__read_alias, (int __fd, void *__buf,
size_t __nbytes), read) __wur;
+extern ssize_t __REDIRECT (__read_chk_warn,
+ (int __fd, void *__buf, size_t __nbytes,
+ size_t __buflen), __read_chk)
+ __wur __warnattr ("read called with bigger length than size of "
+ "the destination buffer");
__extern_always_inline __wur ssize_t
read (int __fd, void *__buf, size_t __nbytes)
{
- if (__bos0 (__buf) != (size_t) -1
- && (!__builtin_constant_p (__nbytes) || __nbytes > __bos0 (__buf)))
- return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf));
+ if (__bos0 (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__nbytes))
+ return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf));
+
+ if (__nbytes > __bos0 (__buf))
+ return __read_chk_warn (__fd, __buf, __nbytes, __bos0 (__buf));
+ }
return __read_alias (__fd, __buf, __nbytes);
}
@@ -46,23 +56,47 @@ extern ssize_t __REDIRECT (__pread_alias,
extern ssize_t __REDIRECT (__pread64_alias,
(int __fd, void *__buf, size_t __nbytes,
__off64_t __offset), pread64) __wur;
+extern ssize_t __REDIRECT (__pread_chk_warn,
+ (int __fd, void *__buf, size_t __nbytes,
+ __off_t __offset, size_t __bufsize), __pread_chk)
+ __wur __warnattr ("pread called with bigger length than size of "
+ "the destination buffer");
+extern ssize_t __REDIRECT (__pread64_chk_warn,
+ (int __fd, void *__buf, size_t __nbytes,
+ __off64_t __offset, size_t __bufsize),
+ __pread64_chk)
+ __wur __warnattr ("pread64 called with bigger length than size of "
+ "the destination buffer");
# ifndef __USE_FILE_OFFSET64
__extern_always_inline __wur ssize_t
pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset)
{
- if (__bos0 (__buf) != (size_t) -1
- && (!__builtin_constant_p (__nbytes) || __nbytes > __bos0 (__buf)))
- return __pread_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+ if (__bos0 (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__nbytes))
+ return __pread_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+ if ( __nbytes > __bos0 (__buf))
+ return __pread_chk_warn (__fd, __buf, __nbytes, __offset,
+ __bos0 (__buf));
+ }
return __pread_alias (__fd, __buf, __nbytes, __offset);
}
# else
__extern_always_inline __wur ssize_t
pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
{
- if (__bos0 (__buf) != (size_t) -1
- && (!__builtin_constant_p (__nbytes) || __nbytes > __bos0 (__buf)))
- return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+ if (__bos0 (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__nbytes))
+ return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+ if ( __nbytes > __bos0 (__buf))
+ return __pread64_chk_warn (__fd, __buf, __nbytes, __offset,
+ __bos0 (__buf));
+ }
+
return __pread64_alias (__fd, __buf, __nbytes, __offset);
}
# endif
@@ -71,9 +105,16 @@ pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
__extern_always_inline __wur ssize_t
pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
{
- if (__bos0 (__buf) != (size_t) -1
- && (!__builtin_constant_p (__nbytes) || __nbytes > __bos0 (__buf)))
- return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+ if (__bos0 (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__nbytes))
+ return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
+
+ if ( __nbytes > __bos0 (__buf))
+ return __pread64_chk_warn (__fd, __buf, __nbytes, __offset,
+ __bos0 (__buf));
+ }
+
return __pread64_alias (__fd, __buf, __nbytes, __offset);
}
# endif
@@ -88,14 +129,25 @@ extern ssize_t __REDIRECT_NTH (__readlink_alias,
(__const char *__restrict __path,
char *__restrict __buf, size_t __len), readlink)
__nonnull ((1, 2)) __wur;
+extern ssize_t __REDIRECT_NTH (__readlink_chk_warn,
+ (__const char *__restrict __path,
+ char *__restrict __buf, size_t __len,
+ size_t __buflen), __readlink_chk)
+ __nonnull ((1, 2)) __wur __warnattr ("readlink called with bigger length "
+ "than size of destination buffer");
__extern_always_inline __nonnull ((1, 2)) __wur ssize_t
__NTH (readlink (__const char *__restrict __path, char *__restrict __buf,
size_t __len))
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__len) || __len > __bos (__buf)))
- return __readlink_chk (__path, __buf, __len, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __readlink_chk (__path, __buf, __len, __bos (__buf));
+
+ if ( __len > __bos (__buf))
+ return __readlink_chk_warn (__path, __buf, __len, __bos (__buf));
+ }
return __readlink_alias (__path, __buf, __len);
}
#endif
@@ -110,14 +162,27 @@ extern ssize_t __REDIRECT_NTH (__readlinkat_alias,
char *__restrict __buf, size_t __len),
readlinkat)
__nonnull ((2, 3)) __wur;
+extern ssize_t __REDIRECT_NTH (__readlinkat_chk_warn,
+ (int __fd, __const char *__restrict __path,
+ char *__restrict __buf, size_t __len,
+ size_t __buflen), __readlinkat_chk)
+ __nonnull ((2, 3)) __wur __warnattr ("readlinkat called with bigger "
+ "length than size of destination "
+ "buffer");
__extern_always_inline __nonnull ((2, 3)) __wur ssize_t
__NTH (readlinkat (int __fd, __const char *__restrict __path,
char *__restrict __buf, size_t __len))
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__len) || __len > __bos (__buf)))
- return __readlinkat_chk (__fd, __path, __buf, __len, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __readlinkat_chk (__fd, __path, __buf, __len, __bos (__buf));
+
+ if (__len > __bos (__buf))
+ return __readlinkat_chk_warn (__fd, __path, __buf, __len,
+ __bos (__buf));
+ }
return __readlinkat_alias (__fd, __path, __buf, __len);
}
#endif
@@ -126,28 +191,39 @@ extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen)
__THROW __wur;
extern char *__REDIRECT_NTH (__getcwd_alias,
(char *__buf, size_t __size), getcwd) __wur;
+extern char *__REDIRECT_NTH (__getcwd_chk_warn,
+ (char *__buf, size_t __size, size_t __buflen),
+ __getcwd_chk)
+ __wur __warnattr ("getcwd caller with bigger length than size of "
+ "destination buffer");
__extern_always_inline __wur char *
__NTH (getcwd (char *__buf, size_t __size))
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__size) || __size > __bos (__buf)))
- return __getcwd_chk (__buf, __size, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__size))
+ return __getcwd_chk (__buf, __size, __bos (__buf));
+
+ if (__size > __bos (__buf))
+ return __getcwd_chk_warn (__buf, __size, __bos (__buf));
+ }
return __getcwd_alias (__buf, __size);
}
#if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
extern char *__getwd_chk (char *__buf, size_t buflen)
__THROW __nonnull ((1)) __wur;
-extern char *__REDIRECT_NTH (__getwd_alias, (char *__buf), getwd)
- __nonnull ((1)) __wur;
+extern char *__REDIRECT_NTH (__getwd_warn, (char *__buf), getwd)
+ __nonnull ((1)) __wur __warnattr ("please use getcwd instead, as getwd "
+ "doesn't specify buffer size");
__extern_always_inline __nonnull ((1)) __attribute_deprecated__ __wur char *
__NTH (getwd (char *__buf))
{
if (__bos (__buf) != (size_t) -1)
return __getwd_chk (__buf, __bos (__buf));
- return __getwd_alias (__buf);
+ return __getwd_warn (__buf);
}
#endif
@@ -155,29 +231,48 @@ extern size_t __confstr_chk (int __name, char *__buf, size_t __len,
size_t __buflen) __THROW;
extern size_t __REDIRECT_NTH (__confstr_alias, (int __name, char *__buf,
size_t __len), confstr);
+extern size_t __REDIRECT_NTH (__confstr_chk_warn,
+ (int __name, char *__buf, size_t __len,
+ size_t __buflen), __confstr_chk)
+ __warnattr ("confstr called with bigger length than size of destination "
+ "buffer");
__extern_always_inline size_t
__NTH (confstr (int __name, char *__buf, size_t __len))
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__len) || __bos (__buf) < __len))
- return __confstr_chk (__name, __buf, __len, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __confstr_chk (__name, __buf, __len, __bos (__buf));
+
+ if (__bos (__buf) < __len)
+ return __confstr_chk_warn (__name, __buf, __len, __bos (__buf));
+ }
return __confstr_alias (__name, __buf, __len);
}
-extern int __getgroups_chk (int __size, __gid_t __list[], size_t listlen)
+extern int __getgroups_chk (int __size, __gid_t __list[], size_t __listlen)
__THROW __wur;
extern int __REDIRECT_NTH (__getgroups_alias, (int __size, __gid_t __list[]),
getgroups) __wur;
+extern int __REDIRECT_NTH (__getgroups_chk_warn,
+ (int __size, __gid_t __list[], size_t __listlen),
+ __getgroups_chk)
+ __wur __warnattr ("getgroups called with bigger group count than what "
+ "can fit into destination buffer");
__extern_always_inline int
__NTH (getgroups (int __size, __gid_t __list[]))
{
- if (__bos (__list) != (size_t) -1
- && (!__builtin_constant_p (__size)
- || __size * sizeof (__gid_t) > __bos (__list)))
- return __getgroups_chk (__size, __list, __bos (__list));
+ if (__bos (__list) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__size))
+ return __getgroups_chk (__size, __list, __bos (__list));
+
+ if (__size * sizeof (__gid_t) > __bos (__list))
+ return __getgroups_chk_warn (__size, __list, __bos (__list));
+ }
return __getgroups_alias (__size, __list);
}
@@ -187,13 +282,23 @@ extern int __ttyname_r_chk (int __fd, char *__buf, size_t __buflen,
extern int __REDIRECT_NTH (__ttyname_r_alias, (int __fd, char *__buf,
size_t __buflen), ttyname_r)
__nonnull ((2));
+extern int __REDIRECT_NTH (__ttyname_r_chk_warn,
+ (int __fd, char *__buf, size_t __buflen,
+ size_t __nreal), __ttyname_r_chk)
+ __nonnull ((2)) __warnattr ("ttyname_r called with bigger buflen than "
+ "size of destination buffer");
__extern_always_inline int
__NTH (ttyname_r (int __fd, char *__buf, size_t __buflen))
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
- return __ttyname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__buflen))
+ return __ttyname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+
+ if (__buflen > __bos (__buf))
+ return __ttyname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf));
+ }
return __ttyname_r_alias (__fd, __buf, __buflen);
}
@@ -203,13 +308,23 @@ extern int __getlogin_r_chk (char *__buf, size_t __buflen, size_t __nreal)
__nonnull ((1));
extern int __REDIRECT (__getlogin_r_alias, (char *__buf, size_t __buflen),
getlogin_r) __nonnull ((1));
+extern int __REDIRECT (__getlogin_r_chk_warn,
+ (char *__buf, size_t __buflen, size_t __nreal),
+ __getlogin_r_chk)
+ __nonnull ((1)) __warnattr ("getlogin_r called with bigger buflen than "
+ "size of destination buffer");
__extern_always_inline int
getlogin_r (char *__buf, size_t __buflen)
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
- return __getlogin_r_chk (__buf, __buflen, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__buflen))
+ return __getlogin_r_chk (__buf, __buflen, __bos (__buf));
+
+ if (__buflen > __bos (__buf))
+ return __getlogin_r_chk_warn (__buf, __buflen, __bos (__buf));
+ }
return __getlogin_r_alias (__buf, __buflen);
}
#endif
@@ -220,13 +335,23 @@ extern int __gethostname_chk (char *__buf, size_t __buflen, size_t __nreal)
__THROW __nonnull ((1));
extern int __REDIRECT_NTH (__gethostname_alias, (char *__buf, size_t __buflen),
gethostname) __nonnull ((1));
+extern int __REDIRECT_NTH (__gethostname_chk_warn,
+ (char *__buf, size_t __buflen, size_t __nreal),
+ __gethostname_chk)
+ __nonnull ((1)) __warnattr ("gethostname called with bigger buflen than "
+ "size of destination buffer");
__extern_always_inline int
__NTH (gethostname (char *__buf, size_t __buflen))
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
- return __gethostname_chk (__buf, __buflen, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__buflen))
+ return __gethostname_chk (__buf, __buflen, __bos (__buf));
+
+ if (__buflen > __bos (__buf))
+ return __gethostname_chk_warn (__buf, __buflen, __bos (__buf));
+ }
return __gethostname_alias (__buf, __buflen);
}
#endif
@@ -238,13 +363,24 @@ extern int __getdomainname_chk (char *__buf, size_t __buflen, size_t __nreal)
extern int __REDIRECT_NTH (__getdomainname_alias, (char *__buf,
size_t __buflen),
getdomainname) __nonnull ((1)) __wur;
+extern int __REDIRECT_NTH (__getdomainname_chk_warn,
+ (char *__buf, size_t __buflen, size_t __nreal),
+ __getdomainname_chk)
+ __nonnull ((1)) __wur __warnattr ("getdomainname called with bigger "
+ "buflen than size of destination "
+ "buffer");
__extern_always_inline int
__NTH (getdomainname (char *__buf, size_t __buflen))
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
- return __getdomainname_chk (__buf, __buflen, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__buflen))
+ return __getdomainname_chk (__buf, __buflen, __bos (__buf));
+
+ if (__buflen > __bos (__buf))
+ return __getdomainname_chk_warn (__buf, __buflen, __bos (__buf));
+ }
return __getdomainname_alias (__buf, __buflen);
}
#endif
diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h
index 9fac75669c..5c4cb47a6d 100644
--- a/socket/bits/socket2.h
+++ b/socket/bits/socket2.h
@@ -25,13 +25,23 @@ extern ssize_t __recv_chk (int __fd, void *__buf, size_t __n, size_t __buflen,
int __flags);
extern ssize_t __REDIRECT (__recv_alias, (int __fd, void *__buf, size_t __n,
int __flags), recv);
+extern ssize_t __REDIRECT (__recv_chk_warn,
+ (int __fd, void *__buf, size_t __n, size_t __buflen,
+ int __flags), __recv_chk)
+ __warnattr ("recv called with bigger length than size of destination "
+ "buffer");
__extern_always_inline ssize_t
recv (int __fd, void *__buf, size_t __n, int __flags)
{
- if (__bos0 (__buf) != (size_t) -1
- && (!__builtin_constant_p (__n) || __n > __bos0 (__buf)))
- return __recv_chk (__fd, __buf, __n, __bos0 (__buf), __flags);
+ if (__bos0 (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__n))
+ return __recv_chk (__fd, __buf, __n, __bos0 (__buf), __flags);
+
+ if (__n > __bos0 (__buf))
+ return __recv_chk_warn (__fd, __buf, __n, __bos0 (__buf), __flags);
+ }
return __recv_alias (__fd, __buf, __n, __flags);
}
@@ -43,14 +53,26 @@ extern ssize_t __REDIRECT (__recvfrom_alias,
(int __fd, void *__restrict __buf, size_t __n,
int __flags, __SOCKADDR_ARG __addr,
socklen_t *__restrict __addr_len), recvfrom);
+extern ssize_t __REDIRECT (__recvfrom_chk_warn,
+ (int __fd, void *__restrict __buf, size_t __n,
+ size_t __buflen, int __flags,
+ __SOCKADDR_ARG __addr,
+ socklen_t *__restrict __addr_len), __recvfrom_chk)
+ __warnattr ("recvfrom called with bigger length than size of "
+ "destination buffer");
__extern_always_inline ssize_t
recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags,
__SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len)
{
- if (__bos0 (__buf) != (size_t) -1
- && (!__builtin_constant_p (__n) || __n > __bos0 (__buf)))
- return __recvfrom_chk (__fd, __buf, __n, __bos0 (__buf), __flags,
- __addr, __addr_len);
+ if (__bos0 (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__n))
+ return __recvfrom_chk (__fd, __buf, __n, __bos0 (__buf), __flags,
+ __addr, __addr_len);
+ if (__n > __bos0 (__buf))
+ return __recvfrom_chk_warn (__fd, __buf, __n, __bos0 (__buf), __flags,
+ __addr, __addr_len);
+ }
return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len);
}
diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
index 7ee7bf5587..f6af5e518c 100644
--- a/stdlib/bits/stdlib.h
+++ b/stdlib/bits/stdlib.h
@@ -27,12 +27,24 @@ extern char *__realpath_chk (__const char *__restrict __name,
extern char *__REDIRECT_NTH (__realpath_alias,
(__const char *__restrict __name,
char *__restrict __resolved), realpath) __wur;
+extern char *__REDIRECT_NTH (__realpath_chk_warn,
+ (__const char *__restrict __name,
+ char *__restrict __resolved,
+ size_t __resolvedlen), __realpath_chk) __wur
+ __warnattr ("second argument of realpath must be either NULL or at "
+ "least PATH_MAX bytes long buffer");
__extern_always_inline __wur char *
__NTH (realpath (__const char *__restrict __name, char *__restrict __resolved))
{
if (__bos (__resolved) != (size_t) -1)
- return __realpath_chk (__name, __resolved, __bos (__resolved));
+ {
+#if defined _LIBC_LIMITS_H_ && defined PATH_MAX
+ if (__bos (__resolved) < PATH_MAX)
+ return __realpath_chk_warn (__name, __resolved, __bos (__resolved));
+#endif
+ return __realpath_chk (__name, __resolved, __bos (__resolved));
+ }
return __realpath_alias (__name, __resolved);
}
@@ -43,13 +55,22 @@ extern int __ptsname_r_chk (int __fd, char *__buf, size_t __buflen,
extern int __REDIRECT_NTH (__ptsname_r_alias, (int __fd, char *__buf,
size_t __buflen), ptsname_r)
__nonnull ((2));
+extern int __REDIRECT_NTH (__ptsname_r_chk_warn,
+ (int __fd, char *__buf, size_t __buflen,
+ size_t __nreal), __ptsname_r_chk)
+ __nonnull ((2)) __warnattr ("ptsname_r called with buflen bigger than "
+ "size of buf");
__extern_always_inline int
__NTH (ptsname_r (int __fd, char *__buf, size_t __buflen))
{
- if (__bos (__buf) != (size_t) -1
- && (!__builtin_constant_p (__buflen) || __buflen > __bos (__buf)))
- return __ptsname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+ if (__bos (__buf) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__buflen))
+ return __ptsname_r_chk (__fd, __buf, __buflen, __bos (__buf));
+ if (__buflen > __bos (__buf))
+ return __ptsname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf));
+ }
return __ptsname_r_alias (__fd, __buf, __buflen);
}
@@ -82,16 +103,27 @@ extern size_t __REDIRECT_NTH (__mbstowcs_alias,
(wchar_t *__restrict __dst,
__const char *__restrict __src,
size_t __len), mbstowcs);
+extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn,
+ (wchar_t *__restrict __dst,
+ __const char *__restrict __src,
+ size_t __len, size_t __dstlen), __mbstowcs_chk)
+ __warnattr ("mbstowcs called with dst buffer smaller than len "
+ "* sizeof (wchar_t)");
__extern_always_inline size_t
__NTH (mbstowcs (wchar_t *__restrict __dst, __const char *__restrict __src,
size_t __len))
{
- if (__bos (__dst) != (size_t) -1
- && (!__builtin_constant_p (__len)
- || __len > __bos (__dst) / sizeof (wchar_t)))
- return __mbstowcs_chk (__dst, __src, __len,
- __bos (__dst) / sizeof (wchar_t));
+ if (__bos (__dst) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __mbstowcs_chk (__dst, __src, __len,
+ __bos (__dst) / sizeof (wchar_t));
+
+ if (__len > __bos (__dst) / sizeof (wchar_t))
+ return __mbstowcs_chk_warn (__dst, __src, __len,
+ __bos (__dst) / sizeof (wchar_t));
+ }
return __mbstowcs_alias (__dst, __src, __len);
}
@@ -103,13 +135,22 @@ extern size_t __REDIRECT_NTH (__wcstombs_alias,
(char *__restrict __dst,
__const wchar_t *__restrict __src,
size_t __len), wcstombs);
+extern size_t __REDIRECT_NTH (__wcstombs_chk_warn,
+ (char *__restrict __dst,
+ __const wchar_t *__restrict __src,
+ size_t __len, size_t __dstlen), __wcstombs_chk)
+ __warnattr ("wcstombs called with dst buffer smaller than len");
__extern_always_inline size_t
__NTH (wcstombs (char *__restrict __dst, __const wchar_t *__restrict __src,
size_t __len))
{
- if (__bos (__dst) != (size_t) -1
- && (!__builtin_constant_p (__len) || __len > __bos (__dst)))
- return __wcstombs_chk (__dst, __src, __len, __bos (__dst));
+ if (__bos (__dst) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __wcstombs_chk (__dst, __src, __len, __bos (__dst));
+ if (__len > __bos (__dst))
+ return __wcstombs_chk_warn (__dst, __src, __len, __bos (__dst));
+ }
return __wcstombs_alias (__dst, __src, __len);
}
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
index e1b7c13023..0c940d7221 100644
--- a/wcsmbs/bits/wchar2.h
+++ b/wcsmbs/bits/wchar2.h
@@ -29,13 +29,27 @@ extern wchar_t *__REDIRECT_NTH (__wmemcpy_alias,
(wchar_t *__restrict __s1,
__const wchar_t *__restrict __s2, size_t __n),
wmemcpy);
+extern wchar_t *__REDIRECT_NTH (__wmemcpy_chk_warn,
+ (wchar_t *__restrict __s1,
+ __const wchar_t *__restrict __s2, size_t __n,
+ size_t __ns1), __wmemcpy_chk)
+ __warnattr ("wmemcpy called with length bigger than size of destination "
+ "buffer");
__extern_always_inline wchar_t *
__NTH (wmemcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
size_t __n))
{
if (__bos0 (__s1) != (size_t) -1)
- return __wmemcpy_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+ {
+ if (!__builtin_constant_p (__n))
+ return __wmemcpy_chk (__s1, __s2, __n,
+ __bos0 (__s1) / sizeof (wchar_t));
+
+ if (__n > __bos0 (__s1) / sizeof (wchar_t))
+ return __wmemcpy_chk_warn (__s1, __s2, __n,
+ __bos0 (__s1) / sizeof (wchar_t));
+ }
return __wmemcpy_alias (__s1, __s2, __n);
}
@@ -45,13 +59,27 @@ extern wchar_t *__wmemmove_chk (wchar_t *__s1, __const wchar_t *__s2,
extern wchar_t *__REDIRECT_NTH (__wmemmove_alias, (wchar_t *__s1,
__const wchar_t *__s2,
size_t __n), wmemmove);
+extern wchar_t *__REDIRECT_NTH (__wmemmove_chk_warn,
+ (wchar_t *__restrict __s1,
+ __const wchar_t *__restrict __s2, size_t __n,
+ size_t __ns1), __wmemmove_chk)
+ __warnattr ("wmemmove called with length bigger than size of destination "
+ "buffer");
__extern_always_inline wchar_t *
__NTH (wmemmove (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
size_t __n))
{
if (__bos0 (__s1) != (size_t) -1)
- return __wmemmove_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+ {
+ if (!__builtin_constant_p (__n))
+ return __wmemmove_chk (__s1, __s2, __n,
+ __bos0 (__s1) / sizeof (wchar_t));
+
+ if (__n > __bos0 (__s1) / sizeof (wchar_t))
+ return __wmemmove_chk_warn (__s1, __s2, __n,
+ __bos0 (__s1) / sizeof (wchar_t));
+ }
return __wmemmove_alias (__s1, __s2, __n);
}
@@ -64,13 +92,27 @@ extern wchar_t *__REDIRECT_NTH (__wmempcpy_alias,
(wchar_t *__restrict __s1,
__const wchar_t *__restrict __s2,
size_t __n), wmempcpy);
+extern wchar_t *__REDIRECT_NTH (__wmempcpy_chk_warn,
+ (wchar_t *__restrict __s1,
+ __const wchar_t *__restrict __s2, size_t __n,
+ size_t __ns1), __wmempcpy_chk)
+ __warnattr ("wmempcpy called with length bigger than size of destination "
+ "buffer");
__extern_always_inline wchar_t *
__NTH (wmempcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
size_t __n))
{
if (__bos0 (__s1) != (size_t) -1)
- return __wmempcpy_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+ {
+ if (!__builtin_constant_p (__n))
+ return __wmempcpy_chk (__s1, __s2, __n,
+ __bos0 (__s1) / sizeof (wchar_t));
+
+ if (__n > __bos0 (__s1) / sizeof (wchar_t))
+ return __wmempcpy_chk_warn (__s1, __s2, __n,
+ __bos0 (__s1) / sizeof (wchar_t));
+ }
return __wmempcpy_alias (__s1, __s2, __n);
}
#endif
@@ -80,12 +122,24 @@ extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
size_t __ns) __THROW;
extern wchar_t *__REDIRECT_NTH (__wmemset_alias, (wchar_t *__s, wchar_t __c,
size_t __n), wmemset);
+extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn,
+ (wchar_t *__s, wchar_t __c, size_t __n,
+ size_t __ns), __wmemset_chk)
+ __warnattr ("wmemset called with length bigger than size of destination "
+ "buffer");
__extern_always_inline wchar_t *
__NTH (wmemset (wchar_t *__restrict __s, wchar_t __c, size_t __n))
{
if (__bos0 (__s) != (size_t) -1)
- return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t));
+ {
+ if (!__builtin_constant_p (__n))
+ return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t));
+
+ if (__n > __bos0 (__s) / sizeof (wchar_t))
+ return __wmemset_chk_warn (__s, __c, __n,
+ __bos0 (__s) / sizeof (wchar_t));
+ }
return __wmemset_alias (__s, __c, __n);
}
@@ -128,14 +182,25 @@ extern wchar_t *__REDIRECT_NTH (__wcsncpy_alias,
(wchar_t *__restrict __dest,
__const wchar_t *__restrict __src,
size_t __n), wcsncpy);
+extern wchar_t *__REDIRECT_NTH (__wcsncpy_chk_warn,
+ (wchar_t *__restrict __dest,
+ __const wchar_t *__restrict __src,
+ size_t __n, size_t __destlen), __wcsncpy_chk)
+ __warnattr ("wcsncpy called with length bigger than size of destination "
+ "buffer");
__extern_always_inline wchar_t *
__NTH (wcsncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n))
{
- if (__bos (__dest) != (size_t) -1
- && (!__builtin_constant_p (__n) || __bos (__dest) >= __n))
- return __wcsncpy_chk (__dest, __src, __n,
- __bos (__dest) / sizeof (wchar_t));
+ if (__bos (__dest) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__n))
+ return __wcsncpy_chk (__dest, __src, __n,
+ __bos (__dest) / sizeof (wchar_t));
+ if (__n > __bos (__dest) / sizeof (wchar_t))
+ return __wcsncpy_chk_warn (__dest, __src, __n,
+ __bos (__dest) / sizeof (wchar_t));
+ }
return __wcsncpy_alias (__dest, __src, __n);
}
@@ -147,14 +212,25 @@ extern wchar_t *__REDIRECT_NTH (__wcpncpy_alias,
(wchar_t *__restrict __dest,
__const wchar_t *__restrict __src,
size_t __n), wcpncpy);
+extern wchar_t *__REDIRECT_NTH (__wcpncpy_chk_warn,
+ (wchar_t *__restrict __dest,
+ __const wchar_t *__restrict __src,
+ size_t __n, size_t __destlen), __wcpncpy_chk)
+ __warnattr ("wcpncpy called with length bigger than size of destination "
+ "buffer");
__extern_always_inline wchar_t *
__NTH (wcpncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n))
{
- if (__bos (__dest) != (size_t) -1
- && (!__builtin_constant_p (__n) || __bos (__dest) >= __n))
- return __wcpncpy_chk (__dest, __src, __n,
- __bos (__dest) / sizeof (wchar_t));
+ if (__bos (__dest) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__n))
+ return __wcpncpy_chk (__dest, __src, __n,
+ __bos (__dest) / sizeof (wchar_t));
+ if (__n > __bos (__dest) / sizeof (wchar_t))
+ return __wcpncpy_chk_warn (__dest, __src, __n,
+ __bos (__dest) / sizeof (wchar_t));
+ }
return __wcpncpy_alias (__dest, __src, __n);
}
@@ -209,7 +285,8 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
__const wchar_t *__restrict __fmt, ...))
{
if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
- return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s),
+ return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+ __bos (__s) / sizeof (wchar_t),
__fmt, __va_arg_pack ());
return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
}
@@ -217,7 +294,8 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
/* XXX We might want to have support in gcc for swprintf. */
# define swprintf(s, n, ...) \
(__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \
- ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), __VA_ARGS__) \
+ ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, \
+ __bos (s) / sizeof (wchar_t), __VA_ARGS__) \
: swprintf (s, n, __VA_ARGS__))
#endif
@@ -237,8 +315,8 @@ __NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
__const wchar_t *__restrict __fmt, __gnuc_va_list __ap))
{
if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
- return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s),
- __fmt, __ap);
+ return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+ __bos (__s) / sizeof (wchar_t), __fmt, __ap);
return __vswprintf_alias (__s, __n, __fmt, __ap);
}
@@ -295,13 +373,25 @@ extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
extern wchar_t *__REDIRECT (__fgetws_alias,
(wchar_t *__restrict __s, int __n,
__FILE *__restrict __stream), fgetws) __wur;
+extern wchar_t *__REDIRECT (__fgetws_chk_warn,
+ (wchar_t *__restrict __s, size_t __size, int __n,
+ __FILE *__restrict __stream), __fgetws_chk)
+ __wur __warnattr ("fgetws called with bigger size than length "
+ "of destination buffer");
__extern_always_inline __wur wchar_t *
fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
{
- if (__bos (__s) != (size_t) -1
- && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
- return __fgetws_chk (__s, __bos (__s), __n, __stream);
+ if (__bos (__s) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__n) || __n <= 0)
+ return __fgetws_chk (__s, __bos (__s) / sizeof (wchar_t),
+ __n, __stream);
+
+ if ((size_t) __n > __bos (__s) / sizeof (wchar_t))
+ return __fgetws_chk_warn (__s, __bos (__s) / sizeof (wchar_t),
+ __n, __stream);
+ }
return __fgetws_alias (__s, __n, __stream);
}
@@ -313,13 +403,26 @@ extern wchar_t *__REDIRECT (__fgetws_unlocked_alias,
(wchar_t *__restrict __s, int __n,
__FILE *__restrict __stream), fgetws_unlocked)
__wur;
+extern wchar_t *__REDIRECT (__fgetws_unlocked_chk_warn,
+ (wchar_t *__restrict __s, size_t __size, int __n,
+ __FILE *__restrict __stream),
+ __fgetws_unlocked_chk)
+ __wur __warnattr ("fgetws_unlocked called with bigger size than length "
+ "of destination buffer");
__extern_always_inline __wur wchar_t *
fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
{
- if (__bos (__s) != (size_t) -1
- && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
- return __fgetws_unlocked_chk (__s, __bos (__s), __n, __stream);
+ if (__bos (__s) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__n) || __n <= 0)
+ return __fgetws_unlocked_chk (__s, __bos (__s) / sizeof (wchar_t),
+ __n, __stream);
+
+ if ((size_t) __n > __bos (__s) / sizeof (wchar_t))
+ return __fgetws_unlocked_chk_warn (__s, __bos (__s) / sizeof (wchar_t),
+ __n, __stream);
+ }
return __fgetws_unlocked_alias (__s, __n, __stream);
}
#endif
@@ -356,16 +459,28 @@ extern size_t __REDIRECT_NTH (__mbsrtowcs_alias,
__const char **__restrict __src,
size_t __len, mbstate_t *__restrict __ps),
mbsrtowcs);
+extern size_t __REDIRECT_NTH (__mbsrtowcs_chk_warn,
+ (wchar_t *__restrict __dst,
+ __const char **__restrict __src,
+ size_t __len, mbstate_t *__restrict __ps,
+ size_t __dstlen), __mbsrtowcs_chk)
+ __warnattr ("mbsrtowcs called with dst buffer smaller than len "
+ "* sizeof (wchar_t)");
__extern_always_inline size_t
__NTH (mbsrtowcs (wchar_t *__restrict __dst, __const char **__restrict __src,
size_t __len, mbstate_t *__restrict __ps))
{
- if (__bos (__dst) != (size_t) -1
- && (!__builtin_constant_p (__len)
- || __len > __bos (__dst) / sizeof (wchar_t)))
- return __mbsrtowcs_chk (__dst, __src, __len, __ps,
- __bos (__dst) / sizeof (wchar_t));
+ if (__bos (__dst) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __mbsrtowcs_chk (__dst, __src, __len, __ps,
+ __bos (__dst) / sizeof (wchar_t));
+
+ if (__len > __bos (__dst) / sizeof (wchar_t))
+ return __mbsrtowcs_chk_warn (__dst, __src, __len, __ps,
+ __bos (__dst) / sizeof (wchar_t));
+ }
return __mbsrtowcs_alias (__dst, __src, __len, __ps);
}
@@ -379,14 +494,25 @@ extern size_t __REDIRECT_NTH (__wcsrtombs_alias,
__const wchar_t **__restrict __src,
size_t __len, mbstate_t *__restrict __ps),
wcsrtombs);
+extern size_t __REDIRECT_NTH (__wcsrtombs_chk_warn,
+ (char *__restrict __dst,
+ __const wchar_t **__restrict __src,
+ size_t __len, mbstate_t *__restrict __ps,
+ size_t __dstlen), __wcsrtombs_chk)
+ __warnattr ("wcsrtombs called with dst buffer smaller than len");
__extern_always_inline size_t
__NTH (wcsrtombs (char *__restrict __dst, __const wchar_t **__restrict __src,
size_t __len, mbstate_t *__restrict __ps))
{
- if (__bos (__dst) != (size_t) -1
- && (!__builtin_constant_p (__len) || __len > __bos (__dst)))
- return __wcsrtombs_chk (__dst, __src, __len, __ps, __bos (__dst));
+ if (__bos (__dst) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __wcsrtombs_chk (__dst, __src, __len, __ps, __bos (__dst));
+
+ if (__len > __bos (__dst))
+ return __wcsrtombs_chk_warn (__dst, __src, __len, __ps, __bos (__dst));
+ }
return __wcsrtombs_alias (__dst, __src, __len, __ps);
}
@@ -401,16 +527,28 @@ extern size_t __REDIRECT_NTH (__mbsnrtowcs_alias,
__const char **__restrict __src, size_t __nmc,
size_t __len, mbstate_t *__restrict __ps),
mbsnrtowcs);
+extern size_t __REDIRECT_NTH (__mbsnrtowcs_chk_warn,
+ (wchar_t *__restrict __dst,
+ __const char **__restrict __src, size_t __nmc,
+ size_t __len, mbstate_t *__restrict __ps,
+ size_t __dstlen), __mbsnrtowcs_chk)
+ __warnattr ("mbsnrtowcs called with dst buffer smaller than len "
+ "* sizeof (wchar_t)");
__extern_always_inline size_t
__NTH (mbsnrtowcs (wchar_t *__restrict __dst, __const char **__restrict __src,
size_t __nmc, size_t __len, mbstate_t *__restrict __ps))
{
- if (__bos (__dst) != (size_t) -1
- && (!__builtin_constant_p (__len)
- || __len > __bos (__dst) / sizeof (wchar_t)))
- return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps,
- __bos (__dst) / sizeof (wchar_t));
+ if (__bos (__dst) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps,
+ __bos (__dst) / sizeof (wchar_t));
+
+ if (__len > __bos (__dst) / sizeof (wchar_t))
+ return __mbsnrtowcs_chk_warn (__dst, __src, __nmc, __len, __ps,
+ __bos (__dst) / sizeof (wchar_t));
+ }
return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps);
}
@@ -425,14 +563,28 @@ extern size_t __REDIRECT_NTH (__wcsnrtombs_alias,
__const wchar_t **__restrict __src,
size_t __nwc, size_t __len,
mbstate_t *__restrict __ps), wcsnrtombs);
+extern size_t __REDIRECT_NTH (__wcsnrtombs_chk_warn,
+ (char *__restrict __dst,
+ __const wchar_t **__restrict __src,
+ size_t __nwc, size_t __len,
+ mbstate_t *__restrict __ps,
+ size_t __dstlen), __wcsnrtombs_chk)
+ __warnattr ("wcsnrtombs called with dst buffer smaller than len");
__extern_always_inline size_t
__NTH (wcsnrtombs (char *__restrict __dst, __const wchar_t **__restrict __src,
size_t __nwc, size_t __len, mbstate_t *__restrict __ps))
{
- if (__bos (__dst) != (size_t) -1
- && (!__builtin_constant_p (__len) || __len > __bos (__dst)))
- return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps, __bos (__dst));
+ if (__bos (__dst) != (size_t) -1)
+ {
+ if (!__builtin_constant_p (__len))
+ return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps,
+ __bos (__dst));
+
+ if (__len > __bos (__dst))
+ return __wcsnrtombs_chk_warn (__dst, __src, __nwc, __len, __ps,
+ __bos (__dst));
+ }
return __wcsnrtombs_alias (__dst, __src, __nwc, __len, __ps);
}
#endif