Add new command line option -fsanitize=memtag with the following
new params:
 --param memtag-instrument-stack [0,1] (default 1) to use MTE
insns for enabling dynamic checking of stack variables.
 --param memtag-instrument-alloca [0,1] (default 1) to use MTE
insns for enabling dynamic checking of stack allocas.

Add errors to convey that memtag sanitizer does not work with
hwaddress and address sanitizers.  Also error out if memtag ISA
extension is not enabled.

MEMTAG sanitizer will use the HWASAN machinery, but with a few
differences:
  - The tags are always generated at runtime by the hardware, so
    -fsanitize=memtag enforces a --param hwasan-random-frame-tag=1

Add documentation in gcc/doc/invoke.texi.

gcc/
        * builtins.def: Adjust the macro to include the new
        SANTIZIE_MEMTAG.
        * flag-types.h (enum sanitize_code): Add new enumerator for
        ANITIZE_MEMTAG.
        * opts.cc (finish_options): MEMTAG conflicts with hwaddress and
        address sanitizers.
        (common_handle_option): SANITIZE_MEMTAG tags are always
        generated (randomly) by the hardware.
        * params.opt: Add new params for MEMTAG sanitizer.
doc/
        * invoke.texi: Update documentation.

gcc/config/
        * aarch64/aarch64.cc (aarch64_override_options_internal): Error
        out if MTE is not available.

---

[Changes from RFC V1]
  - Added documentation for memtag-instrument-stack and
    memtag-instrument-allocas.
[End of changes from RFC V1]
---
 gcc/builtins.def              |  1 +
 gcc/config/aarch64/aarch64.cc |  4 ++++
 gcc/doc/invoke.texi           | 19 +++++++++++++++++--
 gcc/flag-types.h              |  2 ++
 gcc/opts.cc                   | 15 +++++++++++++++
 gcc/params.opt                |  8 ++++++++
 6 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/gcc/builtins.def b/gcc/builtins.def
index ff470051e54e..1f52eb56d962 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -253,6 +253,7 @@ along with GCC; see the file COPYING3.  If not see
               true, true, true, ATTRS, true, \
              (flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_THREAD \
                                | SANITIZE_HWADDRESS \
+                               | SANITIZE_MEMTAG \
                                | SANITIZE_UNDEFINED \
                                | SANITIZE_UNDEFINED_NONDEFAULT) \
               || flag_sanitize_coverage))
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 4e801146c60a..362de36dd098 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18752,6 +18752,10 @@ aarch64_override_options_internal (struct gcc_options 
*opts)
       && !fixed_regs[R18_REGNUM])
     error ("%<-fsanitize=shadow-call-stack%> requires %<-ffixed-x18%>");
 
+  if (flag_sanitize & SANITIZE_MEMTAG && !TARGET_MEMTAG)
+    error ("%<-fsanitize=memtag%> requires the ISA extension %qs",
+          "memtag");
+
   aarch64_feature_flags isa_flags = aarch64_get_isa_flags (opts);
   if ((isa_flags & (AARCH64_FL_SM_ON | AARCH64_FL_ZA_ON))
       && !(isa_flags & AARCH64_FL_SME))
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ffde9df85fd3..de651183a703 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -17079,6 +17079,14 @@ and @option{-fsanitize=kernel-hwaddress}.
 To disable instrumentation of builtin functions use
 @option{--param hwasan-instrument-mem-intrinsics=0}.
 
+@item memtag-instrument-stack
+Enable MTE tagging of statically sized stack-allocated variables.  This kind of
+code generation is enabled by default when using @option{-fsanitize=memtag}.
+
+@item memtag-instrument-allocas
+Enable MTE tagging of dynamically sized stack-allocated variables.  This kind 
of
+code generation is enabled by default when using @option{-fsanitize=memtag}.
+
 @item use-after-scope-direct-emission-threshold
 If the size of a local variable in bytes is smaller or equal to this
 number, directly poison (or unpoison) shadow memory instead of using
@@ -17963,8 +17971,9 @@ for a list of supported options.
 The option cannot be combined with @option{-fsanitize=thread} or
 @option{-fsanitize=hwaddress}.  Note that the only targets
 @option{-fsanitize=hwaddress} is currently supported on are x86-64
-(only with @code{-mlam=u48} or @code{-mlam=u57} options) and AArch64,
-in both cases only in ABIs with 64-bit pointers.
+(only with @code{-mlam=u48} or @code{-mlam=u57} options) and AArch64, in both
+cases only in ABIs with 64-bit pointers.  Similarly, @option{-fsanitize=memtag}
+is currently only supported on AArch64 ABIs with 64-bit pointers.
 
 When compiling with @option{-fsanitize=address}, you should also
 use @option{-g} to produce more meaningful output.
@@ -18017,6 +18026,12 @@ possible by specifying the command-line options
 @option{--param hwasan-instrument-allocas=1} respectively. Using a random frame
 tag is not implemented for kernel instrumentation.
 
+@opindex fsanitize=memtag
+@item -fsanitize=memtag
+Use Memory Tagging Extension instructions instead of instrumentation to allow
+the detection of memory errors.  This option is available only on those AArch64
+architectures that support Memory Tagging Extensions.
+
 @opindex fsanitize=pointer-compare
 @item -fsanitize=pointer-compare
 Instrument comparison operation (<, <=, >, >=) with pointer operands.
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 01276986874a..77c364a5c745 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -337,6 +337,8 @@ enum sanitize_code {
   SANITIZE_KERNEL_HWADDRESS = 1UL << 30,
   /* Shadow Call Stack.  */
   SANITIZE_SHADOW_CALL_STACK = 1UL << 31,
+  /* Memory Tagging.  */
+  SANITIZE_MEMTAG = 1ULL << 32,
   SANITIZE_SHIFT = SANITIZE_SHIFT_BASE | SANITIZE_SHIFT_EXPONENT,
   SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
                       | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 86c6691ecec4..00db662c32ef 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -1287,6 +1287,13 @@ finish_options (struct gcc_options *opts, struct 
gcc_options *opts_set,
   report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_ADDRESS,
                                        SANITIZE_KERNEL_ADDRESS);
 
+  /* Sanitizers using Memory-Tagging Extension conflict with HWASAN and
+     ASAN.  */
+  report_conflicting_sanitizer_options (opts, loc, SANITIZE_MEMTAG,
+                                       SANITIZE_HWADDRESS);
+  report_conflicting_sanitizer_options (opts, loc, SANITIZE_MEMTAG,
+                                       SANITIZE_ADDRESS);
+
   /* Check error recovery for -fsanitize-recover option.  */
   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
     if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
@@ -2146,6 +2153,7 @@ const struct sanitizer_opts_s sanitizer_opts[] =
   SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true, true),
   SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true, true),
   SANITIZER_OPT (shadow-call-stack, SANITIZE_SHADOW_CALL_STACK, false, false),
+  SANITIZER_OPT (memtag, SANITIZE_MEMTAG, false, false),
   SANITIZER_OPT (all, ~0U, true, true),
 #undef SANITIZER_OPT
   { NULL, 0U, 0UL, false, false }
@@ -2780,6 +2788,13 @@ common_handle_option (struct gcc_options *opts,
          SET_OPTION_IF_UNSET (opts, opts_set,
                               param_hwasan_instrument_allocas, 0);
        }
+      /* Memtag sanitizer implies HWASAN but with tags always generated by the
+        hardware randomly.  */
+      if (opts->x_flag_sanitize & SANITIZE_MEMTAG)
+       {
+         SET_OPTION_IF_UNSET (opts, opts_set,
+                              param_hwasan_random_frame_tag, 1);
+       }
       break;
 
     case OPT_fsanitize_recover_:
diff --git a/gcc/params.opt b/gcc/params.opt
index 422d082b3557..77ece0c50512 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -94,6 +94,14 @@ Enable hwasan instrumentation of store operations.
 Common Joined UInteger Var(param_hwasan_instrument_mem_intrinsics) Init(1) 
IntegerRange(0, 1) Param Optimization
 Enable hwasan instrumentation of builtin functions.
 
+-param=memtag-instrument-stack=
+Target Joined UInteger Var(param_memtag_instrument_stack) Init(1) 
IntegerRange(0, 1) Param
+When sanitizing using MTE instructions, add checks for all stack automatics.
+
+-param=memtag-instrument-allocas=
+Target Joined UInteger Var(param_memtag_instrument_allocas) Init(1) 
IntegerRange(0, 1) Param
+When sanitizing using MTE instructions, add checks for all stack allocas.
+
 -param=avg-loop-niter=
 Common Joined UInteger Var(param_avg_loop_niter) Init(10) IntegerRange(1, 
65536) Param Optimization
 Average number of iterations of a loop.
-- 
2.43.0

Reply via email to