This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Add support for KernelAddressSanitizer


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.gribov@samsung.com>
Date:   Tue Jul 22 11:02:03 2014 +0400

    2014-07-23  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 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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]