summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authormaxv <maxv@NetBSD.org>2019-11-22 14:28:46 +0000
committermaxv <maxv@NetBSD.org>2019-11-22 14:28:46 +0000
commitafcac815722c8edda2f493fc4e8059027467883f (patch)
tree7657bfa0f7ae0d86dbf7df3792f939ab9df47824 /sys
parent856d965f09fb16f5c1754d23a260d3a5e66a96c1 (diff)
Ah, strcat/strchr/strrchr are ASM functions, so instrument them.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_msan.c53
-rw-r--r--sys/lib/libkern/libkern.h15
2 files changed, 61 insertions, 7 deletions
diff --git a/sys/kern/subr_msan.c b/sys/kern/subr_msan.c
index cca63f08a45..fb0cc73f043 100644
--- a/sys/kern/subr_msan.c
+++ b/sys/kern/subr_msan.c
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_msan.c,v 1.2 2019/11/15 12:18:46 maxv Exp $ */
+/* $NetBSD: subr_msan.c,v 1.3 2019/11/22 14:28:46 maxv Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
#define KMSAN_NO_INST
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_msan.c,v 1.2 2019/11/15 12:18:46 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_msan.c,v 1.3 2019/11/22 14:28:46 maxv Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -187,7 +187,7 @@ kmsan_report_hook(const void *addr, size_t size, size_t off, const char *hook)
var = (char *)ptr + 4;
strlcpy(buf, var, sizeof(buf));
var = buf;
- fn = strchr(buf, '@');
+ fn = __builtin_strchr(buf, '@');
*fn++ = '\0';
REPORT("MSan: Uninitialized %s Memory In %s() At Offset "
"%zu, Variable '%s' From %s()\n", typename, hook, off,
@@ -238,7 +238,7 @@ kmsan_report_inline(msan_orig_t orig, unsigned long pc)
var = (char *)ptr + 4;
strlcpy(buf, var, sizeof(buf));
var = buf;
- fn = strchr(buf, '@');
+ fn = __builtin_strchr(buf, '@');
*fn++ = '\0';
REPORT("MSan: Uninitialized Variable '%s' From %s()\n",
var, fn);
@@ -754,6 +754,51 @@ kmsan_strlen(const char *str)
return (s - str);
}
+char *
+kmsan_strcat(char *dst, const char *src)
+{
+ size_t ldst, lsrc;
+ char *ret;
+
+ kmsan_check_arg(sizeof(dst) + sizeof(src), "strcat");
+
+ ldst = __builtin_strlen(dst);
+ lsrc = __builtin_strlen(src);
+ kmsan_shadow_check(dst, ldst + 1, "strcat");
+ kmsan_shadow_check(src, lsrc + 1, "strcat");
+ ret = __builtin_strcat(dst, src);
+ kmsan_shadow_fill(dst, KMSAN_STATE_INITED, ldst + lsrc + 1);
+
+ kmsan_init_ret(sizeof(char *));
+ return ret;
+}
+
+char *
+kmsan_strchr(const char *s, int c)
+{
+ char *ret;
+
+ kmsan_check_arg(sizeof(s) + sizeof(c), "strchr");
+ kmsan_shadow_check(s, __builtin_strlen(s), "strchr");
+ ret = __builtin_strchr(s, c);
+
+ kmsan_init_ret(sizeof(char *));
+ return ret;
+}
+
+char *
+kmsan_strrchr(const char *s, int c)
+{
+ char *ret;
+
+ kmsan_check_arg(sizeof(s) + sizeof(c), "strrchr");
+ kmsan_shadow_check(s, __builtin_strlen(s), "strrchr");
+ ret = __builtin_strrchr(s, c);
+
+ kmsan_init_ret(sizeof(char *));
+ return ret;
+}
+
#undef kcopy
#undef copystr
#undef copyin
diff --git a/sys/lib/libkern/libkern.h b/sys/lib/libkern/libkern.h
index f22bb638665..d876601de5e 100644
--- a/sys/lib/libkern/libkern.h
+++ b/sys/lib/libkern/libkern.h
@@ -1,4 +1,4 @@
-/* $NetBSD: libkern.h,v 1.134 2019/11/14 16:23:53 maxv Exp $ */
+/* $NetBSD: libkern.h,v 1.135 2019/11/22 14:28:46 maxv Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -438,13 +438,22 @@ size_t kmsan_strlen(const char *);
#endif
/* These exist in GCC 3.x, but we don't bother. */
+#if defined(_KERNEL) && defined(KMSAN)
+char *kmsan_strcat(char *, const char *);
+char *kmsan_strchr(const char *, int);
+char *kmsan_strrchr(const char *, int);
+#define strcat(d, s) kmsan_strcat(d, s)
+#define strchr(s, c) kmsan_strchr(s, c)
+#define strrchr(s, c) kmsan_strrchr(s, c)
+#else
char *strcat(char *, const char *);
+char *strchr(const char *, int);
+char *strrchr(const char *, int);
+#endif
size_t strcspn(const char *, const char *);
char *strncpy(char *, const char *, size_t);
char *strncat(char *, const char *, size_t);
int strncmp(const char *, const char *, size_t);
-char *strchr(const char *, int);
-char *strrchr(const char *, int);
char *strstr(const char *, const char *);
char *strpbrk(const char *, const char *);
size_t strspn(const char *, const char *);