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: <20201021150608.16469-4-laniel_francis@privacyrequired.com> Date: Wed, 21 Oct 2020 17:06:06 +0200 From: laniel_francis@...vacyrequired.com To: linux-hardening@...r.kernel.org Cc: dja@...ens.net, Francis Laniel <laniel_francis@...vacyrequired.com> Subject: [RFC][PATCH v3 3/5] Fortify string function strscpy. From: Francis Laniel <laniel_francis@...vacyrequired.com> Fortified strscpy detects write overflows to dest. Signed-off-by: Francis Laniel <laniel_francis@...vacyrequired.com> --- include/linux/string.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/include/linux/string.h b/include/linux/string.h index 46e91d684c47..add7426ff718 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,42 @@ __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size) return ret; } +/* defined after fortified strnlen 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 size) +{ + size_t len; + /* + * Use 1 as second argument to guess only p size even and not the + * surrounding struct size (in case it is embedded inside a struct). + */ + size_t p_size = __builtin_object_size(p, 1); + + /* + * If size can be known at compile time and is greater than + * p_size, generate a compile time write overflow error. + */ + if (__builtin_constant_p(size) && size > p_size) + __write_overflow(); + + len = strnlen(q, size); + /* + * strscpy handles read overflows by stop reading q when '\0' is + * met. + * We stick to this behavior here. + */ + len = (len >= size) ? size : len; + + /* Otherwise generate a runtime write overflow error. */ + if (len > p_size) + fortify_panic(__func__); + /* + * Still use size as third argument to correctly compute max + * inside strscpy. + */ + return __real_strscpy(p, q, size); +} + /* 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