On 07/18/2014 05:38 PM, Jakub Jelinek wrote:
Do you error out on -fsanitize=thread -fsanitize=kernel-address ?
Perhaps -fsanitize=kernel-address -fsanitize=address should be invalid too?
Yes, all these combinations are invalid.
But you don't error out on that.
Ok, fixed.
Then in sanitize_spec_function supposedly for "address" check
SANITIZE_USER_ADDRESS bit, for "kernel-address" added there
SANITIZE_KERNEL_ADDRESS, add all the incompatibility diagnostics for the new
invalid combinations.
This delayed detection until link phase (and even then was disabled if
-nostdlib was on)
so I decided to perform this check in finish_options (after passing
cmdline options).
Plus, toplev.c has e.g.:
Fixed as well.
-Y
commit bd51cdb807c2cf5ada0101ca7db89076b54ed18e
Author: Yury Gribov <y.gri...@samsung.com>
Date: Tue Jul 22 11:02:03 2014 +0400
2014-07-23 Yury Gribov <y.gri...@samsung.com>
* doc/cpp.texi (__SANITIZE_ADDRESS__): Updated description.
* doc/invoke.texi (-fsanitize=kernel-address): Describe new option.
* flag-types.h (SANITIZE_USER_ADDRESS, SANITIZE_KERNEL_ADDRESS):
New enums.
* gcc.c (sanitize_spec_function): Support new option.
(SANITIZER_SPEC): Remove now redundant check.
* opts.c (common_handle_option): Support new option.
(finish_options): Check for incompatibilities.
* toplev.c (process_options): Split userspace-specific checks.
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index aaed739..0a6e50c 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -2354,8 +2354,8 @@ This macro is defined, with value 3, when @option{-fstack-protector-strong} is
in use.
@item __SANITIZE_ADDRESS__
-This macro is defined, with value 1, when @option{-fsanitize=address} is
-in use.
+This macro is defined, with value 1, when @option{-fsanitize=address}
+or @option{-fsanitize=kernel-address} are in use.
@item __TIMESTAMP__
This macro expands to a string constant that describes the date and time
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b5e8d98..391daf8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5405,6 +5405,11 @@ more details. The run-time behavior can be influenced using the
@url{https://code.google.com/p/address-sanitizer/wiki/Flags#Run-time_flags} for
a list of supported options.
+@item -fsanitize=kernel-address
+@opindex fsanitize=kernel-address
+Enable AddressSanitizer for Linux kernel.
+See @uref{http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel} for more details.
+
@item -fsanitize=thread
@opindex fsanitize=thread
Enable ThreadSanitizer, a fast data race detector.
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 2849455..bf813b6 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -214,23 +214,25 @@ enum vect_cost_model {
enum sanitize_code {
/* AddressSanitizer. */
SANITIZE_ADDRESS = 1 << 0,
+ SANITIZE_USER_ADDRESS = 1 << 1,
+ SANITIZE_KERNEL_ADDRESS = 1 << 2,
/* ThreadSanitizer. */
- SANITIZE_THREAD = 1 << 1,
+ SANITIZE_THREAD = 1 << 3,
/* LeakSanitizer. */
- SANITIZE_LEAK = 1 << 2,
+ SANITIZE_LEAK = 1 << 4,
/* UndefinedBehaviorSanitizer. */
- SANITIZE_SHIFT = 1 << 3,
- SANITIZE_DIVIDE = 1 << 4,
- SANITIZE_UNREACHABLE = 1 << 5,
- SANITIZE_VLA = 1 << 6,
- SANITIZE_NULL = 1 << 7,
- SANITIZE_RETURN = 1 << 8,
- SANITIZE_SI_OVERFLOW = 1 << 9,
- SANITIZE_BOOL = 1 << 10,
- SANITIZE_ENUM = 1 << 11,
- SANITIZE_FLOAT_DIVIDE = 1 << 12,
- SANITIZE_FLOAT_CAST = 1 << 13,
- SANITIZE_BOUNDS = 1 << 14,
+ SANITIZE_SHIFT = 1 << 5,
+ SANITIZE_DIVIDE = 1 << 6,
+ SANITIZE_UNREACHABLE = 1 << 7,
+ SANITIZE_VLA = 1 << 8,
+ SANITIZE_NULL = 1 << 9,
+ SANITIZE_RETURN = 1 << 10,
+ SANITIZE_SI_OVERFLOW = 1 << 11,
+ SANITIZE_BOOL = 1 << 12,
+ SANITIZE_ENUM = 1 << 13,
+ SANITIZE_FLOAT_DIVIDE = 1 << 14,
+ SANITIZE_FLOAT_CAST = 1 << 15,
+ SANITIZE_BOUNDS = 1 << 16,
SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
| SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
| SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 6cd08ea..c0fde8c 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -779,8 +779,7 @@ proper position among the other output files. */
#ifndef SANITIZER_SPEC
#define SANITIZER_SPEC "\
%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
- %{static:%ecannot specify -static with -fsanitize=address}\
- %{%:sanitize(thread):%e-fsanitize=address is incompatible with -fsanitize=thread}}\
+ %{static:%ecannot specify -static with -fsanitize=address}}\
%{%:sanitize(thread):" LIBTSAN_SPEC "\
%{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}\
%{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
@@ -8224,7 +8223,9 @@ sanitize_spec_function (int argc, const char **argv)
return NULL;
if (strcmp (argv[0], "address") == 0)
- return (flag_sanitize & SANITIZE_ADDRESS) ? "" : NULL;
+ return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL;
+ if (strcmp (argv[0], "kernel-address") == 0)
+ return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL;
if (strcmp (argv[0], "thread") == 0)
return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
if (strcmp (argv[0], "undefined") == 0)
diff --git a/gcc/opts.c b/gcc/opts.c
index 5fed6f0..4b0af82 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -869,6 +869,20 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
/* The -gsplit-dwarf option requires -ggnu-pubnames. */
if (opts->x_dwarf_split_debug_info)
opts->x_debug_generate_pub_sections = 2;
+
+ /* Userspace and kernel ASan conflict with each other and with TSan. */
+
+ if ((flag_sanitize & SANITIZE_USER_ADDRESS)
+ && (flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+ error_at (loc,
+ "-fsanitize=address is incompatible with "
+ "-fsanitize=kernel-address");
+
+ if ((flag_sanitize & SANITIZE_ADDRESS)
+ && (flag_sanitize & SANITIZE_THREAD))
+ error_at (loc,
+ "-fsanitize=address and -fsanitize=kernel-address "
+ "are incompatible with -fsanitize=thread");
}
#define LEFT_COLUMN 27
@@ -1454,7 +1468,10 @@ common_handle_option (struct gcc_options *opts,
size_t len;
} spec[] =
{
- { "address", SANITIZE_ADDRESS, sizeof "address" - 1 },
+ { "address", SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS,
+ sizeof "address" - 1 },
+ { "kernel-address", SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS,
+ sizeof "kernel-address" - 1 },
{ "thread", SANITIZE_THREAD, sizeof "thread" - 1 },
{ "leak", SANITIZE_LEAK, sizeof "leak" - 1 },
{ "shift", SANITIZE_SHIFT, sizeof "shift" - 1 },
@@ -1520,6 +1537,25 @@ common_handle_option (struct gcc_options *opts,
the null pointer checks. */
if (flag_sanitize & SANITIZE_NULL)
opts->x_flag_delete_null_pointer_checks = 0;
+
+ /* Kernel ASan implies normal ASan but does not yet support
+ all features. */
+ if (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
+ {
+ maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, 0,
+ opts->x_param_values,
+ opts_set->x_param_values);
+ maybe_set_param_value (PARAM_ASAN_GLOBALS, 0,
+ opts->x_param_values,
+ opts_set->x_param_values);
+ maybe_set_param_value (PARAM_ASAN_STACK, 0,
+ opts->x_param_values,
+ opts_set->x_param_values);
+ maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
+ opts->x_param_values,
+ opts_set->x_param_values);
+ }
+
break;
}
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 1c9befd..d82244f 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1555,9 +1555,18 @@ process_options (void)
warn_stack_protect = 0;
/* Address Sanitizer needs porting to each target architecture. */
+
if ((flag_sanitize & SANITIZE_ADDRESS)
- && (targetm.asan_shadow_offset == NULL
- || !FRAME_GROWS_DOWNWARD))
+ && !FRAME_GROWS_DOWNWARD)
+ {
+ warning (0,
+ "-fsanitize=address and -fsanitize=kernel-address "
+ "are not supported for this target");
+ flag_sanitize &= ~SANITIZE_ADDRESS;
+ }
+
+ if ((flag_sanitize & SANITIZE_USER_ADDRESS)
+ && targetm.asan_shadow_offset == NULL)
{
warning (0, "-fsanitize=address not supported for this target");
flag_sanitize &= ~SANITIZE_ADDRESS;