lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-Id: <20201013165955.7350-1-laniel_francis@privacyrequired.com> Date: Tue, 13 Oct 2020 18:59:56 +0200 From: laniel_francis@...vacyrequired.com To: linux-hardening@...r.kernel.org Cc: Francis Laniel <laniel_francis@...vacyrequired.com> Subject: [RFC][PATCH v1] Fortify string function strscpy. From: Francis Laniel <laniel_francis@...vacyrequired.com> Hi. First, I do hope you are all fine and the same for your relatives. This patch is related to this issue: https://github.com/KSPP/linux/issues/96 In this patch, I fortified strscpy so the function detects write overflows to dest. I did not deal with read overflows since strscpy will exit when '\0' is met in src. Unfortunately, I did not test this modification at run time because I did not find enough documentation about LKDTM to make it work. Also, when I booted the modified kernel inside a VM, I had oom reaper called to kill systemd related processes when I used len as third argument of __real_strscpy... For all these reasons I marked this patch as RFC. Best regards. Signed-off-by: Francis Laniel <laniel_francis@...vacyrequired.com> --- include/linux/string.h | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/include/linux/string.h b/include/linux/string.h index b1f3894a0a3e..b661863619e0 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -6,6 +6,8 @@ #include <linux/compiler.h> /* for inline */ #include <linux/types.h> /* for size_t */ #include <linux/stddef.h> /* for NULL */ +#include <linux/bug.h> /* for WARN_ON_ONCE */ +#include <linux/errno.h> /* for E2BIG */ #include <stdarg.h> #include <uapi/linux/string.h> @@ -357,6 +359,49 @@ __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size) return ret; } +/* defined after fortified strlen to reuse it */ +extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy); +__FORTIFY_INLINE ssize_t strscpy(char *p, const char *q, size_t count) +{ + size_t len; + size_t p_size = __builtin_object_size(p, 0); + size_t q_size = __builtin_object_size(q, 0); + /* + * If p_size and q_size cannot be known at compile time we just had to + * trust this function caller. + */ + if (p_size == (size_t)-1 && q_size == (size_t)-1) + return __real_strscpy(p, q, count); + len = strlen(q); + if (count) { + /* If count is bigger than INT_MAX, strscpy returns -E2BIG. */ + if (WARN_ON_ONCE(count > INT_MAX)) + return -E2BIG; + /* + * strscpy handles read overflows by stop reading q when '\0' is + * met. + * We stick to this behavior here. + */ + len = (len >= count) ? count : len; + /* + * If len can be known at compile time and is greater than + * p_size, generate a compile time write overflow error. + */ + if (__builtin_constant_p(len) && len > p_size) + __write_overflow(); + /* Otherwise generate a runtime write overflow error. */ + if (len > p_size) + fortify_panic(__func__); + /* + * Still use count as third argument to correctly compute max + * inside strscpy. + */ + return __real_strscpy(p, q, count); + } + /* If count is 0, strscpy return -E2BIG. */ + return -E2BIG; +} + /* defined after fortified strlen and strnlen to reuse them */ __FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count) { -- 2.20.1
Powered by blists - more mailing lists