From: Maxim Ostapenko <m.ostapenko@samsung.com>
To: GNU C Library <libc-alpha@sourceware.org>
Cc: Florian Weimer <fweimer@redhat.com>,
Kostya Serebryany <kcc@google.com>,
Yuri Gribov <tetra2005@gmail.com>
Subject: [PATCH BZ#20422] Do not allow asan/msan/tsan and fortify at the same time.
Date: Mon, 05 Sep 2016 17:27:00 -0000 [thread overview]
Message-ID: <57CDAB08.8060601@samsung.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 3395 bytes --]
Hi!
When fortify is used with MSan it will cause MSan false positives.
#include <stdio.h>
#include <string.h>
int main()
{
char text[100];
sprintf(text, "hello");
printf("%lu\n", strlen(text));
}
% clang test.c -fsanitize=memory -O3 && ./a.out
5
% clang test.c -fsanitize=memory -D_FORTIFY_SOURCE=2 -O3 && ./a.out
Uninitialized bytes in __interceptor_strlen at offset 0 inside
[0x7ffe259e4d20, 6)
==26297==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x4869cc in main
With ASan, this will not cause false positives, but may case false
negatives or just confuse people with "wrong" reports when fortify
catches the error.
Although fortify is good thing as it (and it's enabled by default on
some major distros e.g. Ubuntu and Gentoo), people still complain about
{A, M}San vs fortify interaction, see e.g.
https://github.com/google/sanitizers/issues/689. One possible solution
would be to extend {A, M}San to support foo_chk() functions, but this
would increase the complexity of sanitizer tools with quite small
benefit. Another choice would be to warn users when they compile their
code with {A, M, T}San and fortify enabled.
This patch implements the second approach. The simplest way to warn is
to modify the Glibc headers to check if fortify and one of the
sanitizers is enabled. Does this look reasonable?
I've tried to add a testcase for new warning into Glibc testsuite, but
failed to see how exactly I can do it. Does Glibc have some framework
for compilation tests? Could someone help me with this issue?
For now, I've tested this patch locally with GCC 4.8, fresh GCC and
fresh Clang on my Ubuntu box:
gcc test.c -fsanitize=address -D_FORTIFY_SOURCE=2 -O3
-L${SYSROOT}/usr/lib -I${SYSROOT}/include -Wl,-rpath=${SYSROOT}/lib
-Wl,--dynamic-linker=${SYSROOT}/lib/ld-2.24.90.so -S
In file included from
/home/max/install/glibc//include/bits/libc-header-start.h:33:0,
from /home/max/install/glibc//include/stdio.h:28,
from test.c:1:
/home/max/install/glibc//include/features.h:374:3: warning: #warning
_FORTIFY_SOURCE is not compatible with sanitizer [-Wcpp]
# warning _FORTIFY_SOURCE is not compatible with sanitizer
~/install/master/bin/gcc test.c -fsanitize=address -D_FORTIFY_SOURCE=2
-O3 -L${SYSROOT}/usr/lib -I${SYSROOT}/include -Wl,-rpath=${SYSROOT}/lib
-Wl,--dynamic-linker=${SYSROOT}/lib/ld-2.24.90.so -S
In file included from
/home/max/install/glibc//include/bits/libc-header-start.h:33:0,
from /home/max/install/glibc//include/stdio.h:28,
from test.c:1:
/home/max/install/glibc//include/features.h:374:3: warning: #warning
_FORTIFY_SOURCE is not compatible with sanitizer [-Wcpp]
# warning _FORTIFY_SOURCE is not compatible with sanitizer
clang test.c -fsanitize=address -D_FORTIFY_SOURCE=2 -O3
-L${SYSROOT}/usr/lib -I${SYSROOT}/include -Wl,-rpath=${SYSROOT}/lib
-Wl,--dynamic-linker=${SYSROOT}/lib/ld-2.24.90.so
In file included from test.c:1:
In file included from /home/max/install/glibc//include/stdio.h:28:
In file included from
/home/max/install/glibc//include/bits/libc-header-start.h:33:
/home/max/install/glibc//include/features.h:374:3: warning:
_FORTIFY_SOURCE is not compatible with sanitizer [-W#warnings]
# warning _FORTIFY_SOURCE is not compatible with sanitizer
^
1 warning generated.
-Maxim
[-- Attachment #2: fortify-asan.diff --]
[-- Type: text/x-diff, Size: 2289 bytes --]
commit b153492ed25b1bc70141566e6644897b89a82e26
Author: Maxim Ostapenko <m.ostapenko@samsung.com>
Date: Wed Aug 31 15:29:49 2016 +0300
Do not allow asan/msan/tsan and fortify at the same time.
When fortify is used with msan it will cause msan false positives. This is
happening because fortify replaces libc functions (e.g. sprintf) with its own
variants (__sprintf_chk) and the sanitizers don't know about these variants.
Supporting fortify in *san makes little sense because fortify does not add
anything to the sanitizers and it will only increase the complexity. So, the
better way is to warn the user that the sanitizers and fortify are
incompatible.
[BZ #20422]
* include/features.h (__SANITIZER_ENABLED): New macros. Define it if
compiler has {A, T, M}San enabled. Warn if __SANITIZER_ENABLED and
_FORTIFY_SOURCE are both defined.
diff --git a/ChangeLog b/ChangeLog
index d24536b..ee513cd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-09-05 Maxim Ostapenko <m.ostapenko@samsung.com>
+
+ [BZ #20422]
+ * include/features.h (__SANITIZER_ENABLED): New macros. Define it if
+ compiler has {A, T, M}San enabled. Warn if __SANITIZER_ENABLED and
+ _FORTIFY_SOURCE are both defined.
+
2016-08-30 Svante Signell <svante.signell@gmail.com>
* sysdeps/mach/hurd/adjtime.c (__adjtime): When OLDDELTA is NULL, make
diff --git a/include/features.h b/include/features.h
index 650d4c5..1158e5a 100644
--- a/include/features.h
+++ b/include/features.h
@@ -355,11 +355,23 @@
# define __USE_REENTRANT 1
#endif
+#if !defined(__has_feature)
+# define __has_feature(x) 0
+#endif
+
+#if defined __SANITIZE_ADDRESS__ || defined __SANITIZE_THREAD__ \
+ || __has_feature(address_sanitizer) || __has_feature(thread_sanitizer) \
+ || __has_feature(memory_sanitizer)
+# define __SANITIZER_ENABLED 1
+#endif
+
#if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0
# if !defined __OPTIMIZE__ || __OPTIMIZE__ <= 0
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
# elif !__GNUC_PREREQ (4, 1)
# warning _FORTIFY_SOURCE requires GCC 4.1 or later
+# elif defined __SANITIZER_ENABLED
+# warning _FORTIFY_SOURCE is not compatible with sanitizer
# elif _FORTIFY_SOURCE > 1
# define __USE_FORTIFY_LEVEL 2
# else
next reply other threads:[~2016-09-05 17:27 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-05 17:27 Maxim Ostapenko [this message]
2016-09-05 19:48 ` Andrew Pinski
2016-09-06 8:39 ` Florian Weimer
2016-09-06 8:58 ` Yuri Gribov
2016-09-06 9:13 ` Florian Weimer
2016-09-06 9:20 ` Yuri Gribov
2016-09-06 9:51 ` Florian Weimer
2016-09-09 22:35 ` Kostya Serebryany
[not found] ` <CAN=P9phe_OP+tU+nnDDPEeZCR77w2ddrSX+LtSnx2-42p9JgUg@mail.gmail.com>
2016-09-12 9:36 ` Florian Weimer
2016-09-06 9:16 ` Maxim Ostapenko
2016-09-06 9:44 ` Florian Weimer
2016-09-09 22:36 ` Kostya Serebryany
2016-09-12 9:31 ` Florian Weimer
2016-09-12 18:54 ` Kostya Serebryany
2016-09-17 9:00 ` Yuri Gribov
2016-09-29 8:08 ` Florian Weimer
2016-09-29 9:47 ` Yuri Gribov
2016-09-29 10:04 ` Jakub Jelinek
2016-09-29 10:32 ` Yuri Gribov
2016-09-29 10:44 ` Jakub Jelinek
2016-09-29 10:52 ` Andrew Pinski
2016-09-29 21:23 ` Kostya Serebryany
2016-10-01 21:38 ` Andrew Pinski
2016-10-01 21:50 ` Jakub Jelinek
2016-10-02 7:51 ` Florian Weimer
2016-10-02 9:40 ` Jakub Jelinek
2016-10-02 9:43 ` Florian Weimer
2016-10-02 14:02 ` Yuri Gribov
2016-10-04 0:53 ` Kostya Serebryany
2016-10-04 6:46 ` Jakub Jelinek
2016-10-04 12:15 ` fortification and valgrind/memcheck (Was: [PATCH BZ#20422] Do not allow asan/msan/tsan and fortify@the same time) Mark Wielaard
2016-10-05 11:49 ` Florian Weimer
2016-10-05 12:02 ` Mark Wielaard
2016-10-05 14:27 ` [PATCH BZ#20422] Do not allow asan/msan/tsan and fortify at the same time Florian Weimer
2016-10-05 15:46 ` Maxim Ostapenko
2016-10-05 16:01 ` Kostya Serebryany
2016-10-05 16:01 ` Maxim Ostapenko
2016-10-05 16:06 ` Zack Weinberg
2016-10-05 16:11 ` Kostya Serebryany
2016-10-05 16:46 ` Zack Weinberg
2016-10-05 17:58 ` Yuri Gribov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=57CDAB08.8060601@samsung.com \
--to=m.ostapenko@samsung.com \
--cc=fweimer@redhat.com \
--cc=kcc@google.com \
--cc=libc-alpha@sourceware.org \
--cc=tetra2005@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).