[Patch 0/X] HWASAN v4

Matthew Malcomson matthew.malcomson@arm.com
Mon Aug 17 14:12:57 GMT 2020


This is v4 of the HWASAN patches which add the LLVM hardware address
sanitizer (HWASAN) to GCC.
The document describing HWASAN can be found here

This address sanitizer only works for AArch64 at the moment.  It
requires the "top byte ignore" feature where the top byte of a pointer
does not affect dereferences.  This is checked for by a backend hook so
that if other architectures have this feature HWASAN can be used for

We require a linux kernel with the relaxed ABI to allow tagged pointers
in system calls.  This is in the linux mainline, I have been testing
this feature on 5.8.0, but it has been in since at least 5.5.0.

HWASAN works by storing a tag in the top bits of every pointer and a tag in
a shadow memory region corresponding to each area of memory pointed at.
On every memory access through a pointer the tag in the pointer is
checked against the tag in shadow memory corresponding to the memory the
pointer is accessing.  If the pointer tag and memory tag do not match
then a fault is signalled.

The instrumentation required for this sanitizer has a large overlap with
the instrumentation required for implementing MTE (which has similar
functionality but checks are automatically done in the hardware and
instructions for tagging shadow memory and for managing tags are
provided by the architecture).

We hope to use the HWASAN framework to implement MTE for the stack, so I
have included a "dummy" patch showing how this might be done in the full
patch set attached to this cover letter.  (mte-approach.patch)

Mainly this is the same patch series as posted in December rebased onto
master, but I have also identified and fixed a few minor bugs.

  - A few bugs around the use of ptr_mode and Pmode
    (for AArch64 only observable with -mabi=ilp32).
  - A frame-extent calculation bug when every stack object in a frame is
    `large aligned` -- see the arguments that hwasan_emit_prologue
    passes to hwasan_emit_untag_frame.
  - A few changes of parameter names to match Clang.
    The names were originally chosen to match ASAN, but I found that
    most of these parameters can be mapped to a Clang configurable and
    that renaming them to match clang makes Makefiles (like
    scripts/Makefile.kasan in the linux kernel) easier to write.

Bootstrapped and regtested on x86_64 and AArch64.
Bootstrapped with `--with-build-config=bootstrap-hwasan` on AArch64 and
hwasan features tested there (all new regression failures accounted for
Built the linux kernel using this feature and ran the test_kasan.ko
testing to check the this works for the kernel.

(NOTE: Stack-tagging for the linux kernel has recently been added for
clang.  Testing GCC stack-tagging on the kernel showed two small bugs --
1) using __hwasan_tag_pointer for allocas which isn't available in the
kernel, 2) not avoiding zero tag due to the stack pointer having tag of
0xff. I'm working on fixing these but I'm sending up the patch series
as-is to get feedback earlier.  A small change to a kernel makefile, and
some headers are needed to build it with this sanitizer -- a patch with
the changes and a text file explaining how to build and test the kernel
with HWASAN is attached.
  linux-for-gcc-hwasan.patch and testing-kasan.txt )

Last time the patch set went up Martin Liska had provided a patch to
build upon that added libhwasan into the libsanitizer directory so the
patch set didn't contain anything to do that.

The "full" patchset attached to this email contains a patch that adds
this library so that anyone who wants to test this can do so, but there
is no corresponding email for the individual patch.

  1) The target of having this sanitizer in GCC is for use on the Linux
  kernel.  The implementation should be good for the kernel, while the
  userspace story is not robust.

  The main use case of HWASAN is when it lies *underneath* the system
  libc.  In this approach the libc calls into libhwasan on important
  events (e.g. longjmp).
  This has been used very well in Android.
  At the moment there are no plans to do similar on distros with a
  modified glibc.

  A userspace story can be made by intercepting important functions.
  LLVM maintain this approach for *testing* only, and hence it is not of
  a production quality.
  Similarly we aim to use this "interception" model for testing, while
  maintaining the focus of the GCC port of use on the kernel.

  2) This sanitizer has no handling of C++ exceptions.
  If an exception is thrown the "shadow stack" is left in an
  inconsistent state and will likely eventually cause a false positive
  later on in the program.
  This is due to the fact that the handling of exceptions in LLVM relies
  on having the frame record appear after any locals(*).  This
  restriction is not satisfied by GCC due to its frame layout
  (*) https://github.com/llvm-mirror/compiler-rt/blob/master/lib/hwasan/hwasan_exceptions.cpp#L52

Entire patch set attached to this cover letter.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: all-patches.tar.gz
Type: application/gzip
Size: 112098 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc-patches/attachments/20200817/db64990e/attachment-0001.gz>

More information about the Gcc-patches mailing list