Thu Oct 10 13:45:14 2019 UTC ()
Add KASAN instrumentation on ucas and ufetch.


(maxv)
diff -r1.15 -r1.16 src/sys/kern/subr_asan.c
diff -r1.286 -r1.287 src/sys/sys/systm.h

cvs diff -r1.15 -r1.16 src/sys/kern/subr_asan.c (expand / switch to context diff)
--- src/sys/kern/subr_asan.c 2019/10/04 06:27:42 1.15
+++ src/sys/kern/subr_asan.c 2019/10/10 13:45:14 1.16
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_asan.c,v 1.15 2019/10/04 06:27:42 maxv Exp $	*/
+/*	$NetBSD: subr_asan.c,v 1.16 2019/10/10 13:45:14 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_asan.c,v 1.15 2019/10/04 06:27:42 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_asan.c,v 1.16 2019/10/10 13:45:14 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -556,6 +556,109 @@
 	kasan_shadow_check((unsigned long)kaddr, len, false, __RET_ADDR);
 	return copyoutstr(kaddr, uaddr, len, done);
 }
+
+/* -------------------------------------------------------------------------- */
+
+#undef _ucas_32
+#undef _ucas_32_mp
+#undef _ucas_64
+#undef _ucas_64_mp
+#undef _ufetch_8
+#undef _ufetch_16
+#undef _ufetch_32
+#undef _ufetch_64
+
+int _ucas_32(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
+int kasan__ucas_32(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
+int
+kasan__ucas_32(volatile uint32_t *uaddr, uint32_t old, uint32_t new,
+    uint32_t *ret)
+{
+	kasan_shadow_check((unsigned long)ret, sizeof(*ret), true,
+	    __RET_ADDR);
+	return _ucas_32(uaddr, old, new, ret);
+}
+
+#ifdef __HAVE_UCAS_MP
+int _ucas_32_mp(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
+int kasan__ucas_32_mp(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
+int
+kasan__ucas_32_mp(volatile uint32_t *uaddr, uint32_t old, uint32_t new,
+    uint32_t *ret)
+{
+	kasan_shadow_check((unsigned long)ret, sizeof(*ret), true,
+	    __RET_ADDR);
+	return _ucas_32_mp(uaddr, old, new, ret);
+}
+#endif
+
+#ifdef _LP64
+int _ucas_64(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
+int kasan__ucas_64(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
+int
+kasan__ucas_64(volatile uint64_t *uaddr, uint64_t old, uint64_t new,
+    uint64_t *ret)
+{
+	kasan_shadow_check((unsigned long)ret, sizeof(*ret), true,
+	    __RET_ADDR);
+	return _ucas_64(uaddr, old, new, ret);
+}
+
+#ifdef __HAVE_UCAS_MP
+int _ucas_64_mp(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
+int kasan__ucas_64_mp(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
+int
+kasan__ucas_64_mp(volatile uint64_t *uaddr, uint64_t old, uint64_t new,
+    uint64_t *ret)
+{
+	kasan_shadow_check((unsigned long)ret, sizeof(*ret), true,
+	    __RET_ADDR);
+	return _ucas_64_mp(uaddr, old, new, ret);
+}
+#endif
+#endif
+
+int _ufetch_8(const uint8_t *, uint8_t *);
+int kasan__ufetch_8(const uint8_t *, uint8_t *);
+int
+kasan__ufetch_8(const uint8_t *uaddr, uint8_t *valp)
+{
+	kasan_shadow_check((unsigned long)valp, sizeof(*valp), true,
+	    __RET_ADDR);
+	return _ufetch_8(uaddr, valp);
+}
+
+int _ufetch_16(const uint16_t *, uint16_t *);
+int kasan__ufetch_16(const uint16_t *, uint16_t *);
+int
+kasan__ufetch_16(const uint16_t *uaddr, uint16_t *valp)
+{
+	kasan_shadow_check((unsigned long)valp, sizeof(*valp), true,
+	    __RET_ADDR);
+	return _ufetch_16(uaddr, valp);
+}
+
+int _ufetch_32(const uint32_t *, uint32_t *);
+int kasan__ufetch_32(const uint32_t *, uint32_t *);
+int
+kasan__ufetch_32(const uint32_t *uaddr, uint32_t *valp)
+{
+	kasan_shadow_check((unsigned long)valp, sizeof(*valp), true,
+	    __RET_ADDR);
+	return _ufetch_32(uaddr, valp);
+}
+
+#ifdef _LP64
+int _ufetch_64(const uint64_t *, uint64_t *);
+int kasan__ufetch_64(const uint64_t *, uint64_t *);
+int
+kasan__ufetch_64(const uint64_t *uaddr, uint64_t *valp)
+{
+	kasan_shadow_check((unsigned long)valp, sizeof(*valp), true,
+	    __RET_ADDR);
+	return _ufetch_64(uaddr, valp);
+}
+#endif
 
 /* -------------------------------------------------------------------------- */
 

cvs diff -r1.286 -r1.287 src/sys/sys/systm.h (expand / switch to context diff)
--- src/sys/sys/systm.h 2019/07/23 17:39:36 1.286
+++ src/sys/sys/systm.h 2019/10/10 13:45:14 1.287
@@ -1,4 +1,4 @@
-/*	$NetBSD: systm.h,v 1.286 2019/07/23 17:39:36 rin Exp $	*/
+/*	$NetBSD: systm.h,v 1.287 2019/10/10 13:45:14 maxv Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1988, 1991, 1993
@@ -43,6 +43,7 @@
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
 #include "opt_gprof.h"
+#include "opt_kasan.h"
 #include "opt_kleak.h"
 #include "opt_wsdisplay_compat.h"
 #endif
@@ -319,74 +320,102 @@
 int	ioctl_copyin(int ioctlflags, const void *src, void *dst, size_t len);
 int	ioctl_copyout(int ioctlflags, const void *src, void *dst, size_t len);
 
-int	ucas_32(volatile uint32_t *uaddr, uint32_t old, uint32_t new,
-		uint32_t *ret);
+int	ucas_32(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
 #ifdef _LP64
-int	ucas_64(volatile uint64_t *uaddr, uint64_t old, uint64_t new,
-		uint64_t *ret);
-#endif /* _LP64 */
-
+int	ucas_64(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
+#endif
 int	ucas_ptr(volatile void *, void *, void *, void *);
 int	ucas_int(volatile unsigned int *, unsigned int, unsigned int,
 		 unsigned int *);
+int	ufetch_8(const uint8_t *, uint8_t *);
+int	ufetch_16(const uint16_t *, uint16_t *);
+int	ufetch_32(const uint32_t *, uint32_t *);
+#ifdef _LP64
+int	ufetch_64(const uint64_t *, uint64_t *);
+#endif
+int	ufetch_char(const unsigned char *, unsigned char *);
+int	ufetch_short(const unsigned short *, unsigned short *);
+int	ufetch_int(const unsigned int *, unsigned int *);
+int	ufetch_long(const unsigned long *, unsigned long *);
+int	ufetch_ptr(const void **, void **);
+int	ustore_8(uint8_t *, uint8_t);
+int	ustore_16(uint16_t *, uint16_t);
+int	ustore_32(uint32_t *, uint32_t);
+#ifdef _LP64
+int	ustore_64(uint64_t *, uint64_t);
+#endif
+int	ustore_char(unsigned char *, unsigned char);
+int	ustore_short(unsigned short *, unsigned short);
+int	ustore_int(unsigned int *, unsigned int);
+int	ustore_long(unsigned long *, unsigned long);
+int	ustore_ptr(void **, void *);
 
 #ifdef __UCAS_PRIVATE
-int	_ucas_32(volatile uint32_t *uaddr, uint32_t old, uint32_t new,
-		 uint32_t *ret);
+
+#if defined(KASAN)
+int	kasan__ucas_32(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
 #ifdef __HAVE_UCAS_MP
-int	_ucas_32_mp(volatile uint32_t *uaddr, uint32_t old, uint32_t new,
-		    uint32_t *ret);
+int	kasan__ucas_32_mp(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
 #endif /* __HAVE_UCAS_MP */
 #ifdef _LP64
-int	_ucas_64(volatile uint64_t *uaddr, uint64_t old, uint64_t new,
-		 uint64_t *ret);
+int	kasan__ucas_64(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
 #ifdef __HAVE_UCAS_MP
-int	_ucas_64_mp(volatile uint64_t *uaddr, uint64_t old, uint64_t new,
-		    uint64_t *ret);
+int	kasan__ucas_64_mp(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
 #endif /* __HAVE_UCAS_MP */
 #endif /* _LP64 */
-#endif /* __UCAS_PRIVATE */
-
-int	ufetch_8(const uint8_t *uaddr, uint8_t *valp);
-int	ufetch_16(const uint16_t *uaddr, uint16_t *valp);
-int	ufetch_32(const uint32_t *uaddr, uint32_t *valp);
+#define _ucas_32	kasan__ucas_32
+#define _ucas_32_mp	kasan__ucas_32_mp
+#define _ucas_64	kasan__ucas_64
+#define _ucas_64_mp	kasan__ucas_64_mp
+#else
+int	_ucas_32(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
+#ifdef __HAVE_UCAS_MP
+int	_ucas_32_mp(volatile uint32_t *, uint32_t, uint32_t, uint32_t *);
+#endif /* __HAVE_UCAS_MP */
 #ifdef _LP64
-int	ufetch_64(const uint64_t *uaddr, uint64_t *valp);
+int	_ucas_64(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
+#ifdef __HAVE_UCAS_MP
+int	_ucas_64_mp(volatile uint64_t *, uint64_t, uint64_t, uint64_t *);
+#endif /* __HAVE_UCAS_MP */
+#endif /* _LP64 */
 #endif
 
-int	ufetch_char(const unsigned char *uaddr, unsigned char *valp);
-int	ufetch_short(const unsigned short *uaddr, unsigned short *valp);
-int	ufetch_int(const unsigned int *uaddr, unsigned int *valp);
-int	ufetch_long(const unsigned long *uaddr, unsigned long *valp);
-int	ufetch_ptr(const void **uaddr, void **valp);
+#endif /* __UCAS_PRIVATE */
 
-int	ustore_8(uint8_t *uaddr, uint8_t val);
-int	ustore_16(uint16_t *uaddr, uint16_t val);
-int	ustore_32(uint32_t *uaddr, uint32_t val);
+#ifdef __UFETCHSTORE_PRIVATE
+
+#if defined(KASAN)
+int	kasan__ufetch_8(const uint8_t *, uint8_t *);
+int	kasan__ufetch_16(const uint16_t *, uint16_t *);
+int	kasan__ufetch_32(const uint32_t *, uint32_t *);
 #ifdef _LP64
-int	ustore_64(uint64_t *uaddr, uint64_t val);
+int	kasan__ufetch_64(const uint64_t *, uint64_t *);
 #endif
-
-int	ustore_char(unsigned char *uaddr, unsigned char val);
-int	ustore_short(unsigned short *uaddr, unsigned short val);
-int	ustore_int(unsigned int *uaddr, unsigned int val);
-int	ustore_long(unsigned long *uaddr, unsigned long val);
-int	ustore_ptr(void **uaddr, void *val);
-
-#ifdef __UFETCHSTORE_PRIVATE
-int	_ufetch_8(const uint8_t *uaddr, uint8_t *valp);
-int	_ufetch_16(const uint16_t *uaddr, uint16_t *valp);
-int	_ufetch_32(const uint32_t *uaddr, uint32_t *valp);
+int	_ustore_8(uint8_t *, uint8_t);
+int	_ustore_16(uint16_t *, uint16_t);
+int	_ustore_32(uint32_t *, uint32_t);
 #ifdef _LP64
-int	_ufetch_64(const uint64_t *uaddr, uint64_t *valp);
+int	_ustore_64(uint64_t *, uint64_t);
 #endif
-
-int	_ustore_8(uint8_t *uaddr, uint8_t val);
-int	_ustore_16(uint16_t *uaddr, uint16_t val);
-int	_ustore_32(uint32_t *uaddr, uint32_t val);
+#define _ufetch_8	kasan__ufetch_8
+#define _ufetch_16	kasan__ufetch_16
+#define _ufetch_32	kasan__ufetch_32
+#define _ufetch_64	kasan__ufetch_64
+#else
+int	_ufetch_8(const uint8_t *, uint8_t *);
+int	_ufetch_16(const uint16_t *, uint16_t *);
+int	_ufetch_32(const uint32_t *, uint32_t *);
 #ifdef _LP64
-int	_ustore_64(uint64_t *uaddr, uint64_t val);
+int	_ufetch_64(const uint64_t *, uint64_t *);
 #endif
+int	_ustore_8(uint8_t *, uint8_t);
+int	_ustore_16(uint16_t *, uint16_t);
+int	_ustore_32(uint32_t *, uint32_t);
+#ifdef _LP64
+int	_ustore_64(uint64_t *, uint64_t);
+#endif
+#endif
+
 #endif /* __UFETCHSTORE_PRIVATE */
 
 void	hardclock(struct clockframe *);