Re: [PATCH 4/X] libsanitizer: options: Add hwasan flags and argument parsing

2020-11-23 Thread Richard Sandiford via Gcc-patches
Matthew Malcomson  writes:
> Hi there,
>
> I was just doing some double-checks and noticed I'd placed the
> documentation in the wrong section of tm.texi.  The `MEMTAG` hooks were
> documented in the `Register Classes` section, so I've now moved it to
> the `Misc` section.
>
> That's the only change, Ok for trunk?

OK, thanks.

Richard


Re: [PATCH 4/X] libsanitizer: options: Add hwasan flags and argument parsing

2020-11-20 Thread Matthew Malcomson via Gcc-patches
Hi there,

I was just doing some double-checks and noticed I'd placed the
documentation in the wrong section of tm.texi.  The `MEMTAG` hooks were
documented in the `Register Classes` section, so I've now moved it to
the `Misc` section.

That's the only change, Ok for trunk?

Matthew



These flags can't be used at the same time as any of the other
sanitizers.
We add an equivalent flag to -static-libasan in -static-libhwasan to
ensure static linking.

The -fsanitize=kernel-hwaddress option is for compiling targeting the
kernel.  This flag has defaults to match the LLVM implementation and
sets some other behaviors to work in the kernel (e.g. accounting for
the fact that the stack pointer will have 0xff in the top byte and to not
call the userspace library initialisation routines).
The defaults are that we do not sanitize variables on the stack and
always recover from a detected bug.

Since we are introducing a few more conflicts between sanitizer flags we
refactor the checking for such conflicts to use a helper function which
makes checking for such conflicts more easy and consistent.

We introduce a backend hook `targetm.memtag.can_tag_addresses` that
indicates to the mid-end whether a target has a feature like AArch64 TBI
where the top byte of an address is ignored.
Without this feature hwasan sanitization is not done.

gcc/ChangeLog:

* common.opt (flag_sanitize_recover): Default for kernel
hwaddress.
(static-libhwasan): New cli option.
* config/aarch64/aarch64.c (aarch64_can_tag_addresses): New.
(TARGET_MEMTAG_CAN_TAG_ADDRESSES): New.
* config/gnu-user.h (LIBHWASAN_EARLY_SPEC): hwasan equivalent of
asan command line flags.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags):
Add hwasan equivalent of __SANITIZE_ADDRESS__.
* doc/invoke.texi: Document hwasan command line flags.
* doc/tm.texi: Document new hook.
* doc/tm.texi.in: Document new hook.
* flag-types.h (enum sanitize_code): New sanitizer values.
* gcc.c (STATIC_LIBHWASAN_LIBS): New macro.
(LIBHWASAN_SPEC): New macro.
(LIBHWASAN_EARLY_SPEC): New macro.
(SANITIZER_EARLY_SPEC): Update to include hwasan.
(SANITIZER_SPEC): Update to include hwasan.
(sanitize_spec_function): Use hwasan options.
* opts.c (finish_options): Describe conflicts between address
sanitizers.
(find_sanitizer_argument): New.
(report_conflicting_sanitizer_options): New.
(sanitizer_opts): Introduce new sanitizer flags.
(common_handle_option): Add defaults for kernel sanitizer.
* params.opt (hwasan--instrument-stack): New
(hwasan-random-frame-tag): New
(hwasan-instrument-allocas): New
(hwasan-instrument-reads): New
(hwasan-instrument-writes): New
(hwasan-instrument-mem-intrinsics): New
* target.def (HOOK_PREFIX): Add new hook.
(can_tag_addresses): Add new hook under memtag prefix.
* targhooks.c (default_memtag_can_tag_addresses): New.
* targhooks.h (default_memtag_can_tag_addresses): New decl.
* toplev.c (process_options): Ensure hwasan only on
architectures that advertise the possibility.



### Attachment also inlined for ease of reply###


diff --git a/gcc/common.opt b/gcc/common.opt
index 
fe39b3dee9f270dd39b3f69ff6a0e2e854058703..4e4ba790ce668e490e35c2d95a0b12472754fba4
 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -218,7 +218,7 @@ unsigned int flag_sanitize
 
 ; What sanitizers should recover from errors
 Variable
-unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | 
SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS) & 
~(SANITIZE_UNREACHABLE | SANITIZE_RETURN)
+unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | 
SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS | 
SANITIZE_KERNEL_HWADDRESS) & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN)
 
 ; What the coverage sanitizers should instrument
 Variable
@@ -3445,6 +3445,9 @@ Driver
 static-libasan
 Driver
 
+static-libhwasan
+Driver
+
 static-libtsan
 Driver
 
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 
6de51b521bacb0530799c7cbddb5f6b170bf441c..4f90a49f1b79db406319ddbf89e42f58a695f430
 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -23294,6 +23294,15 @@ aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, 
const_tree type1,
   return NULL;
 }
 
+/* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES.  Here we tell the rest of the
+   compiler that we automatically ignore the top byte of our pointers, which
+   allows using -fsanitize=hwaddress.  */
+bool
+aarch64_can_tag_addresses ()
+{
+  return !TARGET_ILP32;
+}
+
 /* Implement TARGET_ASM_FILE_END for AArch64.  This adds the AArch64 GNU NOTE
section at the end if needed.  */
 #define 

Re: [PATCH 4/X] libsanitizer: options: Add hwasan flags and argument parsing

2020-11-18 Thread Richard Sandiford via Gcc-patches
Matthew Malcomson  writes:
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 
> 5320e6c1e1e3c8d1482c20590049f763e11f8ff0..84050058be8eaa306b07655737e49ea8b6eb21a9
>  100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -13709,6 +13709,53 @@ is greater or equal to this number, use callbacks 
> instead of inline checks.
>  E.g. to disable inline code use
>  @option{--param asan-instrumentation-with-call-threshold=0}.
>  
> +@item hwasan-instrument-stack
> +Enable hwasan instrumentation of statically sized stack-allocated variables.
> +This kind of instrumentation is enabled by default when using
> +@option{-fsanitize=hwaddress} and disabled by default when using
> +@option{-fsanitize=kernel-hwaddress}.
> +To disable stack instrumentation use
> +@option{--param hwasan-instrument-stack=0}, and to enable it use
> +@option{--param hwasan-instrument-stack=1}.
> +
> +@item hwasan-random-frame-tag
> +When using stack instrumentation, decide tags for stack variables using a
> +deterministic sequence beginning at a random tag for each frame.  Usually 
> tags
> +are chosen using the same sequence beginning from 1.
> +This is enabled by default for @option{-fsanitize=hwaddress} and unavailable
> +for @option{-fsanitize=kernel-hwaddress}.
> +To disable it use @option{--param hwasan-random-frame-tag=0}.

I think it would be worth clarifying this.  I wasn't sure whether
“Usually tags are chosen…” was describing the “determinstic random
sequence” or whether it was describing the behaviour of
hwasan-random-frame-tag=0.  If it's describing the behaviour of
hwasan-random-frame-tag=0, then I'm not sure “usually” applies,
given that hwasan-random-frame-tag=1 is the default.

> […]
> +@item -fsanitize=kernel-hwaddress
> +@opindex fsanitize=kernel-hwaddress
> +Enable Hardware-assisted AddressSanitizer for compilation of the Linux 
> kernel.
> +Similar to @option{-fsanitize=kernel-address} but using an alternate
> +instrumentation method, and similar to @option{-fsanitize=hwaddress} but with
> +instrumentation differences necessary for compiling the Linux kernel.
> +These differences are to avoid hwasan library initialisation calls and to

initialization

> +account for the stack pointer having a different value in its top byte.
> +Note: This option has different defaults to the 
> @option{-fsanitize=hwaddress}.

texinfo has:

  @quotation Note
  @end quotation

for this, but we don't seem to use it.  Still, I think it would be better
to break the paragraph before Note: and use:

  @emph{Note:}

which seems to be the preferred style in the GCC manual.

> +Instrumenting the stack and alloca calls are not on by default but is still

@code{alloca}
s/is still/are still/

> +possible by specifying it on the command line with

maybe s/it on the command line with/specifying the command-line options/?
Just a suggestion: would be happy with alternatives.

> +@option{--param hwasan-instrument-stack=1} and
> +@option{--param hwasan-instrument-allocas=1}. Using a random frame tag is not

and maybe add a “respectively” at the end of this sentence.

> +implemented for kernel instrumentation.
> +
>  @item -fsanitize=pointer-compare
>  @opindex fsanitize=pointer-compare
>  Instrument comparison operation (<, <=, >, >=) with pointer operands.
> […]
> diff --git a/gcc/opts.c b/gcc/opts.c
> index 
> ac9972d9c386247af3482e07a94c76da3e1abb4d..f3662062c421e1c58c3243109891900eb2dc84bc
>  100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -823,6 +823,51 @@ control_options_for_live_patching (struct gcc_options 
> *opts,
>  /* --help option argument if set.  */
>  vec help_option_arguments;
>  
> +/* Return the string name describing the argument provided on the command 
> line
> +which has set this particular flag.  */
> +const char *
> +find_argument (struct gcc_options *opts, unsigned int flags)
> +{

I think either (a) the name and comment need to mention the
sanitiser more explicitly or (b) this should be a lambda function
in report_conflicting_sanitizer_options:

  auto find_argument = [&](unsigned int flags)
{
  …
};

(in which case the implementation and comments above are fine as-is).

> +  for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
> +{
> +  /* Need to find the sanitizer_opts element which:
> +  a) Could have set the flags requested.
> +  b) Has been set on the command line.
> +
> +  Can have (a) without (b) if the flag requested is e.g.
> +  SANITIZE_ADDRESS, since both -fsanitize=address and
> +  -fsanitize=kernel-address set this flag.
> +
> +  Can have (b) without (a) by requesting more than one sanitizer on the
> +  command line.  */
> +  if ((sanitizer_opts[i].flag & opts->x_flag_sanitize)
> +   != sanitizer_opts[i].flag)
> + continue;
> +  if ((sanitizer_opts[i].flag & flags) != flags)
> + continue;
> +  return sanitizer_opts[i].name;
> +}
> +  return NULL;
> +}
> +
> +
> +/* Report any conflicting sanitizer options 

[PATCH 4/X] libsanitizer: options: Add hwasan flags and argument parsing

2020-11-16 Thread Matthew Malcomson via Gcc-patches
These flags can't be used at the same time as any of the other
sanitizers.
We add an equivalent flag to -static-libasan in -static-libhwasan to
ensure static linking.

The -fsanitize=kernel-hwaddress option is for compiling targeting the
kernel.  This flag has defaults to match the LLVM implementation and
sets some other behaviors to work in the kernel (e.g. accounting for
the fact that the stack pointer will have 0xff in the top byte and to not
call the userspace library initialisation routines).
The defaults are that we do not sanitize variables on the stack and
always recover from a detected bug.

Since we are introducing a few more conflicts between sanitizer flags we
refactor the checking for such conflicts to use a helper function which
makes checking for such conflicts more easy and consistent.

We introduce a backend hook `targetm.memtag.can_tag_addresses` that
indicates to the mid-end whether a target has a feature like AArch64 TBI
where the top byte of an address is ignored.
Without this feature hwasan sanitization is not done.

gcc/ChangeLog:

* common.opt (flag_sanitize_recover): Default for kernel
hwaddress.
(static-libhwasan): New cli option.
* config/aarch64/aarch64.c (aarch64_can_tag_addresses): New.
(TARGET_MEMTAG_CAN_TAG_ADDRESSES): New.
* config/gnu-user.h (LIBHWASAN_EARLY_SPEC): hwasan equivalent of
asan command line flags.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags):
Add hwasan equivalent of __SANITIZE_ADDRESS__.
* doc/invoke.texi: Document hwasan command line flags.
* doc/tm.texi: Document new hook.
* doc/tm.texi.in: Document new hook.
* flag-types.h (enum sanitize_code): New sanitizer values.
* gcc.c (STATIC_LIBHWASAN_LIBS): New macro.
(LIBHWASAN_SPEC): New macro.
(LIBHWASAN_EARLY_SPEC): New macro.
(SANITIZER_EARLY_SPEC): Update to include hwasan.
(SANITIZER_SPEC): Update to include hwasan.
(sanitize_spec_function): Use hwasan options.
* opts.c (finish_options): Describe conflicts between address
sanitizers.
(find_argument): New.
(report_conflicting_sanitizer_options): New.
(sanitizer_opts): Introduce new sanitizer flags.
(common_handle_option): Add defaults for kernel sanitizer.
* params.opt (hwasan--instrument-stack): New
(hwasan-random-frame-tag): New
(hwasan-instrument-allocas): New
(hwasan-instrument-reads): New
(hwasan-instrument-writes): New
(hwasan-instrument-mem-intrinsics): New
* target.def (HOOK_PREFIX): Add new hook.
(can_tag_addresses): Add new hook under memtag prefix.
* targhooks.c (default_memtag_can_tag_addresses): New.
* targhooks.h (default_memtag_can_tag_addresses): New decl.
* toplev.c (process_options): Ensure hwasan only on
architectures that advertise the possibility.



### Attachment also inlined for ease of reply###


diff --git a/gcc/common.opt b/gcc/common.opt
index 
d4cbb2f86a554fa2f87e52b2b6cbd1de27ddaa31..c7eec0fe683b817233ab4572024c16542a646cb4
 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -218,7 +218,7 @@ unsigned int flag_sanitize
 
 ; What sanitizers should recover from errors
 Variable
-unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | 
SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS) & 
~(SANITIZE_UNREACHABLE | SANITIZE_RETURN)
+unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | 
SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS | 
SANITIZE_KERNEL_HWADDRESS) & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN)
 
 ; What the coverage sanitizers should instrument
 Variable
@@ -3429,6 +3429,9 @@ Driver
 static-libasan
 Driver
 
+static-libhwasan
+Driver
+
 static-libtsan
 Driver
 
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 
27f587be7e7483093f1fd381d8fa14a6c6581ccf..ea85aadb619eb2e9ee7328f035f81aa8578ee3ad
 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -23175,6 +23175,15 @@ aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, 
const_tree type1,
   return NULL;
 }
 
+/* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES.  Here we tell the rest of the
+   compiler that we automatically ignore the top byte of our pointers, which
+   allows using -fsanitize=hwaddress.  */
+bool
+aarch64_can_tag_addresses ()
+{
+  return true;
+}
+
 /* Implement TARGET_ASM_FILE_END for AArch64.  This adds the AArch64 GNU NOTE
section at the end if needed.  */
 #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc000
@@ -23994,6 +24003,9 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_FNTYPE_ABI
 #define TARGET_FNTYPE_ABI aarch64_fntype_abi
 
+#undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
+#define TARGET_MEMTAG_CAN_TAG_ADDRESSES aarch64_can_tag_addresses
+
 #if CHECKING_P
 #undef TARGET_RUN_TARGET_SELFTESTS
 #define 

Re: [PATCH 4/X] libsanitizer: options: Add hwasan flags and argument parsing

2020-10-14 Thread Richard Sandiford via Gcc-patches
Matthew Malcomson  writes:
> ### Attachment also inlined for ease of reply
> ###
>
>
> diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
> index 
> 372148315389db6671dfd943fd1a68670fcb1cbc..f8bf165aa48b5709c26f4e8245e5ab929b44fca6
>  100644
> --- a/gcc/c-family/c-attribs.c
> +++ b/gcc/c-family/c-attribs.c
> @@ -54,6 +54,8 @@ static tree handle_cold_attribute (tree *, tree, tree, int, 
> bool *);
>  static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
> int, bool *);
> +static tree handle_no_sanitize_hwaddress_attribute (tree *, tree, tree,
> + int, bool *);
>  static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
>int, bool *);
>  static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
> @@ -412,6 +414,8 @@ const struct attribute_spec c_common_attribute_table[] =
> handle_no_sanitize_attribute, NULL },
>{ "no_sanitize_address",0, 0, true, false, false, false,
> handle_no_sanitize_address_attribute, NULL },
> +  { "no_sanitize_hwaddress",0, 0, true, false, false, false,
> +   handle_no_sanitize_hwaddress_attribute, NULL },
>{ "no_sanitize_thread", 0, 0, true, false, false, false,
> handle_no_sanitize_thread_attribute, NULL },
>{ "no_sanitize_undefined",  0, 0, true, false, false, false,
> @@ -946,6 +950,22 @@ handle_no_sanitize_address_attribute (tree *node, tree 
> name, tree, int,
>return NULL_TREE;
>  }
>  
> +/* Handle a "no_sanitize_hwaddress" attribute; arguments as in
> +   struct attribute_spec.handler.  */
> +
> +static tree
> +handle_no_sanitize_hwaddress_attribute (tree *node, tree name, tree, int,
> +   bool *no_add_attrs)
> +{
> +  *no_add_attrs = true;
> +  if (TREE_CODE (*node) != FUNCTION_DECL)
> +warning (OPT_Wattributes, "%qE attribute ignored", name);
> +  else
> +add_no_sanitize_value (*node, SANITIZE_HWADDRESS);
> +
> +  return NULL_TREE;
> +}
> +
>  /* Handle a "no_sanitize_thread" attribute; arguments as in
> struct attribute_spec.handler.  */
>  

Although the Clang design page mentions this attribute, it doesn't look
like it was ever committed upstream (unless I'm missing something).
Clang instead seems to require:

  __attribute__((no_sanitize("hwaddress")))
  __attribute__((no_sanitize("kernel-hwaddress")))

That seems more scalable than adding an extra attribute for each new
sanitiser, and of course is what this patch also supports.

So it might be better to drop this and just stick with what Clang provides.

> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 
> ba18e05fb1abd0034afb73fd4a20feac27133149..97a5a532e31a9cea20955863bf6d2c8911a8e869
>  100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -13898,13 +13898,34 @@ more details.  The run-time behavior can be 
> influenced using the
>  the available options are shown at startup of the instrumented program.  See
>  
> @url{https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags}
>  for a list of supported options.
> -The option cannot be combined with @option{-fsanitize=thread}.
> +The option cannot be combined with @option{-fsanitize=thread} or
> +@option{-fsanitize=hwaddress}.
>  
>  @item -fsanitize=kernel-address
>  @opindex fsanitize=kernel-address
>  Enable AddressSanitizer for Linux kernel.
>  See @uref{https://github.com/google/kasan/wiki} for more details.
>  
> +@item -fsanitize=hwaddress
> +@opindex fsanitize=hwaddress
> +Enable HardwareAddressSanitizer, a fast memory error detector.

Is HardwareAddressSanitizer an established shorthand?  All the references
I could see instead referred to it as “Hardware-assisted AddressSanitizer”,
which seems a bit more descriptive.

It would be good to expand on “a fast memory error detector“ a bit.
I was wondering about something like “, which uses dedicated features
of the target hardware to accelerate the detection of memory errors”.

> +Memory access instructions are instrumented to detect out-of-bounds and
> +use-after-free bugs.
> +The option enables @option{-fsanitize-address-use-after-scope}.
> +See
> +@uref{https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html}
> +for more details.  The run-time behavior can be influenced using the
> +@env{HWASAN_OPTIONS} environment variable.  When set to @code{help=1},
> +the available options are shown at startup of the instrumented program.
> +The option cannot be combined with @option{-fsanitize=thread} or
> +@option{-fsanitize=address}.

I think it would be worth emphasising that this option is only supported
on AArch64.

> +
> +@item -fsanitize=kernel-hwaddress
> 

[PATCH 4/X] libsanitizer: options: Add hwasan flags and argument parsing

2020-08-17 Thread Matthew Malcomson
These flags can't be used at the same time as any of the other
sanitizers.
We add an equivalent flag to -static-libasan in -static-libhwasan to
ensure static linking.

The -fsanitize=kernel-hwaddress option is for compiling targeting the
kernel.  This flag has defaults that allow compiling KASAN with tags as
it is currently implemented.
These defaults are that we do not sanitize variables on the stack and
always recover from a detected bug.
Stack tagging in the kernel is a future aim, I don't know of any reason
it would not work, but this has not yet been tested.

We introduce a backend hook `targetm.memtag.can_tag_addresses` that
indicates to the mid-end whether a target has a feature like AArch64 TBI
where the top byte of an address is ignored.
Without this feature hwasan sanitization is not done.

gcc/ChangeLog:

* common.opt (flag_sanitize_recover): Default for kernel
hwaddress.
(static-libhwasan): New cli option.
* config/aarch64/aarch64.c (aarch64_can_tag_addresses): New.
(TARGET_MEMTAG_CAN_TAG_ADDRESSES): New.
* config/gnu-user.h (LIBHWASAN_EARLY_SPEC): hwasan equivalent of
asan command line flags.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags):
Add hwasan equivalent of __SANITIZE_ADDRESS__.
* doc/invoke.texi: Document hwasan command line flags.
* doc/tm.texi: Document new hook.
* doc/tm.texi.in: Document new hook.
* flag-types.h (enum sanitize_code): New sanitizer values.
* gcc.c (STATIC_LIBHWASAN_LIBS): New macro.
(LIBHWASAN_SPEC): New macro.
(LIBHWASAN_EARLY_SPEC): New macro.
(SANITIZER_EARLY_SPEC): Update to include hwasan.
(SANITIZER_SPEC): Update to include hwasan.
(sanitize_spec_function): Use hwasan options.
* opts.c (finish_options): Describe conflicts between address
sanitizers.
(sanitizer_opts): Introduce new sanitizer flags.
(common_handle_option): Add defaults for kernel sanitizer.
* params.opt (hwasan--instrument-stack): New
(hwasan-random-frame-tag): New
(hwasan-instrument-allocas): New
(hwasan-instrument-reads): New
(hwasan-instrument-writes): New
(hwasan-instrument-mem-intrinsics): New
* target.def (HOOK_PREFIX): Add new hook.
(can_tag_addresses): Add new hook under memtag prefix.
* targhooks.c (default_memtag_can_tag_addresses): New.
* targhooks.h (default_memtag_can_tag_addresses): New decl.
* toplev.c (process_options): Ensure hwasan only on TBI
architectures.

gcc/c-family/ChangeLog:

* c-attribs.c (handle_no_sanitize_hwaddress_attribute): New
attribute.



### Attachment also inlined for ease of reply###


diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 
372148315389db6671dfd943fd1a68670fcb1cbc..f8bf165aa48b5709c26f4e8245e5ab929b44fca6
 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -54,6 +54,8 @@ static tree handle_cold_attribute (tree *, tree, tree, int, 
bool *);
 static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
 static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
  int, bool *);
+static tree handle_no_sanitize_hwaddress_attribute (tree *, tree, tree,
+   int, bool *);
 static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
 int, bool *);
 static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
@@ -412,6 +414,8 @@ const struct attribute_spec c_common_attribute_table[] =
  handle_no_sanitize_attribute, NULL },
   { "no_sanitize_address",0, 0, true, false, false, false,
  handle_no_sanitize_address_attribute, NULL },
+  { "no_sanitize_hwaddress",0, 0, true, false, false, false,
+ handle_no_sanitize_hwaddress_attribute, NULL },
   { "no_sanitize_thread", 0, 0, true, false, false, false,
  handle_no_sanitize_thread_attribute, NULL },
   { "no_sanitize_undefined",  0, 0, true, false, false, false,
@@ -946,6 +950,22 @@ handle_no_sanitize_address_attribute (tree *node, tree 
name, tree, int,
   return NULL_TREE;
 }
 
+/* Handle a "no_sanitize_hwaddress" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_no_sanitize_hwaddress_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
+{
+  *no_add_attrs = true;
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+warning (OPT_Wattributes, "%qE attribute ignored", name);
+  else
+add_no_sanitize_value (*node, SANITIZE_HWADDRESS);
+
+  return NULL_TREE;
+}
+
 /* Handle a "no_sanitize_thread" attribute; arguments as in
struct 

Re: [PATCH 4/X] [libsanitizer][options] Add hwasan flags and argument parsing

2020-01-07 Thread Martin Liška

On 12/12/19 4:19 PM, Matthew Malcomson wrote:

+-param=hwasan-stack=
+Common Joined UInteger Var(param_hwasan_stack) Init(1) IntegerRange(0, 1) Param
+Enable hwasan stack protection.
+
+-param=hwasan-random-frame-tag=
+Common Joined UInteger Var(param_hwasan_random_frame_tag) Init(1) 
IntegerRange(0, 1) Param
+Use random base tag for each frame, as opposed to base always zero.
+
+-param=hwasan-instrument-allocas=
+Common Joined UInteger Var(param_hwasan_protect_allocas) Init(1) 
IntegerRange(0, 1) Param
+Enable hwasan allocas/VLAs protection.
+
+-param=hwasan-instrument-reads=
+Common Joined UInteger Var(param_hwasan_instrument_reads) Init(1) 
IntegerRange(0, 1) Param
+Enable hwasan load operations protection.
+
+-param=hwasan-instrument-writes=
+Common Joined UInteger Var(param_hwasan_instrument_writes) Init(1) 
IntegerRange(0, 1) Param
+Enable hwasan store operations protection.
+
+-param=hwasan-memintrin=
+Common Joined UInteger Var(param_hwasan_memintrin) Init(1) IntegerRange(0, 1) 
Param
+Enable hwasan builtin functions protection.


Similarly to majority of ASAN parameters, all these should have Optimization 
keyword.
That means one can have different parameter values for each function (one can 
do that
with LTO right now).

Martin


[PATCH 4/X] [libsanitizer][options] Add hwasan flags and argument parsing

2019-12-12 Thread Matthew Malcomson
These flags can't be used at the same time as any of the other
sanitizers.
We add an equivalent flag to -static-libasan in -static-libhwasan to
ensure static linking.

The -fsanitize=kernel-hwaddress option is for compiling targeting the
kernel.  This flag has defaults that allow compiling KASAN with tags as
it is currently implemented.
These defaults are that we do not sanitize variables on the stack and
always recover from a detected bug.
Stack tagging in the kernel is a future aim, stack instrumentation has
not yet been enabled for the kernel for clang either
(https://lists.infradead.org/pipermail/linux-arm-kernel/2019-October/687121.html).

We introduce a backend hook `targetm.memtag.can_tag_addresses` that
indicates to the mid-end whether a target has a feature like AArch64 TBI
where the top byte of an address is ignored.
Without this feature hwasan sanitization is not done.

gcc/ChangeLog:

2019-12-12  Matthew Malcomson  

* common.opt (flag_sanitize_recover): Default for kernel
hwaddress.
(static-libhwasan): New cli option.
* config/aarch64/aarch64.c (aarch64_can_tag_addresses): New.
(TARGET_MEMTAG_CAN_TAG_ADDRESSES): New.
* config/gnu-user.h (LIBHWASAN_EARLY_SPEC): hwasan equivalent of
asan command line flags.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags):
Add hwasan equivalent of __SANITIZE_ADDRESS__.
* doc/tm.texi: Document new hook.
* doc/tm.texi.in: Document new hook.
* flag-types.h (enum sanitize_code): New sanitizer values.
* gcc.c (STATIC_LIBHWASAN_LIBS): New macro.
(LIBHWASAN_SPEC): New macro.
(LIBHWASAN_EARLY_SPEC): New macro.
(SANITIZER_EARLY_SPEC): Update to include hwasan.
(SANITIZER_SPEC): Update to include hwasan.
(sanitize_spec_function): Use hwasan options.
* opts.c (finish_options): Describe conflicts between address
sanitizers.
(sanitizer_opts): Introduce new sanitizer flags.
(common_handle_option): Add defaults for kernel sanitizer.
* params.opt (hwasan-stack): New
(hwasan-random-frame-tag): New
(hwasan-instrument-allocas): New
(hwasan-instrument-reads): New
(hwasan-instrument-writes): New
(hwasan-memintrin): New
* target.def (HOOK_PREFIX): Add new hook.
* targhooks.c (default_memtag_can_tag_addresses): New.
* toplev.c (process_options): Ensure hwasan only on TBI
architectures.

gcc/c-family/ChangeLog:

2019-12-12  Matthew Malcomson  

* c-attribs.c (handle_no_sanitize_hwaddress_attribute): New
attribute.



### Attachment also inlined for ease of reply###


diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 
dc56e2ec62ffc7f494cc59ddf02452ac0cb406de..81f8dfc6dd3f54067d7cc0def3c0babc03bcd9c4
 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -54,6 +54,8 @@ static tree handle_cold_attribute (tree *, tree, tree, int, 
bool *);
 static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
 static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
  int, bool *);
+static tree handle_no_sanitize_hwaddress_attribute (tree *, tree, tree,
+   int, bool *);
 static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
 int, bool *);
 static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
@@ -412,6 +414,8 @@ const struct attribute_spec c_common_attribute_table[] =
  handle_no_sanitize_attribute, NULL },
   { "no_sanitize_address",0, 0, true, false, false, false,
  handle_no_sanitize_address_attribute, NULL },
+  { "no_sanitize_hwaddress",0, 0, true, false, false, false,
+ handle_no_sanitize_hwaddress_attribute, NULL },
   { "no_sanitize_thread", 0, 0, true, false, false, false,
  handle_no_sanitize_thread_attribute, NULL },
   { "no_sanitize_undefined",  0, 0, true, false, false, false,
@@ -946,6 +950,22 @@ handle_no_sanitize_address_attribute (tree *node, tree 
name, tree, int,
   return NULL_TREE;
 }
 
+/* Handle a "no_sanitize_hwaddress" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_no_sanitize_hwaddress_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
+{
+  *no_add_attrs = true;
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+warning (OPT_Wattributes, "%qE attribute ignored", name);
+  else
+add_no_sanitize_value (*node, SANITIZE_HWADDRESS);
+
+  return NULL_TREE;
+}
+
 /* Handle a "no_sanitize_thread" attribute; arguments as in
struct attribute_spec.handler.  */
 
diff --git a/gcc/common.opt b/gcc/common.opt

Re: [PATCH 4/X] [libsanitizer][options] Add hwasan flags and argument parsing

2019-11-20 Thread Martin Liška

On 11/7/19 7:37 PM, Matthew Malcomson wrote:

These flags can't be used at the same time as any of the other
sanitizers.
We add an equivalent flag to -static-libasan in -static-libhwasan to
ensure static linking.

The -fsanitize=kernel-hwaddress option is for compiling targeting the
kernel.  This flag has defaults that allow compiling KASAN with tags as
it is currently implemented.
These defaults are that we do not sanitize variables on the stack and
always recover from a detected bug.
Stack tagging in the kernel is a future aim, stack instrumentation has
not yet been enabled for the kernel for clang either
(https://lists.infradead.org/pipermail/linux-arm-kernel/2019-October/687121.html).

We introduce a backend hook `targetm.memtag.can_tag_addresses` that
indicates to the mid-end whether a target has a feature like AArch64 TBI
where the top byte of an address is ignored.
Without this feature hwasan sanitization is not done.

gcc/ChangeLog:

2019-11-07  Matthew Malcomson  

* asan.c (memory_tagging_p): New.
* asan.h (memory_tagging_p): New.
* common.opt (flag_sanitize_recover): Default for kernel
hwaddress.
(static-libhwasan): New cli option.
* config/aarch64/aarch64.c (aarch64_can_tag_addresses): New.
(TARGET_MEMTAG_CAN_TAG_ADDRESSES): New.
* config/gnu-user.h (LIBHWASAN_EARLY_SPEC): hwasan equivalent of
asan command line flags.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags):
Add hwasan equivalent of __SANITIZE_ADDRESS__.
* doc/tm.texi: Document new hook.
* doc/tm.texi.in: Document new hook.
* flag-types.h (enum sanitize_code): New sanitizer values.
* gcc.c (STATIC_LIBHWASAN_LIBS): New macro.
(LIBHWASAN_SPEC): New macro.
(LIBHWASAN_EARLY_SPEC): New macro.
(SANITIZER_EARLY_SPEC): Update to include hwasan.
(SANITIZER_SPEC): Update to include hwasan.
(sanitize_spec_function): Use hwasan options.
* opts.c (finish_options): Describe conflicts between address
sanitizers.
(sanitizer_opts): Introduce new sanitizer flags.
(common_handle_option): Add defaults for kernel sanitizer.
* params.def (PARAM_HWASAN_RANDOM_FRAME_TAG): New.
(PARAM_HWASAN_STACK): New.
* params.h (HWASAN_STACK): New.
(HWASAN_RANDOM_FRAME_TAG): New.
* target.def (HOOK_PREFIX): Add new hook.
* targhooks.c (default_memtag_can_tag_addresses): New.
* toplev.c (process_options): Ensure hwasan only on TBI
architectures.

gcc/c-family/ChangeLog:

2019-11-07  Matthew Malcomson  

* c-attribs.c (handle_no_sanitize_hwaddress_attribute): New
attribute.



### Attachment also inlined for ease of reply###


diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 
1c9f28587fbb2348cc30e302e889a5a22906901a..a5e68061ff956018957b6be137a7b2f2b7353647
 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -54,6 +54,8 @@ static tree handle_cold_attribute (tree *, tree, tree, int, 
bool *);
  static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
  static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
  int, bool *);
+static tree handle_no_sanitize_hwaddress_attribute (tree *, tree, tree,
+   int, bool *);
  static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
 int, bool *);
  static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
@@ -412,6 +414,8 @@ const struct attribute_spec c_common_attribute_table[] =
  handle_no_sanitize_attribute, NULL },
{ "no_sanitize_address",0, 0, true, false, false, false,
  handle_no_sanitize_address_attribute, NULL },
+  { "no_sanitize_hwaddress",0, 0, true, false, false, false,
+ handle_no_sanitize_hwaddress_attribute, NULL },
{ "no_sanitize_thread", 0, 0, true, false, false, false,
  handle_no_sanitize_thread_attribute, NULL },
{ "no_sanitize_undefined",  0, 0, true, false, false, false,
@@ -941,6 +945,22 @@ handle_no_sanitize_address_attribute (tree *node, tree 
name, tree, int,
return NULL_TREE;
  }
  
+/* Handle a "no_sanitize_hwaddress" attribute; arguments as in

+   struct attribute_spec.handler.  */
+
+static tree
+handle_no_sanitize_hwaddress_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
+{
+  *no_add_attrs = true;
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+warning (OPT_Wattributes, "%qE attribute ignored", name);
+  else
+add_no_sanitize_value (*node, SANITIZE_HWADDRESS);
+
+  return NULL_TREE;
+}
+
  /* Handle a "no_sanitize_thread" attribute; arguments as in
  

[PATCH 4/X] [libsanitizer][options] Add hwasan flags and argument parsing

2019-11-07 Thread Matthew Malcomson
These flags can't be used at the same time as any of the other
sanitizers.
We add an equivalent flag to -static-libasan in -static-libhwasan to
ensure static linking.

The -fsanitize=kernel-hwaddress option is for compiling targeting the
kernel.  This flag has defaults that allow compiling KASAN with tags as
it is currently implemented.
These defaults are that we do not sanitize variables on the stack and
always recover from a detected bug.
Stack tagging in the kernel is a future aim, stack instrumentation has
not yet been enabled for the kernel for clang either
(https://lists.infradead.org/pipermail/linux-arm-kernel/2019-October/687121.html).

We introduce a backend hook `targetm.memtag.can_tag_addresses` that
indicates to the mid-end whether a target has a feature like AArch64 TBI
where the top byte of an address is ignored.
Without this feature hwasan sanitization is not done.

gcc/ChangeLog:

2019-11-07  Matthew Malcomson  

* asan.c (memory_tagging_p): New.
* asan.h (memory_tagging_p): New.
* common.opt (flag_sanitize_recover): Default for kernel
hwaddress.
(static-libhwasan): New cli option.
* config/aarch64/aarch64.c (aarch64_can_tag_addresses): New.
(TARGET_MEMTAG_CAN_TAG_ADDRESSES): New.
* config/gnu-user.h (LIBHWASAN_EARLY_SPEC): hwasan equivalent of
asan command line flags.
* cppbuiltin.c (define_builtin_macros_for_compilation_flags):
Add hwasan equivalent of __SANITIZE_ADDRESS__.
* doc/tm.texi: Document new hook.
* doc/tm.texi.in: Document new hook.
* flag-types.h (enum sanitize_code): New sanitizer values.
* gcc.c (STATIC_LIBHWASAN_LIBS): New macro.
(LIBHWASAN_SPEC): New macro.
(LIBHWASAN_EARLY_SPEC): New macro.
(SANITIZER_EARLY_SPEC): Update to include hwasan.
(SANITIZER_SPEC): Update to include hwasan.
(sanitize_spec_function): Use hwasan options.
* opts.c (finish_options): Describe conflicts between address
sanitizers.
(sanitizer_opts): Introduce new sanitizer flags.
(common_handle_option): Add defaults for kernel sanitizer.
* params.def (PARAM_HWASAN_RANDOM_FRAME_TAG): New.
(PARAM_HWASAN_STACK): New.
* params.h (HWASAN_STACK): New.
(HWASAN_RANDOM_FRAME_TAG): New.
* target.def (HOOK_PREFIX): Add new hook.
* targhooks.c (default_memtag_can_tag_addresses): New.
* toplev.c (process_options): Ensure hwasan only on TBI
architectures.

gcc/c-family/ChangeLog:

2019-11-07  Matthew Malcomson  

* c-attribs.c (handle_no_sanitize_hwaddress_attribute): New
attribute.



### Attachment also inlined for ease of reply###


diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 
1c9f28587fbb2348cc30e302e889a5a22906901a..a5e68061ff956018957b6be137a7b2f2b7353647
 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -54,6 +54,8 @@ static tree handle_cold_attribute (tree *, tree, tree, int, 
bool *);
 static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
 static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
  int, bool *);
+static tree handle_no_sanitize_hwaddress_attribute (tree *, tree, tree,
+   int, bool *);
 static tree handle_no_sanitize_thread_attribute (tree *, tree, tree,
 int, bool *);
 static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
@@ -412,6 +414,8 @@ const struct attribute_spec c_common_attribute_table[] =
  handle_no_sanitize_attribute, NULL },
   { "no_sanitize_address",0, 0, true, false, false, false,
  handle_no_sanitize_address_attribute, NULL },
+  { "no_sanitize_hwaddress",0, 0, true, false, false, false,
+ handle_no_sanitize_hwaddress_attribute, NULL },
   { "no_sanitize_thread", 0, 0, true, false, false, false,
  handle_no_sanitize_thread_attribute, NULL },
   { "no_sanitize_undefined",  0, 0, true, false, false, false,
@@ -941,6 +945,22 @@ handle_no_sanitize_address_attribute (tree *node, tree 
name, tree, int,
   return NULL_TREE;
 }
 
+/* Handle a "no_sanitize_hwaddress" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_no_sanitize_hwaddress_attribute (tree *node, tree name, tree, int,
+ bool *no_add_attrs)
+{
+  *no_add_attrs = true;
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+warning (OPT_Wattributes, "%qE attribute ignored", name);
+  else
+add_no_sanitize_value (*node, SANITIZE_HWADDRESS);
+
+  return NULL_TREE;
+}
+
 /* Handle a "no_sanitize_thread" attribute; arguments as in
struct attribute_spec.handler.  */
 
diff --git