diff mbox

[9/17] Initial KAsan support

Message ID 543F845C.2090908@samsung.com
State New
Headers show

Commit Message

Yury Gribov Oct. 16, 2014, 8:39 a.m. UTC
The patch was slightly updated to take care of missing UBSan work 
(SANITIZE_FLOAT_DIVIDE, SANITIZE_FLOAT_CAST, SANITIZE_BOUNDS).

Comments

Jakub Jelinek Oct. 16, 2014, 8:50 a.m. UTC | #1
On Thu, Oct 16, 2014 at 12:39:56PM +0400, Yury Gribov wrote:
> The patch was slightly updated to take care of missing UBSan work
> (SANITIZE_FLOAT_DIVIDE, SANITIZE_FLOAT_CAST, SANITIZE_BOUNDS).

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-07-31  Yury Gribov  <y.gribov@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.

Ok.

	Jakub
diff mbox

Patch

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-07-31  Yury Gribov  <y.gribov@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 4012f08..179f273 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5286,6 +5286,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 ec16faa..1dd1b3e 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -204,20 +204,22 @@  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_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_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 9c4c40c..1034de8 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -734,8 +734,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 "}\
@@ -8173,7 +8172,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 bbd6b9c..fbdebd7 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -868,6 +868,20 @@  finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
   /* The -gsplit-dwarf option requires -gpubnames.  */
   if (opts->x_dwarf_split_debug_info)
     opts->x_debug_generate_pub_sections = 1;
+
+  /* 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
@@ -1453,7 +1467,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 },
@@ -1514,6 +1531,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 d646faf..588fa2b 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;