linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v1 1/3] kasan: move memset/memmove/memcpy interceptors in a dedicated file
@ 2019-03-22 14:00 Christophe Leroy
  2019-03-22 14:00 ` [RFC PATCH v1 2/3] lib/string: move sysfs string functions out of string.c Christophe Leroy
  2019-03-22 14:00 ` [RFC PATCH v1 3/3] kasan: add interceptors for all string functions Christophe Leroy
  0 siblings, 2 replies; 3+ messages in thread
From: Christophe Leroy @ 2019-03-22 14:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Nicholas Piggin, Aneesh Kumar K.V, Andrey Ryabinin,
	Alexander Potapenko, Dmitry Vyukov, Daniel Axtens
  Cc: linux-kernel, linuxppc-dev, kasan-dev, linux-mm

In preparation of the addition of interceptors for other string functions,
this patch moves memset/memmove/memcpy interceptions in string.c

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 mm/kasan/Makefile |  5 ++++-
 mm/kasan/common.c | 26 --------------------------
 mm/kasan/string.c | 35 +++++++++++++++++++++++++++++++++++
 3 files changed, 39 insertions(+), 27 deletions(-)
 create mode 100644 mm/kasan/string.c

diff --git a/mm/kasan/Makefile b/mm/kasan/Makefile
index 5d1065efbd47..85e91e301404 100644
--- a/mm/kasan/Makefile
+++ b/mm/kasan/Makefile
@@ -1,11 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0
 KASAN_SANITIZE := n
 UBSAN_SANITIZE_common.o := n
+UBSAN_SANITIZE_string.o := n
 UBSAN_SANITIZE_generic.o := n
 UBSAN_SANITIZE_tags.o := n
 KCOV_INSTRUMENT := n
 
 CFLAGS_REMOVE_common.o = -pg
+CFLAGS_REMOVE_string.o = -pg
 CFLAGS_REMOVE_generic.o = -pg
 CFLAGS_REMOVE_tags.o = -pg
 
@@ -13,9 +15,10 @@ CFLAGS_REMOVE_tags.o = -pg
 # see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63533
 
 CFLAGS_common.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
+CFLAGS_string.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
 CFLAGS_generic.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
 CFLAGS_tags.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
 
-obj-$(CONFIG_KASAN) := common.o init.o report.o
+obj-$(CONFIG_KASAN) := common.o init.o report.o string.o
 obj-$(CONFIG_KASAN_GENERIC) += generic.o generic_report.o quarantine.o
 obj-$(CONFIG_KASAN_SW_TAGS) += tags.o tags_report.o
diff --git a/mm/kasan/common.c b/mm/kasan/common.c
index 80bbe62b16cd..3b94f484bf78 100644
--- a/mm/kasan/common.c
+++ b/mm/kasan/common.c
@@ -109,32 +109,6 @@ void kasan_check_write(const volatile void *p, unsigned int size)
 }
 EXPORT_SYMBOL(kasan_check_write);
 
-#undef memset
-void *memset(void *addr, int c, size_t len)
-{
-	check_memory_region((unsigned long)addr, len, true, _RET_IP_);
-
-	return __memset(addr, c, len);
-}
-
-#undef memmove
-void *memmove(void *dest, const void *src, size_t len)
-{
-	check_memory_region((unsigned long)src, len, false, _RET_IP_);
-	check_memory_region((unsigned long)dest, len, true, _RET_IP_);
-
-	return __memmove(dest, src, len);
-}
-
-#undef memcpy
-void *memcpy(void *dest, const void *src, size_t len)
-{
-	check_memory_region((unsigned long)src, len, false, _RET_IP_);
-	check_memory_region((unsigned long)dest, len, true, _RET_IP_);
-
-	return __memcpy(dest, src, len);
-}
-
 /*
  * Poisons the shadow memory for 'size' bytes starting from 'addr'.
  * Memory addresses should be aligned to KASAN_SHADOW_SCALE_SIZE.
diff --git a/mm/kasan/string.c b/mm/kasan/string.c
new file mode 100644
index 000000000000..f23a740ff985
--- /dev/null
+++ b/mm/kasan/string.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This file contains strings functions for KASAN
+ *
+ */
+
+#include <linux/string.h>
+
+#include "kasan.h"
+
+#undef memset
+void *memset(void *addr, int c, size_t len)
+{
+	check_memory_region((unsigned long)addr, len, true, _RET_IP_);
+
+	return __memset(addr, c, len);
+}
+
+#undef memmove
+void *memmove(void *dest, const void *src, size_t len)
+{
+	check_memory_region((unsigned long)src, len, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, len, true, _RET_IP_);
+
+	return __memmove(dest, src, len);
+}
+
+#undef memcpy
+void *memcpy(void *dest, const void *src, size_t len)
+{
+	check_memory_region((unsigned long)src, len, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, len, true, _RET_IP_);
+
+	return __memcpy(dest, src, len);
+}
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC PATCH v1 2/3] lib/string: move sysfs string functions out of string.c
  2019-03-22 14:00 [RFC PATCH v1 1/3] kasan: move memset/memmove/memcpy interceptors in a dedicated file Christophe Leroy
@ 2019-03-22 14:00 ` Christophe Leroy
  2019-03-22 14:00 ` [RFC PATCH v1 3/3] kasan: add interceptors for all string functions Christophe Leroy
  1 sibling, 0 replies; 3+ messages in thread
From: Christophe Leroy @ 2019-03-22 14:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Nicholas Piggin, Aneesh Kumar K.V, Andrey Ryabinin,
	Alexander Potapenko, Dmitry Vyukov, Daniel Axtens
  Cc: linux-kernel, linuxppc-dev, kasan-dev, linux-mm

In order to implement interceptors for string functions, move
higher level sysfs related string functions out of string.c

This patch creates a new file named string_sysfs.c

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 lib/Makefile       |  3 ++-
 lib/string.c       | 79 ------------------------------------------------------
 lib/string_sysfs.c | 61 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 80 deletions(-)
 create mode 100644 lib/string_sysfs.c

diff --git a/lib/Makefile b/lib/Makefile
index 3b08673e8881..30b9b0bfbba9 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -12,12 +12,13 @@ endif
 # flaky coverage that is not a function of syscall inputs. For example,
 # rbtree can be global and individual rotations don't correlate with inputs.
 KCOV_INSTRUMENT_string.o := n
+KCOV_INSTRUMENT_string_sysfs.o := n
 KCOV_INSTRUMENT_rbtree.o := n
 KCOV_INSTRUMENT_list_debug.o := n
 KCOV_INSTRUMENT_debugobjects.o := n
 KCOV_INSTRUMENT_dynamic_debug.o := n
 
-lib-y := ctype.o string.o vsprintf.o cmdline.o \
+lib-y := ctype.o string.o string_sysfs.o vsprintf.o cmdline.o \
 	 rbtree.o radix-tree.o timerqueue.o xarray.o \
 	 idr.o int_sqrt.o extable.o \
 	 sha1.o chacha.o irq_regs.o argv_split.o \
diff --git a/lib/string.c b/lib/string.c
index 38e4ca08e757..f3886c5175ac 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -605,85 +605,6 @@ char *strsep(char **s, const char *ct)
 EXPORT_SYMBOL(strsep);
 #endif
 
-/**
- * sysfs_streq - return true if strings are equal, modulo trailing newline
- * @s1: one string
- * @s2: another string
- *
- * This routine returns true iff two strings are equal, treating both
- * NUL and newline-then-NUL as equivalent string terminations.  It's
- * geared for use with sysfs input strings, which generally terminate
- * with newlines but are compared against values without newlines.
- */
-bool sysfs_streq(const char *s1, const char *s2)
-{
-	while (*s1 && *s1 == *s2) {
-		s1++;
-		s2++;
-	}
-
-	if (*s1 == *s2)
-		return true;
-	if (!*s1 && *s2 == '\n' && !s2[1])
-		return true;
-	if (*s1 == '\n' && !s1[1] && !*s2)
-		return true;
-	return false;
-}
-EXPORT_SYMBOL(sysfs_streq);
-
-/**
- * match_string - matches given string in an array
- * @array:	array of strings
- * @n:		number of strings in the array or -1 for NULL terminated arrays
- * @string:	string to match with
- *
- * Return:
- * index of a @string in the @array if matches, or %-EINVAL otherwise.
- */
-int match_string(const char * const *array, size_t n, const char *string)
-{
-	int index;
-	const char *item;
-
-	for (index = 0; index < n; index++) {
-		item = array[index];
-		if (!item)
-			break;
-		if (!strcmp(item, string))
-			return index;
-	}
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(match_string);
-
-/**
- * __sysfs_match_string - matches given string in an array
- * @array: array of strings
- * @n: number of strings in the array or -1 for NULL terminated arrays
- * @str: string to match with
- *
- * Returns index of @str in the @array or -EINVAL, just like match_string().
- * Uses sysfs_streq instead of strcmp for matching.
- */
-int __sysfs_match_string(const char * const *array, size_t n, const char *str)
-{
-	const char *item;
-	int index;
-
-	for (index = 0; index < n; index++) {
-		item = array[index];
-		if (!item)
-			break;
-		if (sysfs_streq(item, str))
-			return index;
-	}
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL(__sysfs_match_string);
-
 #ifndef __HAVE_ARCH_MEMSET
 /**
  * memset - Fill a region of memory with the given value
diff --git a/lib/string_sysfs.c b/lib/string_sysfs.c
new file mode 100644
index 000000000000..f2dd384be20d
--- /dev/null
+++ b/lib/string_sysfs.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * stupid library routines for sysfs
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/string.h>
+
+/**
+ * match_string - matches given string in an array
+ * @array:	array of strings
+ * @n:		number of strings in the array or -1 for NULL terminated arrays
+ * @string:	string to match with
+ *
+ * Return:
+ * index of a @string in the @array if matches, or %-EINVAL otherwise.
+ */
+int match_string(const char * const *array, size_t n, const char *string)
+{
+	int index;
+	const char *item;
+
+	for (index = 0; index < n; index++) {
+		item = array[index];
+		if (!item)
+			break;
+		if (!strcmp(item, string))
+			return index;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(match_string);
+
+/**
+ * __sysfs_match_string - matches given string in an array
+ * @array: array of strings
+ * @n: number of strings in the array or -1 for NULL terminated arrays
+ * @str: string to match with
+ *
+ * Returns index of @str in the @array or -EINVAL, just like match_string().
+ * Uses sysfs_streq instead of strcmp for matching.
+ */
+int __sysfs_match_string(const char * const *array, size_t n, const char *str)
+{
+	const char *item;
+	int index;
+
+	for (index = 0; index < n; index++) {
+		item = array[index];
+		if (!item)
+			break;
+		if (sysfs_streq(item, str))
+			return index;
+	}
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(__sysfs_match_string);
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC PATCH v1 3/3] kasan: add interceptors for all string functions
  2019-03-22 14:00 [RFC PATCH v1 1/3] kasan: move memset/memmove/memcpy interceptors in a dedicated file Christophe Leroy
  2019-03-22 14:00 ` [RFC PATCH v1 2/3] lib/string: move sysfs string functions out of string.c Christophe Leroy
@ 2019-03-22 14:00 ` Christophe Leroy
  1 sibling, 0 replies; 3+ messages in thread
From: Christophe Leroy @ 2019-03-22 14:00 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
	Nicholas Piggin, Aneesh Kumar K.V, Andrey Ryabinin,
	Alexander Potapenko, Dmitry Vyukov, Daniel Axtens
  Cc: linux-kernel, linuxppc-dev, kasan-dev, linux-mm

In the same spirit as commit 393f203f5fd5 ("x86_64: kasan: add
interceptors for memset/memmove/memcpy functions"), this patch
adds interceptors for string manipulation functions so that we
can compile lib/string.o without kasan support hence allow the
string functions to also be used from places where kasan has
to be disabled.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 This is the generic part. If we agree on the principle, then I'll
 go through the arches and see if adaptations need to be done there.

 include/linux/string.h |  79 ++++++++++++
 lib/Makefile           |   2 +
 mm/kasan/string.c      | 334 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 415 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index 7927b875f80c..7e7441f4c420 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -19,54 +19,117 @@ extern void *memdup_user_nul(const void __user *, size_t);
  */
 #include <asm/string.h>
 
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+/*
+ * For files that are not instrumented (e.g. mm/slub.c) we
+ * should use not instrumented version of mem* functions.
+ */
+#define memset16	__memset16
+#define memset32	__memset32
+#define memset64	__memset64
+#define memzero_explicit	__memzero_explicit
+#define strcpy		__strcpy
+#define strncpy		__strncpy
+#define strlcpy		__strlcpy
+#define strscpy		__strscpy
+#define strcat		__strcat
+#define strncat		__strncat
+#define strlcat		__strlcat
+#define strcmp		__strcmp
+#define strncmp		__strncmp
+#define strcasecmp	__strcasecmp
+#define strncasecmp	__strncasecmp
+#define strchr		__strchr
+#define strchrnul	__strchrnul
+#define strrchr		__strrchr
+#define strnchr		__strnchr
+#define skip_spaces	__skip_spaces
+#define strim		__strim
+#define strstr		__strstr
+#define strnstr		__strnstr
+#define strlen		__strlen
+#define strnlen		__strnlen
+#define strpbrk		__strpbrk
+#define strsep		__strsep
+#define strspn		__strspn
+#define strcspn		__strcspn
+#define memscan		__memscan
+#define memcmp		__memcmp
+#define memchr		__memchr
+#define memchr_inv	__memchr_inv
+#define strreplace	__strreplace
+
+#ifndef __NO_FORTIFY
+#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
+#endif
+
+#endif
+
 #ifndef __HAVE_ARCH_STRCPY
 extern char * strcpy(char *,const char *);
+char *__strcpy(char *,const char *);
 #endif
 #ifndef __HAVE_ARCH_STRNCPY
 extern char * strncpy(char *,const char *, __kernel_size_t);
+char *__strncpy(char *,const char *, __kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_STRLCPY
 size_t strlcpy(char *, const char *, size_t);
+size_t __strlcpy(char *, const char *, size_t);
 #endif
 #ifndef __HAVE_ARCH_STRSCPY
 ssize_t strscpy(char *, const char *, size_t);
+ssize_t __strscpy(char *, const char *, size_t);
 #endif
 #ifndef __HAVE_ARCH_STRCAT
 extern char * strcat(char *, const char *);
+char *__strcat(char *, const char *);
 #endif
 #ifndef __HAVE_ARCH_STRNCAT
 extern char * strncat(char *, const char *, __kernel_size_t);
+char *__strncat(char *, const char *, __kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_STRLCAT
 extern size_t strlcat(char *, const char *, __kernel_size_t);
+size_t __strlcat(char *, const char *, __kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_STRCMP
 extern int strcmp(const char *,const char *);
+int __strcmp(const char *,const char *);
 #endif
 #ifndef __HAVE_ARCH_STRNCMP
 extern int strncmp(const char *,const char *,__kernel_size_t);
+int __strncmp(const char *,const char *,__kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_STRCASECMP
 extern int strcasecmp(const char *s1, const char *s2);
+int __strcasecmp(const char *s1, const char *s2);
 #endif
 #ifndef __HAVE_ARCH_STRNCASECMP
 extern int strncasecmp(const char *s1, const char *s2, size_t n);
+int __strncasecmp(const char *s1, const char *s2, size_t n);
 #endif
 #ifndef __HAVE_ARCH_STRCHR
 extern char * strchr(const char *,int);
+char *__strchr(const char *,int);
 #endif
 #ifndef __HAVE_ARCH_STRCHRNUL
 extern char * strchrnul(const char *,int);
+char *__strchrnul(const char *,int);
 #endif
 #ifndef __HAVE_ARCH_STRNCHR
 extern char * strnchr(const char *, size_t, int);
+char *__strnchr(const char *, size_t, int);
 #endif
 #ifndef __HAVE_ARCH_STRRCHR
 extern char * strrchr(const char *,int);
+char *__strrchr(const char *,int);
 #endif
 extern char * __must_check skip_spaces(const char *);
+char * __must_check __skip_spaces(const char *);
 
 extern char *strim(char *);
+char *__strim(char *);
 
 static inline __must_check char *strstrip(char *str)
 {
@@ -75,27 +138,35 @@ static inline __must_check char *strstrip(char *str)
 
 #ifndef __HAVE_ARCH_STRSTR
 extern char * strstr(const char *, const char *);
+char *__strstr(const char *, const char *);
 #endif
 #ifndef __HAVE_ARCH_STRNSTR
 extern char * strnstr(const char *, const char *, size_t);
+char *__strnstr(const char *, const char *, size_t);
 #endif
 #ifndef __HAVE_ARCH_STRLEN
 extern __kernel_size_t strlen(const char *);
+__kernel_size_t __strlen(const char *);
 #endif
 #ifndef __HAVE_ARCH_STRNLEN
 extern __kernel_size_t strnlen(const char *,__kernel_size_t);
+__kernel_size_t __strnlen(const char *,__kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_STRPBRK
 extern char * strpbrk(const char *,const char *);
+char *__strpbrk(const char *,const char *);
 #endif
 #ifndef __HAVE_ARCH_STRSEP
 extern char * strsep(char **,const char *);
+char *__strsep(char **,const char *);
 #endif
 #ifndef __HAVE_ARCH_STRSPN
 extern __kernel_size_t strspn(const char *,const char *);
+__kernel_size_t __strspn(const char *,const char *);
 #endif
 #ifndef __HAVE_ARCH_STRCSPN
 extern __kernel_size_t strcspn(const char *,const char *);
+__kernel_size_t __strcspn(const char *,const char *);
 #endif
 
 #ifndef __HAVE_ARCH_MEMSET
@@ -104,14 +175,17 @@ extern void * memset(void *,int,__kernel_size_t);
 
 #ifndef __HAVE_ARCH_MEMSET16
 extern void *memset16(uint16_t *, uint16_t, __kernel_size_t);
+void *__memset16(uint16_t *, uint16_t, __kernel_size_t);
 #endif
 
 #ifndef __HAVE_ARCH_MEMSET32
 extern void *memset32(uint32_t *, uint32_t, __kernel_size_t);
+void *__memset32(uint32_t *, uint32_t, __kernel_size_t);
 #endif
 
 #ifndef __HAVE_ARCH_MEMSET64
 extern void *memset64(uint64_t *, uint64_t, __kernel_size_t);
+void *__memset64(uint64_t *, uint64_t, __kernel_size_t);
 #endif
 
 static inline void *memset_l(unsigned long *p, unsigned long v,
@@ -146,12 +220,15 @@ extern void * memmove(void *,const void *,__kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_MEMSCAN
 extern void * memscan(void *,int,__kernel_size_t);
+void *__memscan(void *,int,__kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_MEMCMP
 extern int memcmp(const void *,const void *,__kernel_size_t);
+int __memcmp(const void *,const void *,__kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_MEMCHR
 extern void * memchr(const void *,int,__kernel_size_t);
+void *__memchr(const void *,int,__kernel_size_t);
 #endif
 #ifndef __HAVE_ARCH_MEMCPY_MCSAFE
 static inline __must_check unsigned long memcpy_mcsafe(void *dst,
@@ -168,7 +245,9 @@ static inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)
 }
 #endif
 void *memchr_inv(const void *s, int c, size_t n);
+void *__memchr_inv(const void *s, int c, size_t n);
 char *strreplace(char *s, char old, char new);
+char *__strreplace(char *s, char old, char new);
 
 extern void kfree_const(const void *x);
 
diff --git a/lib/Makefile b/lib/Makefile
index 30b9b0bfbba9..19d0237f9b9c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -18,6 +18,8 @@ KCOV_INSTRUMENT_list_debug.o := n
 KCOV_INSTRUMENT_debugobjects.o := n
 KCOV_INSTRUMENT_dynamic_debug.o := n
 
+KASAN_SANITIZE_string.o := n
+
 lib-y := ctype.o string.o string_sysfs.o vsprintf.o cmdline.o \
 	 rbtree.o radix-tree.o timerqueue.o xarray.o \
 	 idr.o int_sqrt.o extable.o \
diff --git a/mm/kasan/string.c b/mm/kasan/string.c
index f23a740ff985..9a86b422e2e7 100644
--- a/mm/kasan/string.c
+++ b/mm/kasan/string.c
@@ -16,6 +16,38 @@ void *memset(void *addr, int c, size_t len)
 	return __memset(addr, c, len);
 }
 
+#undef memset16
+void *memset16(uint16_t *s, uint16_t v, size_t count)
+{
+	check_memory_region((unsigned long)s, count << 1, true, _RET_IP_);
+
+	return __memset16(s, v, count);
+}
+
+#undef memset32
+void *memset32(uint32_t *s, uint32_t v, size_t count)
+{
+	check_memory_region((unsigned long)s, count << 2, true, _RET_IP_);
+
+	return __memset32(s, v, count);
+}
+
+#undef memset64
+void *memset64(uint64_t *s, uint64_t v, size_t count)
+{
+	check_memory_region((unsigned long)s, count << 3, true, _RET_IP_);
+
+	return __memset64(s, v, count);
+}
+
+#undef memzero_explicit
+void memzero_explicit(void *s, size_t count)
+{
+	check_memory_region((unsigned long)s, count, true, _RET_IP_);
+
+	return __memzero_explicit(s, count);
+}
+
 #undef memmove
 void *memmove(void *dest, const void *src, size_t len)
 {
@@ -33,3 +65,305 @@ void *memcpy(void *dest, const void *src, size_t len)
 
 	return __memcpy(dest, src, len);
 }
+
+#undef strcpy
+char *strcpy(char *dest, const char *src)
+{
+	size_t len = __strlen(src) + 1;
+
+	check_memory_region((unsigned long)src, len, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, len, true, _RET_IP_);
+
+	return __strcpy(dest, src);
+}
+
+#undef strncpy
+char *strncpy(char *dest, const char *src, size_t count)
+{
+	size_t len = min(__strlen(src) + 1, count);
+
+	check_memory_region((unsigned long)src, len, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, count, true, _RET_IP_);
+
+	return __strncpy(dest, src, count);
+}
+
+#undef strlcpy
+size_t strlcpy(char *dest, const char *src, size_t size)
+{
+	size_t len = __strlen(src) + 1;
+
+	check_memory_region((unsigned long)src, len, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, min(len, size), true, _RET_IP_);
+
+	return __strlcpy(dest, src, size);
+}
+
+#undef strscpy
+ssize_t strscpy(char *dest, const char *src, size_t count)
+{
+	int len = min(__strlen(src) + 1, count);
+
+	check_memory_region((unsigned long)src, len, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, len, true, _RET_IP_);
+
+	return __strscpy(dest, src, count);
+}
+
+#undef strcat
+char *strcat(char *dest, const char *src)
+{
+	size_t slen = __strlen(src) + 1;
+	size_t dlen = __strlen(dest);
+
+	check_memory_region((unsigned long)src, slen, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, dlen, false, _RET_IP_);
+	check_memory_region((unsigned long)(dest + dlen), slen, true, _RET_IP_);
+
+	return __strcat(dest, src);
+}
+
+char *strncat(char *dest, const char *src, size_t count)
+{
+	size_t slen = min(__strlen(src) + 1, count);
+	size_t dlen = __strlen(dest);
+
+	check_memory_region((unsigned long)src, slen, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, dlen, false, _RET_IP_);
+	check_memory_region((unsigned long)(dest + dlen), slen , true, _RET_IP_);
+
+	return __strncat(dest, src, count);
+}
+
+size_t strlcat(char *dest, const char *src, size_t count)
+{
+	size_t slen = min(__strlen(src) + 1, count);
+	size_t dlen = __strlen(dest);
+
+	check_memory_region((unsigned long)src, slen, false, _RET_IP_);
+	check_memory_region((unsigned long)dest, dlen, false, _RET_IP_);
+	check_memory_region((unsigned long)(dest + dlen), slen , true, _RET_IP_);
+
+	return __strlcat(dest, src, count);
+}
+
+int strcmp(const char *cs, const char *ct)
+{
+	size_t len = min(__strlen(cs) + 1, __strlen(ct) + 1);
+
+	check_memory_region((unsigned long)cs, len, false, _RET_IP_);
+	check_memory_region((unsigned long)ct, len, false, _RET_IP_);
+
+	return __strcmp(cs, ct);
+}
+
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+	size_t len = min3(__strlen(cs) + 1, __strlen(ct) + 1, count);
+
+	check_memory_region((unsigned long)cs, len, false, _RET_IP_);
+	check_memory_region((unsigned long)ct, len, false, _RET_IP_);
+
+	return __strncmp(cs, ct, count);
+}
+
+int strcasecmp(const char *s1, const char *s2)
+{
+	size_t len = min(__strlen(s1) + 1, __strlen(s2) + 1);
+
+	check_memory_region((unsigned long)s1, len, false, _RET_IP_);
+	check_memory_region((unsigned long)s2, len, false, _RET_IP_);
+
+	return __strcasecmp(s1, s2);
+}
+
+int strncasecmp(const char *s1, const char *s2, size_t len)
+{
+	size_t sz = min3(__strlen(s1) + 1, __strlen(s2) + 1, len);
+
+	check_memory_region((unsigned long)s1, sz, false, _RET_IP_);
+	check_memory_region((unsigned long)s2, sz, false, _RET_IP_);
+
+	return __strncasecmp(s1, s2, len);
+}
+
+char *strchr(const char *s, int c)
+{
+	size_t len = __strlen(s) + 1;
+
+	check_memory_region((unsigned long)s, len, false, _RET_IP_);
+
+	return __strchr(s, c);
+}
+
+char *strchrnul(const char *s, int c)
+{
+	size_t len = __strlen(s) + 1;
+
+	check_memory_region((unsigned long)s, len, false, _RET_IP_);
+
+	return __strchrnul(s, c);
+}
+
+char *strrchr(const char *s, int c)
+{
+	size_t len = __strlen(s) + 1;
+
+	check_memory_region((unsigned long)s, len, false, _RET_IP_);
+
+	return __strrchr(s, c);
+}
+
+char *strnchr(const char *s, size_t count, int c)
+{
+	size_t len = __strlen(s) + 1;
+
+	check_memory_region((unsigned long)s, len, false, _RET_IP_);
+
+	return __strnchr(s, count, c);
+}
+
+char *skip_spaces(const char *str)
+{
+	size_t len = __strlen(str) + 1;
+
+	check_memory_region((unsigned long)str, len, false, _RET_IP_);
+
+	return __skip_spaces(str);
+}
+
+char *strim(char *s)
+{
+	size_t len = __strlen(s) + 1;
+
+	check_memory_region((unsigned long)s, len, false, _RET_IP_);
+
+	return __strim(s);
+}
+
+char *strstr(const char *s1, const char *s2)
+{
+	size_t l1 = __strlen(s1) + 1;
+	size_t l2 = __strlen(s2) + 1;
+
+	check_memory_region((unsigned long)s1, l1, false, _RET_IP_);
+	check_memory_region((unsigned long)s2, l2, false, _RET_IP_);
+
+	return __strstr(s1, s2);
+}
+
+char *strnstr(const char *s1, const char *s2, size_t len)
+{
+	size_t l1 = min(__strlen(s1) + 1, len);
+	size_t l2 = __strlen(s2) + 1;
+
+	check_memory_region((unsigned long)s1, l1, false, _RET_IP_);
+	check_memory_region((unsigned long)s2, l2, false, _RET_IP_);
+
+	return __strnstr(s1, s2, len);
+}
+
+size_t strlen(const char *s)
+{
+	size_t len = __strlen(s);
+
+	check_memory_region((unsigned long)s, len + 1, false, _RET_IP_);
+
+	return len;
+}
+
+size_t strnlen(const char *s, size_t count)
+{
+	size_t len = __strnlen(s, count);
+
+	check_memory_region((unsigned long)s, min(len + 1, count), false, _RET_IP_);
+
+	return len;
+}
+
+char *strpbrk(const char *cs, const char *ct)
+{
+	size_t ls = __strlen(cs) + 1;
+	size_t lt = __strlen(ct) + 1;
+
+	check_memory_region((unsigned long)cs, ls, false, _RET_IP_);
+	check_memory_region((unsigned long)ct, lt, false, _RET_IP_);
+
+	return __strpbrk(cs, ct);
+}
+char *strsep(char **s, const char *ct)
+{
+	char *cs = *s;
+
+	check_memory_region((unsigned long)s, sizeof(*s), true, _RET_IP_);
+
+	if (cs) {
+		int ls = __strlen(cs) + 1;
+		int lt = __strlen(ct) + 1;
+
+		check_memory_region((unsigned long)cs, ls, false, _RET_IP_);
+		check_memory_region((unsigned long)ct, lt, false, _RET_IP_);
+	}
+
+	return __strsep(s, ct);
+}
+
+size_t strspn(const char *s, const char *accept)
+{
+	size_t ls = __strlen(s) + 1;
+	size_t la = __strlen(accept) + 1;
+
+	check_memory_region((unsigned long)s, ls, false, _RET_IP_);
+	check_memory_region((unsigned long)accept, la, false, _RET_IP_);
+
+	return __strspn(s, accept);
+}
+
+size_t strcspn(const char *s, const char *reject)
+{
+	size_t ls = __strlen(s) + 1;
+	size_t lr = __strlen(reject) + 1;
+
+	check_memory_region((unsigned long)s, ls, false, _RET_IP_);
+	check_memory_region((unsigned long)reject, lr, false, _RET_IP_);
+
+	return __strcspn(s, reject);
+}
+
+void *memscan(void *addr, int c, size_t size)
+{
+	check_memory_region((unsigned long)addr, size, false, _RET_IP_);
+
+	return __memscan(addr, c, size);
+}
+
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+	check_memory_region((unsigned long)cs, count, false, _RET_IP_);
+	check_memory_region((unsigned long)ct, count, false, _RET_IP_);
+
+	return __memcmp(cs, ct, count);
+}
+
+void *memchr(const void *s, int c, size_t n)
+{
+	check_memory_region((unsigned long)s, n, false, _RET_IP_);
+
+	return __memchr(s, c, n);
+}
+
+void *memchr_inv(const void *start, int c, size_t bytes)
+{
+	check_memory_region((unsigned long)start, bytes, false, _RET_IP_);
+
+	return __memchr_inv(start, c, bytes);
+}
+
+char *strreplace(char *s, char old, char new)
+{
+	size_t len = __strlen(s) + 1;
+
+	check_memory_region((unsigned long)s, len, true, _RET_IP_);
+
+	return __strreplace(s, old, new);
+}
-- 
2.13.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-03-22 14:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-22 14:00 [RFC PATCH v1 1/3] kasan: move memset/memmove/memcpy interceptors in a dedicated file Christophe Leroy
2019-03-22 14:00 ` [RFC PATCH v1 2/3] lib/string: move sysfs string functions out of string.c Christophe Leroy
2019-03-22 14:00 ` [RFC PATCH v1 3/3] kasan: add interceptors for all string functions Christophe Leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).