aboutsummaryrefslogtreecommitdiff
path: root/gcc/asan.cc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2023-02-14 12:10:09 +0100
committerJakub Jelinek <jakub@redhat.com>2023-02-14 12:10:09 +0100
commit91b36d1c85ae3ad667d11c1ceeffc698126ab804 (patch)
tree5b7eb70e23728a2b13fff9e3a48e43c4b614cb49 /gcc/asan.cc
parent26f4b055d97804666d6d144b2af9b9dee0854354 (diff)
downloadgcc-91b36d1c85ae3ad667d11c1ceeffc698126ab804.zip
gcc-91b36d1c85ae3ad667d11c1ceeffc698126ab804.tar.gz
gcc-91b36d1c85ae3ad667d11c1ceeffc698126ab804.tar.bz2
asan: Add --param=asan-kernel-mem-intrinsic-prefix= [PR108777]
While in the -fsanitize=address case libasan overloads memcpy, memset, memmove and many other builtins, such that they are always instrumented, Linux kernel for -fsanitize=kernel-address recently changed or is changing, such that memcpy, memset and memmove actually aren't instrumented because they are often used also from no_sanitize ("kernel-address") functions and wants __{,hw,}asaN_{memcpy,memset,memmove} to be used instead for the instrumented calls. See e.g. the https://lkml.org/lkml/2023/2/9/1182 thread. Without appropriate support on the compiler side, that will mean any time a kernel-address instrumented function (most of them) calls memcpy/memset/memmove, they will not be instrumented and thus won't catch kernel bugs. Apparently clang 15 has a param for this. The following patch implements the same (except it is a usual GCC --param, not -mllvm argument) on the GCC side. I know this isn't a regression bugfix, but given that -fsanitize=kernel-address has a single project that uses it which badly wants this I think it would be worthwhile to make an exception and get this into GCC 13 rather than waiting another year, it won't affect non-kernel code, nor even the kernel unless the new parameter is used. 2023-02-14 Jakub Jelinek <jakub@redhat.com> PR sanitizer/108777 * params.opt (-param=asan-kernel-mem-intrinsic-prefix=): New param. * asan.h (asan_memfn_rtl): Declare. * asan.cc (asan_memfn_rtls): New variable. (asan_memfn_rtl): New function. * builtins.cc (expand_builtin): If param_asan_kernel_mem_intrinsic_prefix and function is kernel-{,hw}address sanitized, emit calls to __{,hw}asan_{memcpy,memmove,memset} rather than {memcpy,memmove,memset}. Use sanitize_flags_p (SANITIZE_ADDRESS) instead of flag_sanitize & SANITIZE_ADDRESS to check if asan_intercepted_p functions shouldn't be expanded inline. * gcc.dg/asan/pr108777-1.c: New test. * gcc.dg/asan/pr108777-2.c: New test. * gcc.dg/asan/pr108777-3.c: New test. * gcc.dg/asan/pr108777-4.c: New test. * gcc.dg/asan/pr108777-5.c: New test. * gcc.dg/asan/pr108777-6.c: New test. * gcc.dg/completion-3.c: Adjust expected multiline output.
Diffstat (limited to 'gcc/asan.cc')
-rw-r--r--gcc/asan.cc40
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/asan.cc b/gcc/asan.cc
index 57834b7..f56d084 100644
--- a/gcc/asan.cc
+++ b/gcc/asan.cc
@@ -391,6 +391,46 @@ asan_memintrin (void)
}
+/* Support for --param asan-kernel-mem-intrinsic-prefix=1. */
+static GTY(()) rtx asan_memfn_rtls[3];
+
+rtx
+asan_memfn_rtl (tree fndecl)
+{
+ int i;
+ const char *f, *p;
+ char buf[sizeof ("__hwasan_memmove")];
+
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_MEMCPY: i = 0; f = "memcpy"; break;
+ case BUILT_IN_MEMSET: i = 1; f = "memset"; break;
+ case BUILT_IN_MEMMOVE: i = 2; f = "memmove"; break;
+ default: gcc_unreachable ();
+ }
+ if (asan_memfn_rtls[i] == NULL_RTX)
+ {
+ tree save_name = DECL_NAME (fndecl);
+ tree save_assembler_name = DECL_ASSEMBLER_NAME (fndecl);
+ rtx save_rtl = DECL_RTL (fndecl);
+ if (flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
+ p = "__hwasan_";
+ else
+ p = "__asan_";
+ strcpy (buf, p);
+ strcat (buf, f);
+ DECL_NAME (fndecl) = get_identifier (buf);
+ DECL_ASSEMBLER_NAME_RAW (fndecl) = NULL_TREE;
+ SET_DECL_RTL (fndecl, NULL_RTX);
+ asan_memfn_rtls[i] = DECL_RTL (fndecl);
+ DECL_NAME (fndecl) = save_name;
+ DECL_ASSEMBLER_NAME_RAW (fndecl) = save_assembler_name;
+ SET_DECL_RTL (fndecl, save_rtl);
+ }
+ return asan_memfn_rtls[i];
+}
+
+
/* Checks whether section SEC should be sanitized. */
static bool