From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1780DC4338F for ; Sun, 22 Aug 2021 07:52:08 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id AD02D61247 for ; Sun, 22 Aug 2021 07:52:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org AD02D61247 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kvack.org Received: by kanga.kvack.org (Postfix) id D772B6B0085; Sun, 22 Aug 2021 03:51:37 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id D28546B0088; Sun, 22 Aug 2021 03:51:37 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B7B338D0001; Sun, 22 Aug 2021 03:51:37 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0044.hostedemail.com [216.40.44.44]) by kanga.kvack.org (Postfix) with ESMTP id 93C976B0085 for ; Sun, 22 Aug 2021 03:51:37 -0400 (EDT) Received: from smtpin25.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id 291A482499A8 for ; Sun, 22 Aug 2021 07:51:37 +0000 (UTC) X-FDA: 78501947034.25.EF9EF93 Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) by imf30.hostedemail.com (Postfix) with ESMTP id CE276E001981 for ; Sun, 22 Aug 2021 07:51:36 +0000 (UTC) Received: by mail-pj1-f53.google.com with SMTP id j10-20020a17090a94ca00b00181f17b7ef7so3804925pjw.2 for ; Sun, 22 Aug 2021 00:51:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CuzECHqSba5eY7nnFJUmPxt/bYBuzeDhyAa0OVkC4n4=; b=USFeAqU4vBKDG2YMqPqaocKpSXsJbgoUVF7UqCRgINUMIaqqk1MgdzeZdNEsz5syWE Q/srRcae53qHKuASFzb1YQkRijBTrYE1G6JRIbhFJ3VQ2fE7ADG/FLiSG04tZmIdzaRK ibgyV31RvnIskF3WWcWz1gvBTe89OuW1RvmvY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CuzECHqSba5eY7nnFJUmPxt/bYBuzeDhyAa0OVkC4n4=; b=kSjmtEsRpzJvqeOk9JZ4D+/5ySJeUXW9J4EfVEF0AhQaFU3ZLpTTgnm9wgDjCwjmVS XdWXlIzXfDKHqoNXXgfYHwtF5FA5Uogj/LQIox4PvG1o/xKVhOEEg7TJv2xriHKbqEUK bu/HEGnraGM0QCObx7KZIncA9GonrxtnBoNvadFsou5It7REHyStWb03bCPf6i0sih6S dbuskyWcvBIVpqKxATvh2p/Kmdq6g1MQq0kwUCRNyT8XfaGzOkosik9jSr8jFxkCG3zM ZangGzDxWSy7Z3UfE528jKPZuc/LkBA/b+YCOFV0Us0E1rMVbIAeMkXJCv4ecG0rryUP SlBg== X-Gm-Message-State: AOAM530OSHaQDDuQn7KL7Vn3RzflBDaURYkQSR4376FER1Na22pXI/xv KSnPB5Dw9dz8luqGHEBIeFtGKg== X-Google-Smtp-Source: ABdhPJzJyxventESg31yOthp+HUgzF7BOwI9tsOPhUsHlJOaNAhhtGCDSqdaNTLqzw1tKoOncpUXag== X-Received: by 2002:a17:902:c402:b0:12d:b2fe:f0f1 with SMTP id k2-20020a170902c40200b0012db2fef0f1mr23624016plk.9.1629618695830; Sun, 22 Aug 2021 00:51:35 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id c2sm12338876pfp.138.2021.08.22.00.51.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Aug 2021 00:51:33 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Andy Shevchenko , Rasmus Villemoes , Daniel Micay , Francis Laniel , Bart Van Assche , David Gow , linux-mm@kvack.org, clang-built-linux@googlegroups.com, linux-hardening@vger.kernel.org Subject: [PATCH for-next 14/25] lib/string: Move helper functions out of string.c Date: Sun, 22 Aug 2021 00:51:11 -0700 Message-Id: <20210822075122.864511-15-keescook@chromium.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210822075122.864511-1-keescook@chromium.org> References: <20210822075122.864511-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=15944; h=from:subject; bh=fdPsodWtszorf3587zUcTPJmGc3GEyAiUFPzZGwGXEk=; b=owEBbAKT/ZANAwAKAYly9N/cbcAmAcsmYgBhIgH3TR8TGm5yRlZPvSOdrEKiiOFp7tL7cjwQnF3e BnpeiAaJAjIEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYSIB9wAKCRCJcvTf3G3AJnX7D/ jIkMWAmbwMF4RwEwkxj2KEpgGHCwmIkz/nkU5g8E5+vb39vpSvl/MAlASCt7qZYshwqzAuBJpUsGOD yasCerv+Qka8zJmGqfWIA8zKQ+bZkXawdCusXFZ/IbyhNmCCzk9D85m9pixePTuMikADPhZmYxUlGz TXmk9tvlzx9U3Np2clRUuDJwjFq1q3N+aRjLVjvzUOt9Ukgd2zS1CyzGNrTkOZ82bUbaBr5WzouSOj TRHmEmC/UEFkhxFOixtKR2HlY+mWlyB0RUiTkC86ClUaPw3cNw5KYvnTOID1Ujd/aOZbKDvoM5NSWG I6Gg3s8SXIXvmSkD31ZydtWBdDR6DRwyLpYt/3ghz4kLZnHTnC4PHE5I3VCbVPgb0i6LzRpaadNLiy r3M8WXJBd0RglXQpHXtnDafar3TuqNrLlTiBsedkwtj7fZLWt1xLu0IrGin88H1uRT9hC6LhZ6ciF2 FSK8PnNGIRtAZnnHuncgnjXnNGyz1FRfwDssItlFGYwQrhf0yFbX5tv+1MYnGCnHQ8OMyaRkxFF/wN RfBfhIrfcFsc1q78qJMoiGJjCrWvOpwmyFbf1eh8SmZJHu5TtgLvHbVsBeYxlcLtWZjskGPCbKxIJN f0aML/mnkeJ7yJjv4uP2JJdn4i+EMT5UcZQu0xAT77yCILeO/n3/6HHAS2 X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=USFeAqU4; dmarc=pass (policy=none) header.from=chromium.org; spf=pass (imf30.hostedemail.com: domain of keescook@chromium.org designates 209.85.216.53 as permitted sender) smtp.mailfrom=keescook@chromium.org X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: CE276E001981 X-Stat-Signature: tp1c6fqqjp3zb4w769crtw97m4o715en X-HE-Tag: 1629618696-580124 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The core functions of string.c are those that may be implemented by per-architecture functions, or overloaded by FORTIFY_SOURCE. As a result, it needs to be built with __NO_FORTIFY. Without this, macros will collide with function declarations. This was accidentally working due to -ffreestanding (on some architectures). Make this deterministic by explicitly setting __NO_FORTIFY and move all the helper functions into string_helpers.c so that they gain the fortification coverage they had been missing. Acked-by: Andy Shevchenko Signed-off-by: Kees Cook --- arch/arm/boot/compressed/string.c | 1 + arch/s390/lib/string.c | 3 + arch/x86/boot/compressed/misc.h | 2 + arch/x86/boot/compressed/pgtable_64.c | 2 + arch/x86/lib/string_32.c | 1 + lib/string.c | 210 +------------------------- lib/string_helpers.c | 193 +++++++++++++++++++++++ 7 files changed, 208 insertions(+), 204 deletions(-) diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed= /string.c index 8c0fa276d994..fcc678fce045 100644 --- a/arch/arm/boot/compressed/string.c +++ b/arch/arm/boot/compressed/string.c @@ -5,6 +5,7 @@ * Small subset of simple string routines */ =20 +#define __NO_FORTIFY #include =20 /* diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c index cfcdf76d6a95..392fb9f4f4db 100644 --- a/arch/s390/lib/string.c +++ b/arch/s390/lib/string.c @@ -8,6 +8,9 @@ */ =20 #define IN_ARCH_STRING_C 1 +#ifndef __NO_FORTIFY +# define __NO_FORTIFY +#endif =20 #include #include diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/m= isc.h index 31139256859f..49bde196da9b 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -14,6 +14,8 @@ #undef CONFIG_KASAN #undef CONFIG_KASAN_GENERIC =20 +#define __NO_FORTIFY + /* cpu_feature_enabled() cannot be used this early */ #define USE_EARLY_PGTABLE_L5 =20 diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compre= ssed/pgtable_64.c index 2a78746f5a4c..a1733319a22a 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "misc.h" #include #include #include diff --git a/arch/x86/lib/string_32.c b/arch/x86/lib/string_32.c index d15fdae9656e..53b3f202267c 100644 --- a/arch/x86/lib/string_32.c +++ b/arch/x86/lib/string_32.c @@ -11,6 +11,7 @@ * strings. */ =20 +#define __NO_FORTIFY #include #include =20 diff --git a/lib/string.c b/lib/string.c index 77bd0b1d3296..1e6259f263b8 100644 --- a/lib/string.c +++ b/lib/string.c @@ -6,20 +6,15 @@ */ =20 /* - * stupid library routines.. The optimized versions should generally be = found - * as inline code in + * This file should be used only for "library" routines that may have + * alternative implementations on specific architectures (generally + * found in ), or get overloaded by FORTIFY_SOURCE. + * (Specifically, this file is built with __NO_FORTIFY.) * - * These are buggy as well.. - * - * * Fri Jun 25 1999, Ingo Oeser - * - Added strsep() which will replace strtok() soon (because strsep() = is - * reentrant and should be faster). Use only strsep() in new code, pl= ease. - * - * * Sat Feb 09 2002, Jason Thomas , - * Matthew Hawkins - * - Kissed strtok() goodbye + * Other helper functions should live in string_helpers.c. */ =20 +#define __NO_FORTIFY #include #include #include @@ -237,40 +232,6 @@ ssize_t strscpy(char *dest, const char *src, size_t = count) EXPORT_SYMBOL(strscpy); #endif =20 -/** - * strscpy_pad() - Copy a C-string into a sized buffer - * @dest: Where to copy the string to - * @src: Where to copy the string from - * @count: Size of destination buffer - * - * Copy the string, or as much of it as fits, into the dest buffer. The - * behavior is undefined if the string buffers overlap. The destination - * buffer is always %NUL terminated, unless it's zero-sized. - * - * If the source string is shorter than the destination buffer, zeros - * the tail of the destination buffer. - * - * For full explanation of why you may want to consider using the - * 'strscpy' functions please see the function docstring for strscpy(). - * - * Returns: - * * The number of characters copied (not including the trailing %NUL) - * * -E2BIG if count is 0 or @src was truncated. - */ -ssize_t strscpy_pad(char *dest, const char *src, size_t count) -{ - ssize_t written; - - written =3D strscpy(dest, src, count); - if (written < 0 || written =3D=3D count - 1) - return written; - - memset(dest + written + 1, 0, count - written - 1); - - return written; -} -EXPORT_SYMBOL(strscpy_pad); - /** * stpcpy - copy a string from src to dest returning a pointer to the ne= w end * of dest, including src's %NUL-terminator. May overrun dest. @@ -513,46 +474,6 @@ char *strnchr(const char *s, size_t count, int c) EXPORT_SYMBOL(strnchr); #endif =20 -/** - * skip_spaces - Removes leading whitespace from @str. - * @str: The string to be stripped. - * - * Returns a pointer to the first non-whitespace character in @str. - */ -char *skip_spaces(const char *str) -{ - while (isspace(*str)) - ++str; - return (char *)str; -} -EXPORT_SYMBOL(skip_spaces); - -/** - * strim - Removes leading and trailing whitespace from @s. - * @s: The string to be stripped. - * - * Note that the first trailing whitespace is replaced with a %NUL-termi= nator - * in the given string @s. Returns a pointer to the first non-whitespace - * character in @s. - */ -char *strim(char *s) -{ - size_t size; - char *end; - - size =3D strlen(s); - if (!size) - return s; - - end =3D s + size - 1; - while (end >=3D s && isspace(*end)) - end--; - *(end + 1) =3D '\0'; - - return skip_spaces(s); -} -EXPORT_SYMBOL(strim); - #ifndef __HAVE_ARCH_STRLEN /** * strlen - Find the length of a string @@ -687,101 +608,6 @@ char *strsep(char **s, const char *ct) EXPORT_SYMBOL(strsep); #endif =20 -/** - * sysfs_streq - return true if strings are equal, modulo trailing newli= ne - * @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 =3D=3D *s2) { - s1++; - s2++; - } - - if (*s1 =3D=3D *s2) - return true; - if (!*s1 && *s2 =3D=3D '\n' && !s2[1]) - return true; - if (*s1 =3D=3D '\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 - * - * This routine will look for a string in an array of strings up to the - * n-th element in the array or until the first NULL element. - * - * Historically the value of -1 for @n, was used to search in arrays tha= t - * are NULL terminated. However, the function does not make a distinctio= n - * when finishing the search: either @n elements have been compared OR - * the first NULL element was found. - * - * 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 =3D 0; index < n; index++) { - item =3D 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_strin= g(). - * Uses sysfs_streq instead of strcmp for matching. - * - * This routine will look for a string in an array of strings up to the - * n-th element in the array or until the first NULL element. - * - * Historically the value of -1 for @n, was used to search in arrays tha= t - * are NULL terminated. However, the function does not make a distinctio= n - * when finishing the search: either @n elements have been compared OR - * the first NULL element was found. - */ -int __sysfs_match_string(const char * const *array, size_t n, const char= *str) -{ - const char *item; - int index; - - for (index =3D 0; index < n; index++) { - item =3D 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 @@ -1125,27 +951,3 @@ void *memchr_inv(const void *start, int c, size_t b= ytes) return check_bytes8(start, value, bytes % 8); } EXPORT_SYMBOL(memchr_inv); - -/** - * strreplace - Replace all occurrences of character in string. - * @s: The string to operate on. - * @old: The character being replaced. - * @new: The character @old is replaced with. - * - * Returns pointer to the nul byte at the end of @s. - */ -char *strreplace(char *s, char old, char new) -{ - for (; *s; ++s) - if (*s =3D=3D old) - *s =3D new; - return s; -} -EXPORT_SYMBOL(strreplace); - -void fortify_panic(const char *name) -{ - pr_emerg("detected buffer overflow in %s\n", name); - BUG(); -} -EXPORT_SYMBOL(fortify_panic); diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 5a35c7e16e96..e9433caab217 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -692,3 +692,196 @@ void kfree_strarray(char **array, size_t n) kfree(array); } EXPORT_SYMBOL_GPL(kfree_strarray); + +/** + * strscpy_pad() - Copy a C-string into a sized buffer + * @dest: Where to copy the string to + * @src: Where to copy the string from + * @count: Size of destination buffer + * + * Copy the string, or as much of it as fits, into the dest buffer. The + * behavior is undefined if the string buffers overlap. The destination + * buffer is always %NUL terminated, unless it's zero-sized. + * + * If the source string is shorter than the destination buffer, zeros + * the tail of the destination buffer. + * + * For full explanation of why you may want to consider using the + * 'strscpy' functions please see the function docstring for strscpy(). + * + * Returns: + * * The number of characters copied (not including the trailing %NUL) + * * -E2BIG if count is 0 or @src was truncated. + */ +ssize_t strscpy_pad(char *dest, const char *src, size_t count) +{ + ssize_t written; + + written =3D strscpy(dest, src, count); + if (written < 0 || written =3D=3D count - 1) + return written; + + memset(dest + written + 1, 0, count - written - 1); + + return written; +} +EXPORT_SYMBOL(strscpy_pad); + +/** + * skip_spaces - Removes leading whitespace from @str. + * @str: The string to be stripped. + * + * Returns a pointer to the first non-whitespace character in @str. + */ +char *skip_spaces(const char *str) +{ + while (isspace(*str)) + ++str; + return (char *)str; +} +EXPORT_SYMBOL(skip_spaces); + +/** + * strim - Removes leading and trailing whitespace from @s. + * @s: The string to be stripped. + * + * Note that the first trailing whitespace is replaced with a %NUL-termi= nator + * in the given string @s. Returns a pointer to the first non-whitespace + * character in @s. + */ +char *strim(char *s) +{ + size_t size; + char *end; + + size =3D strlen(s); + if (!size) + return s; + + end =3D s + size - 1; + while (end >=3D s && isspace(*end)) + end--; + *(end + 1) =3D '\0'; + + return skip_spaces(s); +} +EXPORT_SYMBOL(strim); + +/** + * sysfs_streq - return true if strings are equal, modulo trailing newli= ne + * @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 =3D=3D *s2) { + s1++; + s2++; + } + + if (*s1 =3D=3D *s2) + return true; + if (!*s1 && *s2 =3D=3D '\n' && !s2[1]) + return true; + if (*s1 =3D=3D '\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 + * + * This routine will look for a string in an array of strings up to the + * n-th element in the array or until the first NULL element. + * + * Historically the value of -1 for @n, was used to search in arrays tha= t + * are NULL terminated. However, the function does not make a distinctio= n + * when finishing the search: either @n elements have been compared OR + * the first NULL element was found. + * + * 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 =3D 0; index < n; index++) { + item =3D 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_strin= g(). + * Uses sysfs_streq instead of strcmp for matching. + * + * This routine will look for a string in an array of strings up to the + * n-th element in the array or until the first NULL element. + * + * Historically the value of -1 for @n, was used to search in arrays tha= t + * are NULL terminated. However, the function does not make a distinctio= n + * when finishing the search: either @n elements have been compared OR + * the first NULL element was found. + */ +int __sysfs_match_string(const char * const *array, size_t n, const char= *str) +{ + const char *item; + int index; + + for (index =3D 0; index < n; index++) { + item =3D array[index]; + if (!item) + break; + if (sysfs_streq(item, str)) + return index; + } + + return -EINVAL; +} +EXPORT_SYMBOL(__sysfs_match_string); + +/** + * strreplace - Replace all occurrences of character in string. + * @s: The string to operate on. + * @old: The character being replaced. + * @new: The character @old is replaced with. + * + * Returns pointer to the nul byte at the end of @s. + */ +char *strreplace(char *s, char old, char new) +{ + for (; *s; ++s) + if (*s =3D=3D old) + *s =3D new; + return s; +} +EXPORT_SYMBOL(strreplace); + +void fortify_panic(const char *name) +{ + pr_emerg("detected buffer overflow in %s\n", name); + BUG(); +} +EXPORT_SYMBOL(fortify_panic); --=20 2.30.2