Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add KASAN instrumentation on the atomic functions. Use m...



details:   https://anonhg.NetBSD.org/src/rev/e4170d4a9c8f
branches:  trunk
changeset: 454113:e4170d4a9c8f
user:      maxv <maxv%NetBSD.org@localhost>
date:      Thu Sep 05 16:19:16 2019 +0000

description:
Add KASAN instrumentation on the atomic functions. Use macros to simplify.
These macros are prerequisites for future changes.

diffstat:

 sys/kern/subr_asan.c |  226 ++++++++++++++++++++++++++++++++++++++++++++-
 sys/sys/atomic.h     |  255 ++++++++++++++++++++++++++++++--------------------
 2 files changed, 377 insertions(+), 104 deletions(-)

diffs (truncated from 531 to 300 lines):

diff -r 72d8714f22ff -r e4170d4a9c8f sys/kern/subr_asan.c
--- a/sys/kern/subr_asan.c      Thu Sep 05 16:17:48 2019 +0000
+++ b/sys/kern/subr_asan.c      Thu Sep 05 16:19:16 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: subr_asan.c,v 1.10 2019/06/15 06:40:34 maxv Exp $      */
+/*     $NetBSD: subr_asan.c,v 1.11 2019/09/05 16:19:16 maxv Exp $      */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_asan.c,v 1.10 2019/06/15 06:40:34 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_asan.c,v 1.11 2019/09/05 16:19:16 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -551,6 +551,228 @@
 
 /* -------------------------------------------------------------------------- */
 
+#undef atomic_add_32
+#undef atomic_add_int
+#undef atomic_add_long
+#undef atomic_add_ptr
+#undef atomic_add_64
+#undef atomic_add_32_nv
+#undef atomic_add_int_nv
+#undef atomic_add_long_nv
+#undef atomic_add_ptr_nv
+#undef atomic_add_64_nv
+#undef atomic_and_32
+#undef atomic_and_uint
+#undef atomic_and_ulong
+#undef atomic_and_64
+#undef atomic_and_32_nv
+#undef atomic_and_uint_nv
+#undef atomic_and_ulong_nv
+#undef atomic_and_64_nv
+#undef atomic_or_32
+#undef atomic_or_uint
+#undef atomic_or_ulong
+#undef atomic_or_64
+#undef atomic_or_32_nv
+#undef atomic_or_uint_nv
+#undef atomic_or_ulong_nv
+#undef atomic_or_64_nv
+#undef atomic_cas_32
+#undef atomic_cas_uint
+#undef atomic_cas_ulong
+#undef atomic_cas_ptr
+#undef atomic_cas_64
+#undef atomic_cas_32_ni
+#undef atomic_cas_uint_ni
+#undef atomic_cas_ulong_ni
+#undef atomic_cas_ptr_ni
+#undef atomic_cas_64_ni
+#undef atomic_swap_32
+#undef atomic_swap_uint
+#undef atomic_swap_ulong
+#undef atomic_swap_ptr
+#undef atomic_swap_64
+#undef atomic_dec_32
+#undef atomic_dec_uint
+#undef atomic_dec_ulong
+#undef atomic_dec_ptr
+#undef atomic_dec_64
+#undef atomic_dec_32_nv
+#undef atomic_dec_uint_nv
+#undef atomic_dec_ulong_nv
+#undef atomic_dec_ptr_nv
+#undef atomic_dec_64_nv
+#undef atomic_inc_32
+#undef atomic_inc_uint
+#undef atomic_inc_ulong
+#undef atomic_inc_ptr
+#undef atomic_inc_64
+#undef atomic_inc_32_nv
+#undef atomic_inc_uint_nv
+#undef atomic_inc_ulong_nv
+#undef atomic_inc_ptr_nv
+#undef atomic_inc_64_nv
+
+#define ASAN_ATOMIC_FUNC_ADD(name, tret, targ1, targ2) \
+       void atomic_add_##name(volatile targ1 *, targ2); \
+       void kasan_atomic_add_##name(volatile targ1 *, targ2); \
+       void kasan_atomic_add_##name(volatile targ1 *ptr, targ2 val) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               atomic_add_##name(ptr, val); \
+       } \
+       tret atomic_add_##name##_nv(volatile targ1 *, targ2); \
+       tret kasan_atomic_add_##name##_nv(volatile targ1 *, targ2); \
+       tret kasan_atomic_add_##name##_nv(volatile targ1 *ptr, targ2 val) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               return atomic_add_##name##_nv(ptr, val); \
+       }
+
+#define ASAN_ATOMIC_FUNC_AND(name, tret, targ1, targ2) \
+       void atomic_and_##name(volatile targ1 *, targ2); \
+       void kasan_atomic_and_##name(volatile targ1 *, targ2); \
+       void kasan_atomic_and_##name(volatile targ1 *ptr, targ2 val) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               atomic_and_##name(ptr, val); \
+       } \
+       tret atomic_and_##name##_nv(volatile targ1 *, targ2); \
+       tret kasan_atomic_and_##name##_nv(volatile targ1 *, targ2); \
+       tret kasan_atomic_and_##name##_nv(volatile targ1 *ptr, targ2 val) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               return atomic_and_##name##_nv(ptr, val); \
+       }
+
+#define ASAN_ATOMIC_FUNC_OR(name, tret, targ1, targ2) \
+       void atomic_or_##name(volatile targ1 *, targ2); \
+       void kasan_atomic_or_##name(volatile targ1 *, targ2); \
+       void kasan_atomic_or_##name(volatile targ1 *ptr, targ2 val) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               atomic_or_##name(ptr, val); \
+       } \
+       tret atomic_or_##name##_nv(volatile targ1 *, targ2); \
+       tret kasan_atomic_or_##name##_nv(volatile targ1 *, targ2); \
+       tret kasan_atomic_or_##name##_nv(volatile targ1 *ptr, targ2 val) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               return atomic_or_##name##_nv(ptr, val); \
+       }
+
+#define ASAN_ATOMIC_FUNC_CAS(name, tret, targ1, targ2) \
+       tret atomic_cas_##name(volatile targ1 *, targ2, targ2); \
+       tret kasan_atomic_cas_##name(volatile targ1 *, targ2, targ2); \
+       tret kasan_atomic_cas_##name(volatile targ1 *ptr, targ2 exp, targ2 new) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               return atomic_cas_##name(ptr, exp, new); \
+       } \
+       tret atomic_cas_##name##_ni(volatile targ1 *, targ2, targ2); \
+       tret kasan_atomic_cas_##name##_ni(volatile targ1 *, targ2, targ2); \
+       tret kasan_atomic_cas_##name##_ni(volatile targ1 *ptr, targ2 exp, targ2 new) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               return atomic_cas_##name##_ni(ptr, exp, new); \
+       }
+
+#define ASAN_ATOMIC_FUNC_SWAP(name, tret, targ1, targ2) \
+       tret atomic_swap_##name(volatile targ1 *, targ2); \
+       tret kasan_atomic_swap_##name(volatile targ1 *, targ2); \
+       tret kasan_atomic_swap_##name(volatile targ1 *ptr, targ2 val) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               return atomic_swap_##name(ptr, val); \
+       }
+
+#define ASAN_ATOMIC_FUNC_DEC(name, tret, targ1) \
+       void atomic_dec_##name(volatile targ1 *); \
+       void kasan_atomic_dec_##name(volatile targ1 *); \
+       void kasan_atomic_dec_##name(volatile targ1 *ptr) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               atomic_dec_##name(ptr); \
+       } \
+       tret atomic_dec_##name##_nv(volatile targ1 *); \
+       tret kasan_atomic_dec_##name##_nv(volatile targ1 *); \
+       tret kasan_atomic_dec_##name##_nv(volatile targ1 *ptr) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               return atomic_dec_##name##_nv(ptr); \
+       }
+
+#define ASAN_ATOMIC_FUNC_INC(name, tret, targ1) \
+       void atomic_inc_##name(volatile targ1 *); \
+       void kasan_atomic_inc_##name(volatile targ1 *); \
+       void kasan_atomic_inc_##name(volatile targ1 *ptr) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               atomic_inc_##name(ptr); \
+       } \
+       tret atomic_inc_##name##_nv(volatile targ1 *); \
+       tret kasan_atomic_inc_##name##_nv(volatile targ1 *); \
+       tret kasan_atomic_inc_##name##_nv(volatile targ1 *ptr) \
+       { \
+               kasan_shadow_check((uintptr_t)ptr, sizeof(tret), true, \
+                   __RET_ADDR); \
+               return atomic_inc_##name##_nv(ptr); \
+       }
+
+ASAN_ATOMIC_FUNC_ADD(32, uint32_t, uint32_t, int32_t);
+ASAN_ATOMIC_FUNC_ADD(64, uint64_t, uint64_t, int64_t);
+ASAN_ATOMIC_FUNC_ADD(int, unsigned int, unsigned int, int);
+ASAN_ATOMIC_FUNC_ADD(long, unsigned long, unsigned long, long);
+ASAN_ATOMIC_FUNC_ADD(ptr, void *, void, ssize_t);
+
+ASAN_ATOMIC_FUNC_AND(32, uint32_t, uint32_t, uint32_t);
+ASAN_ATOMIC_FUNC_AND(64, uint64_t, uint64_t, uint64_t);
+ASAN_ATOMIC_FUNC_AND(uint, unsigned int, unsigned int, unsigned int);
+ASAN_ATOMIC_FUNC_AND(ulong, unsigned long, unsigned long, unsigned long);
+
+ASAN_ATOMIC_FUNC_OR(32, uint32_t, uint32_t, uint32_t);
+ASAN_ATOMIC_FUNC_OR(64, uint64_t, uint64_t, uint64_t);
+ASAN_ATOMIC_FUNC_OR(uint, unsigned int, unsigned int, unsigned int);
+ASAN_ATOMIC_FUNC_OR(ulong, unsigned long, unsigned long, unsigned long);
+
+ASAN_ATOMIC_FUNC_CAS(32, uint32_t, uint32_t, uint32_t);
+ASAN_ATOMIC_FUNC_CAS(64, uint64_t, uint64_t, uint64_t);
+ASAN_ATOMIC_FUNC_CAS(uint, unsigned int, unsigned int, unsigned int);
+ASAN_ATOMIC_FUNC_CAS(ulong, unsigned long, unsigned long, unsigned long);
+ASAN_ATOMIC_FUNC_CAS(ptr, void *, void, void *);
+
+ASAN_ATOMIC_FUNC_SWAP(32, uint32_t, uint32_t, uint32_t);
+ASAN_ATOMIC_FUNC_SWAP(64, uint64_t, uint64_t, uint64_t);
+ASAN_ATOMIC_FUNC_SWAP(uint, unsigned int, unsigned int, unsigned int);
+ASAN_ATOMIC_FUNC_SWAP(ulong, unsigned long, unsigned long, unsigned long);
+ASAN_ATOMIC_FUNC_SWAP(ptr, void *, void, void *);
+
+ASAN_ATOMIC_FUNC_DEC(32, uint32_t, uint32_t)
+ASAN_ATOMIC_FUNC_DEC(64, uint64_t, uint64_t)
+ASAN_ATOMIC_FUNC_DEC(uint, unsigned int, unsigned int);
+ASAN_ATOMIC_FUNC_DEC(ulong, unsigned long, unsigned long);
+ASAN_ATOMIC_FUNC_DEC(ptr, void *, void);
+
+ASAN_ATOMIC_FUNC_INC(32, uint32_t, uint32_t)
+ASAN_ATOMIC_FUNC_INC(64, uint64_t, uint64_t)
+ASAN_ATOMIC_FUNC_INC(uint, unsigned int, unsigned int);
+ASAN_ATOMIC_FUNC_INC(ulong, unsigned long, unsigned long);
+ASAN_ATOMIC_FUNC_INC(ptr, void *, void);
+
+/* -------------------------------------------------------------------------- */
+
 void __asan_register_globals(struct __asan_global *, size_t);
 void __asan_unregister_globals(struct __asan_global *, size_t);
 
diff -r 72d8714f22ff -r e4170d4a9c8f sys/sys/atomic.h
--- a/sys/sys/atomic.h  Thu Sep 05 16:17:48 2019 +0000
+++ b/sys/sys/atomic.h  Thu Sep 05 16:19:16 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atomic.h,v 1.13 2015/01/08 22:27:18 riastradh Exp $    */
+/*     $NetBSD: atomic.h,v 1.14 2019/09/05 16:19:16 maxv Exp $ */
 
 /*-
  * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
@@ -37,117 +37,104 @@
 #include <stdint.h>
 #endif
 
+#if defined(_KERNEL) && defined(_KERNEL_OPT)
+#include "opt_kasan.h"
+#endif
+
+#if defined(KASAN)
+#define ATOMIC_PROTO_ADD(name, tret, targ1, targ2) \
+       void kasan_atomic_add_##name(volatile targ1 *, targ2); \
+       tret kasan_atomic_add_##name##_nv(volatile targ1 *, targ2);
+#define ATOMIC_PROTO_AND(name, tret, targ1, targ2) \
+       void kasan_atomic_and_##name(volatile targ1 *, targ2); \
+       tret kasan_atomic_and_##name##_nv(volatile targ1 *, targ2);
+#define ATOMIC_PROTO_OR(name, tret, targ1, targ2) \
+       void kasan_atomic_or_##name(volatile targ1 *, targ2); \
+       tret kasan_atomic_or_##name##_nv(volatile targ1 *, targ2);
+#define ATOMIC_PROTO_CAS(name, tret, targ1, targ2) \
+       tret kasan_atomic_cas_##name(volatile targ1 *, targ2, targ2); \
+       tret kasan_atomic_cas_##name##_ni(volatile targ1 *, targ2, targ2);
+#define ATOMIC_PROTO_SWAP(name, tret, targ1, targ2) \
+       tret kasan_atomic_swap_##name(volatile targ1 *, targ2);
+#define ATOMIC_PROTO_DEC(name, tret, targ1) \
+       void kasan_atomic_dec_##name(volatile targ1 *); \
+       tret kasan_atomic_dec_##name##_nv(volatile targ1 *);
+#define ATOMIC_PROTO_INC(name, tret, targ1) \
+       void kasan_atomic_inc_##name(volatile targ1 *); \
+       tret kasan_atomic_inc_##name##_nv(volatile targ1 *);
+#else
+#define ATOMIC_PROTO_ADD(name, tret, targ1, targ2) \
+       void atomic_add_##name(volatile targ1 *, targ2); \
+       tret atomic_add_##name##_nv(volatile targ1 *, targ2);
+#define ATOMIC_PROTO_AND(name, tret, targ1, targ2) \
+       void atomic_and_##name(volatile targ1 *, targ2); \
+       tret atomic_and_##name##_nv(volatile targ1 *, targ2);
+#define ATOMIC_PROTO_OR(name, tret, targ1, targ2) \
+       void atomic_or_##name(volatile targ1 *, targ2); \
+       tret atomic_or_##name##_nv(volatile targ1 *, targ2);
+#define ATOMIC_PROTO_CAS(name, tret, targ1, targ2) \
+       tret atomic_cas_##name(volatile targ1 *, targ2, targ2); \
+       tret atomic_cas_##name##_ni(volatile targ1 *, targ2, targ2);
+#define ATOMIC_PROTO_SWAP(name, tret, targ1, targ2) \
+       tret atomic_swap_##name(volatile targ1 *, targ2);



Home | Main Index | Thread Index | Old Index