From: Kees Cook <keescook@chromium.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
Daniel Micay <danielmicay@gmail.com>,
Dan Williams <dan.j.williams@intel.com>,
Mika Westerberg <mika.westerberg@linux.intel.com>,
Al Viro <viro@zeniv.linux.org.uk>,
David Howells <dhowells@redhat.com>,
Heikki Krogerus <heikki.krogerus@linux.intel.com>,
Bjorn Helgaas <bhelgaas@google.com>,
Arnd Bergmann <arnd@arndb.de>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH] fortify: Use WARN instead of BUG for now
Date: Tue, 25 Jul 2017 20:50:36 -0700 [thread overview]
Message-ID: <20170726035036.GA76341@beast> (raw)
While CONFIG_FORTIFY_SOURCE continues to shake out, don't unconditionally
use BUG(), opting instead for WARN(). At the same time, expand the runtime
detection to provide a better hint about what went wrong.
Cc: Daniel Micay <danielmicay@gmail.com>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
Sending to akpm, since fortify went through -mm originally.
---
include/linux/string.h | 48 ++++++++++++++++++++++++++++++------------------
lib/string.c | 19 +++++++++++++++----
2 files changed, 45 insertions(+), 22 deletions(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index a467e617eeb0..97468047b965 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -197,7 +197,10 @@ static inline const char *kbasename(const char *path)
#define __FORTIFY_INLINE extern __always_inline __attribute__((gnu_inline))
#define __RENAME(x) __asm__(#x)
-void fortify_panic(const char *name) __noreturn __cold;
+void fortify_read_overflow(const char *func) __cold;
+void fortify_read_overflow2(const char *func) __cold;
+void fortify_write_overflow(const char *func) __cold;
+
void __read_overflow(void) __compiletime_error("detected read beyond size of object passed as 1st parameter");
void __read_overflow2(void) __compiletime_error("detected read beyond size of object passed as 2nd parameter");
void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
@@ -209,7 +212,7 @@ __FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
if (__builtin_constant_p(size) && p_size < size)
__write_overflow();
if (p_size < size)
- fortify_panic(__func__);
+ fortify_write_overflow(__func__);
return __builtin_strncpy(p, q, size);
}
@@ -219,7 +222,7 @@ __FORTIFY_INLINE char *strcat(char *p, const char *q)
if (p_size == (size_t)-1)
return __builtin_strcat(p, q);
if (strlcat(p, q, p_size) >= p_size)
- fortify_panic(__func__);
+ fortify_write_overflow(__func__);
return p;
}
@@ -231,7 +234,7 @@ __FORTIFY_INLINE __kernel_size_t strlen(const char *p)
return __builtin_strlen(p);
ret = strnlen(p, p_size);
if (p_size <= ret)
- fortify_panic(__func__);
+ fortify_read_overflow(__func__);
return ret;
}
@@ -241,7 +244,7 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
size_t p_size = __builtin_object_size(p, 0);
__kernel_size_t ret = __real_strnlen(p, maxlen < p_size ? maxlen : p_size);
if (p_size <= ret && maxlen != ret)
- fortify_panic(__func__);
+ fortify_read_overflow(__func__);
return ret;
}
@@ -260,7 +263,7 @@ __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
if (__builtin_constant_p(len) && len >= p_size)
__write_overflow();
if (len >= p_size)
- fortify_panic(__func__);
+ fortify_write_overflow(__func__);
__builtin_memcpy(p, q, len);
p[len] = '\0';
}
@@ -278,7 +281,7 @@ __FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
p_len = strlen(p);
copy_len = strnlen(q, count);
if (p_size < p_len + copy_len + 1)
- fortify_panic(__func__);
+ fortify_write_overflow(__func__);
__builtin_memcpy(p + p_len, q, copy_len);
p[p_len + copy_len] = '\0';
return p;
@@ -290,7 +293,7 @@ __FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size)
if (__builtin_constant_p(size) && p_size < size)
__write_overflow();
if (p_size < size)
- fortify_panic(__func__);
+ fortify_write_overflow(__func__);
return __builtin_memset(p, c, size);
}
@@ -303,9 +306,12 @@ __FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size)
__write_overflow();
if (q_size < size)
__read_overflow2();
+ } else {
+ if (p_size < size)
+ fortify_write_overflow(__func__);
+ if (q_size < size)
+ fortify_read_overflow2(__func__);
}
- if (p_size < size || q_size < size)
- fortify_panic(__func__);
return __builtin_memcpy(p, q, size);
}
@@ -318,9 +324,12 @@ __FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size)
__write_overflow();
if (q_size < size)
__read_overflow2();
+ } else {
+ if (p_size < size)
+ fortify_write_overflow(__func__);
+ if (q_size < size)
+ fortify_read_overflow2(__func__);
}
- if (p_size < size || q_size < size)
- fortify_panic(__func__);
return __builtin_memmove(p, q, size);
}
@@ -331,7 +340,7 @@ __FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size)
if (__builtin_constant_p(size) && p_size < size)
__read_overflow();
if (p_size < size)
- fortify_panic(__func__);
+ fortify_read_overflow(__func__);
return __real_memscan(p, c, size);
}
@@ -344,9 +353,12 @@ __FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size)
__read_overflow();
if (q_size < size)
__read_overflow2();
+ } else {
+ if (p_size < size)
+ fortify_read_overflow(__func__);
+ if (q_size < size)
+ fortify_read_overflow2(__func__);
}
- if (p_size < size || q_size < size)
- fortify_panic(__func__);
return __builtin_memcmp(p, q, size);
}
@@ -356,7 +368,7 @@ __FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size)
if (__builtin_constant_p(size) && p_size < size)
__read_overflow();
if (p_size < size)
- fortify_panic(__func__);
+ fortify_read_overflow(__func__);
return __builtin_memchr(p, c, size);
}
@@ -367,7 +379,7 @@ __FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size)
if (__builtin_constant_p(size) && p_size < size)
__read_overflow();
if (p_size < size)
- fortify_panic(__func__);
+ fortify_read_overflow(__func__);
return __real_memchr_inv(p, c, size);
}
@@ -378,7 +390,7 @@ __FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
if (__builtin_constant_p(size) && p_size < size)
__read_overflow();
if (p_size < size)
- fortify_panic(__func__);
+ fortify_read_overflow(__func__);
return __real_kmemdup(p, size, gfp);
}
diff --git a/lib/string.c b/lib/string.c
index ebbb99c775bd..0fb68ec9a455 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -979,9 +979,20 @@ char *strreplace(char *s, char old, char new)
}
EXPORT_SYMBOL(strreplace);
-void fortify_panic(const char *name)
+void fortify_read_overflow(const char *func)
{
- pr_emerg("detected buffer overflow in %s\n", name);
- BUG();
+ WARN(1, "detected read beyond size of object passed as 1st parameter in %s\n", func);
}
-EXPORT_SYMBOL(fortify_panic);
+EXPORT_SYMBOL(fortify_read_overflow);
+
+void fortify_read_overflow2(const char *func)
+{
+ WARN(1, "detected read beyond size of object passed as 2nd parameter in %s\n", func);
+}
+EXPORT_SYMBOL(fortify_read_overflow2);
+
+void fortify_write_overflow(const char *func)
+{
+ WARN(1, "detected write beyond size of object passed as 1st parameter in %s\n", func);
+}
+EXPORT_SYMBOL(fortify_write_overflow);
--
2.7.4
--
Kees Cook
Pixel Security
next reply other threads:[~2017-07-26 3:50 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-26 3:50 Kees Cook [this message]
2017-07-26 12:52 ` [PATCH] fortify: Use WARN instead of BUG for now Daniel Micay
2017-07-26 17:21 ` Kees Cook
2017-07-26 17:57 ` Daniel Micay
2017-07-26 17:10 ` Linus Torvalds
2017-07-26 17:17 ` Kees Cook
2017-07-27 6:01 ` kbuild test robot
2017-07-27 16:48 ` Daniel Micay
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170726035036.GA76341@beast \
--to=keescook@chromium.org \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=bhelgaas@google.com \
--cc=dan.j.williams@intel.com \
--cc=danielmicay@gmail.com \
--cc=dhowells@redhat.com \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=mika.westerberg@linux.intel.com \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.