summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/testsuite/gcc.dg/asan/snprintf-fortify-1.c29
-rw-r--r--gcc/testsuite/gcc.dg/asan/sprintf-fortify-1.c29
-rw-r--r--gcc/testsuite/gcc.dg/asan/vsnprintf-fortify-1.c38
-rw-r--r--gcc/testsuite/gcc.dg/asan/vsprintf-fortify-1.c37
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc42
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h3
6 files changed, 178 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/asan/snprintf-fortify-1.c b/gcc/testsuite/gcc.dg/asan/snprintf-fortify-1.c
new file mode 100644
index 00000000000..b5e1a6e5101
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/snprintf-fortify-1.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-options "-D_FORTIFY_SOURCE=1 -w" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O1" } } */
+/* { dg-shouldfail "asan" } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *
+__asan_default_options () {
+ return "fast_unwind_on_malloc=false";
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+int main(int argc, char **argv) {
+ char *short_buffer = (char*)malloc(3);
+ snprintf (short_buffer, 10, "%s_%s", "hello", "world"); /* BOOM */
+ return short_buffer[0];
+}
+/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)__snprintf_chk|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+
diff --git a/gcc/testsuite/gcc.dg/asan/sprintf-fortify-1.c b/gcc/testsuite/gcc.dg/asan/sprintf-fortify-1.c
new file mode 100644
index 00000000000..86fed28e373
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/sprintf-fortify-1.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-options "-D_FORTIFY_SOURCE=1 -w" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O1" } } */
+/* { dg-shouldfail "asan" } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *
+__asan_default_options () {
+ return "fast_unwind_on_malloc=false";
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+int main(int argc, char **argv) {
+ char *short_buffer = (char*)malloc(3);
+ sprintf (short_buffer, "%s_%s", "hello", "world"); /* BOOM */
+ return short_buffer[0];
+}
+/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)__sprintf_chk|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+
diff --git a/gcc/testsuite/gcc.dg/asan/vsnprintf-fortify-1.c b/gcc/testsuite/gcc.dg/asan/vsnprintf-fortify-1.c
new file mode 100644
index 00000000000..711c31f84e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/vsnprintf-fortify-1.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-D_FORTIFY_SOURCE=1 -w" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O1" } } */
+/* { dg-shouldfail "asan" } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *
+__asan_default_options () {
+ return "fast_unwind_on_malloc=false";
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+__attribute__((noinline, noclone))
+char foo (const char *format, ...) {
+ char *str = (char *) malloc (1);
+ va_list ap;
+ va_start (ap, format);
+ vsnprintf (str, 10, format, ap);
+ va_end (ap);
+ return str[1];
+}
+
+int main(int argc, char **argv) {
+ return foo ("%s_%s", "hello", "world");
+}
+/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)__vsnprintf_chk|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+
diff --git a/gcc/testsuite/gcc.dg/asan/vsprintf-fortify-1.c b/gcc/testsuite/gcc.dg/asan/vsprintf-fortify-1.c
new file mode 100644
index 00000000000..d14f38fff75
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/vsprintf-fortify-1.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-options "-D_FORTIFY_SOURCE=1 -w" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O1" } } */
+/* { dg-shouldfail "asan" } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *
+__asan_default_options () {
+ return "fast_unwind_on_malloc=false";
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+char foo (const char *format, ...) {
+ char *str = (char *) malloc (1);
+ va_list ap;
+ va_start (ap, format);
+ vsprintf (str, format, ap);
+ va_end (ap);
+ return str[1];
+}
+
+int main(int argc, char **argv) {
+ return foo ("%s_%s", "hello", "world");
+}
+/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)__vsprintf_chk|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
index 38390ed9621..d3059f0c2f7 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1331,6 +1331,12 @@ INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
va_list ap)
VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
+#if SANITIZER_INTERCEPT___PRINTF_CHK
+INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag,
+ SIZE_T size_to, const char *format, va_list ap)
+VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
+#endif
+
#if SANITIZER_INTERCEPT_PRINTF_L
INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
const char *format, va_list ap)
@@ -1344,6 +1350,12 @@ FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
+#if SANITIZER_INTERCEPT___PRINTF_CHK
+INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
+ const char *format, va_list ap)
+VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
+#endif
+
INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
@@ -1372,12 +1384,30 @@ FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
+#if SANITIZER_INTERCEPT___PRINTF_CHK
+INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size,
+ const char *format, ...)
+FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format)
+#endif
+
INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
+#if SANITIZER_INTERCEPT___PRINTF_CHK
+INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to,
+ const char *format, ...) // NOLINT
+FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) // NOLINT
+#endif
+
INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
+#if SANITIZER_INTERCEPT___PRINTF_CHK
+INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
+ SIZE_T size_to, const char *format, ...) // NOLINT
+FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) // NOLINT
+#endif
+
INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
@@ -1417,6 +1447,17 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
#define INIT_PRINTF
#endif
+#if SANITIZER_INTERCEPT___PRINTF_CHK
+#define INIT___PRINTF_CHK \
+ COMMON_INTERCEPT_FUNCTION(__sprintf_chk); \
+ COMMON_INTERCEPT_FUNCTION(__snprintf_chk); \
+ COMMON_INTERCEPT_FUNCTION(__vsprintf_chk); \
+ COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \
+ COMMON_INTERCEPT_FUNCTION(__fprintf_chk);
+#else
+#define INIT___PRINTF_CHK
+#endif
+
#if SANITIZER_INTERCEPT_PRINTF_L
#define INIT_PRINTF_L \
COMMON_INTERCEPT_FUNCTION(snprintf_l); \
@@ -6072,4 +6113,5 @@ static void InitializeCommonInterceptors() {
INIT___LXSTAT;
INIT___LXSTAT64;
// FIXME: add other *stat interceptors.
+ INIT___PRINTF_CHK;
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
index 2a886058187..db1668e4773 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
@@ -116,6 +116,9 @@
# define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_LINUX_NOT_ANDROID
#endif
+#define SANITIZER_INTERCEPT___PRINTF_CHK \
+ (SANITIZER_INTERCEPT_PRINTF && SI_LINUX_NOT_ANDROID)
+
#define SANITIZER_INTERCEPT_FREXP 1
#define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_NOT_WINDOWS