git: be04fec42638 - main - Import _FORTIFY_SOURCE implementation from NetBSD

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Mon, 13 May 2024 05:24:09 UTC
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=be04fec42638f30f50b5b55fd8e3634c0fb89928

commit be04fec42638f30f50b5b55fd8e3634c0fb89928
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2024-05-13 05:23:49 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2024-05-13 05:23:49 +0000

    Import _FORTIFY_SOURCE implementation from NetBSD
    
    This is a mostly-unmodified copy of the various *_chk implementations
    and headers from NetBSD, without yet modifying system headers to start
    actually including them.  A future commit will also apply the needed
    bits to fix ssp/unistd.h.
    
    Reviewed by:    imp, pauamma_gundo.com (both previous versions), kib
    Sponsored by:   Stormshield
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D32306
---
 etc/mtree/BSD.include.dist         |   2 +
 include/Makefile                   |   2 +-
 include/ssp/Makefile               |   6 ++
 include/ssp/ssp.h                  |  91 ++++++++++++++++++++++++++
 include/ssp/stdio.h                |  93 ++++++++++++++++++++++++++
 include/ssp/string.h               | 129 ++++++++++++++++++++++++++++++++++++
 include/ssp/strings.h              |  67 +++++++++++++++++++
 include/ssp/unistd.h               |  54 +++++++++++++++
 lib/libc/secure/Makefile.inc       |  11 ++++
 lib/libc/secure/Symbol.map         |  18 +++++
 lib/libc/secure/fgets_chk.c        |  54 +++++++++++++++
 lib/libc/secure/gets_chk.c         |  74 +++++++++++++++++++++
 lib/libc/secure/memcpy_chk.c       |  53 +++++++++++++++
 lib/libc/secure/memmove_chk.c      |  47 +++++++++++++
 lib/libc/secure/memset_chk.c       |  46 +++++++++++++
 lib/libc/secure/snprintf_chk.c     |  56 ++++++++++++++++
 lib/libc/secure/sprintf_chk.c      |  61 +++++++++++++++++
 lib/libc/secure/ssp_internal.h     |  37 +++++++++++
 lib/libc/secure/stpcpy_chk.c       |  55 ++++++++++++++++
 lib/libc/secure/stpncpy_chk.c      |  53 +++++++++++++++
 lib/libc/secure/strcat_chk.c       |  60 +++++++++++++++++
 lib/libc/secure/strcpy_chk.c       |  54 +++++++++++++++
 lib/libc/secure/strncat_chk.c      |  70 ++++++++++++++++++++
 lib/libc/secure/strncpy_chk.c      |  53 +++++++++++++++
 lib/libc/secure/vsnprintf_chk.c    |  49 ++++++++++++++
 lib/libc/secure/vsprintf_chk.c     |  58 ++++++++++++++++
 lib/libssp/Makefile                |  20 +++++-
 lib/libssp/Symbol.map              |  12 ++--
 lib/libssp/Versions.def            |   5 ++
 lib/libssp/__builtin_object_size.3 | 110 +++++++++++++++++++++++++++++++
 lib/libssp/fortify_stubs.c         | 131 -------------------------------------
 lib/libssp/ssp.3                   | 130 ++++++++++++++++++++++++++++++++++++
 32 files changed, 1621 insertions(+), 140 deletions(-)

diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist
index a6bd5880bf61..f8c83d6dde7a 100644
--- a/etc/mtree/BSD.include.dist
+++ b/etc/mtree/BSD.include.dist
@@ -372,6 +372,8 @@
         mac_veriexec
         ..
     ..
+    ssp
+    ..
     sys
         disk
         ..
diff --git a/include/Makefile b/include/Makefile
index 19e6beb95203..32774419f162 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -4,7 +4,7 @@
 
 PACKAGE=clibs
 CLEANFILES= osreldate.h version
-SUBDIR= arpa protocols rpcsvc rpc xlocale
+SUBDIR= arpa protocols rpcsvc rpc ssp xlocale
 .if ${MACHINE_CPUARCH} == "amd64"
 SUBDIR+=		i386
 INCLUDE_SUBDIRS+=	i386
diff --git a/include/ssp/Makefile b/include/ssp/Makefile
new file mode 100644
index 000000000000..dff19f43c920
--- /dev/null
+++ b/include/ssp/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+INCS=	ssp.h stdio.h string.h strings.h unistd.h
+INCSDIR=	${INCLUDEDIR}/ssp
+
+.include <bsd.prog.mk>
diff --git a/include/ssp/ssp.h b/include/ssp/ssp.h
new file mode 100644
index 000000000000..35a9aeee02df
--- /dev/null
+++ b/include/ssp/ssp.h
@@ -0,0 +1,91 @@
+/*	$NetBSD: ssp.h,v 1.13 2015/09/03 20:43:47 plunky Exp $	*/
+
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006, 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SSP_SSP_H_
+#define _SSP_SSP_H_
+
+#include <sys/cdefs.h>
+
+#if !defined(__cplusplus)
+# if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && \
+     (__OPTIMIZE__ > 0 || defined(__clang__))
+#  if _FORTIFY_SOURCE > 1
+#   define __SSP_FORTIFY_LEVEL 2
+#  else
+#   define __SSP_FORTIFY_LEVEL 1
+#  endif
+# else
+#  define __SSP_FORTIFY_LEVEL 0
+# endif
+#else
+# define __SSP_FORTIFY_LEVEL 0
+#endif
+
+#define	__ssp_var(type)	__CONCAT(__ssp_ ## type, __COUNTER__)
+
+/* __ssp_real is used by the implementation in libc */
+#if __SSP_FORTIFY_LEVEL == 0
+#define __ssp_real_(fun)	fun
+#else
+#define __ssp_real_(fun)	__ssp_real_ ## fun
+#endif
+#define __ssp_real(fun)		__ssp_real_(fun)
+
+#define __ssp_inline static __inline __attribute__((__always_inline__))
+
+#define __ssp_bos(ptr) __builtin_object_size(ptr, __SSP_FORTIFY_LEVEL > 1)
+#define __ssp_bos0(ptr) __builtin_object_size(ptr, 0)
+
+#define __ssp_check(buf, len, bos) \
+	if (bos(buf) != (size_t)-1 && len > bos(buf)) \
+		__chk_fail()
+#define __ssp_redirect_raw(rtype, fun, symbol, args, call, cond, bos) \
+rtype __ssp_real_(fun) args __RENAME(symbol); \
+__ssp_inline rtype fun args __RENAME(__ssp_protected_ ## fun); \
+__ssp_inline rtype fun args { \
+	if (cond) \
+		__ssp_check(__buf, __len, bos); \
+	return __ssp_real_(fun) call; \
+}
+
+#define __ssp_redirect(rtype, fun, args, call) \
+    __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos)
+#define __ssp_redirect0(rtype, fun, args, call) \
+    __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos0)
+
+__BEGIN_DECLS
+void __stack_chk_fail(void) __dead2;
+void __chk_fail(void) __dead2;
+__END_DECLS
+
+#endif /* _SSP_SSP_H_ */
diff --git a/include/ssp/stdio.h b/include/ssp/stdio.h
new file mode 100644
index 000000000000..72e3236eac80
--- /dev/null
+++ b/include/ssp/stdio.h
@@ -0,0 +1,93 @@
+/*	$NetBSD: stdio.h,v 1.5 2011/07/17 20:54:34 joerg Exp $	*/
+
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SSP_STDIO_H_
+#define _SSP_STDIO_H_
+
+#include <ssp/ssp.h>
+
+__BEGIN_DECLS
+int __sprintf_chk(char *__restrict, int, size_t, const char *__restrict, ...)
+    __printflike(4, 5);
+int __vsprintf_chk(char *__restrict, int, size_t, const char *__restrict,
+    __va_list)
+    __printflike(4, 0);
+int __snprintf_chk(char *__restrict, size_t, int, size_t,
+    const char *__restrict, ...)
+    __printflike(5, 6);
+int __vsnprintf_chk(char *__restrict, size_t, int, size_t,
+     const char *__restrict, __va_list)
+    __printflike(5, 0);
+char *__gets_chk(char *, size_t);
+char *__fgets_chk(char *, int, size_t, FILE *);
+__END_DECLS
+
+#if __SSP_FORTIFY_LEVEL > 0
+
+#define sprintf(str, ...) ({	\
+    char *_ssp_str = (str);	\
+    __builtin___sprintf_chk(_ssp_str, 0, __ssp_bos(_ssp_str),		\
+        __VA_ARGS__); \
+})
+
+#define vsprintf(str, fmt, ap) ({	\
+    char *_ssp_str = (str);		\
+    __builtin___vsprintf_chk(_ssp_str, 0, __ssp_bos(_ssp_str), fmt,	\
+        ap);				\
+})
+
+#define snprintf(str, len, ...) ({	\
+    char *_ssp_str = (str);		\
+    __builtin___snprintf_chk(_ssp_str, len, 0, __ssp_bos(_ssp_str),	\
+        __VA_ARGS__);			\
+})
+
+#define vsnprintf(str, len, fmt, ap) ({	\
+    char *_ssp_str = (str);		\
+    __builtin___vsnprintf_chk(_ssp_str, len, 0, __ssp_bos(_ssp_str),	\
+        fmt, ap);			\
+})
+
+#define gets(str) ({			\
+   char *_ssp_str = (str);		\
+    __gets_chk(_ssp_str, __ssp_bos(_ssp_str));	\
+})
+
+#define fgets(str, len, fp) ({		\
+    char *_ssp_str = (str);		\
+    __fgets_chk(_ssp_str, len, __ssp_bos(_ssp_str), fp);	\
+})
+
+#endif /* __SSP_FORTIFY_LEVEL > 0 */
+
+#endif /* _SSP_STDIO_H_ */
diff --git a/include/ssp/string.h b/include/ssp/string.h
new file mode 100644
index 000000000000..996020fda778
--- /dev/null
+++ b/include/ssp/string.h
@@ -0,0 +1,129 @@
+/*	$NetBSD: string.h,v 1.14 2020/09/05 13:37:59 mrg Exp $	*/
+
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SSP_STRING_H_
+#define _SSP_STRING_H_
+
+#include <ssp/ssp.h>
+
+__BEGIN_DECLS
+void *__memcpy_chk(void *, const void *, size_t, size_t);
+void *__memmove_chk(void *, const void *, size_t, size_t);
+void *__memset_chk(void *, int, size_t, size_t);
+char *__stpcpy_chk(char *, const char *, size_t);
+char *__stpncpy_chk(char *, const char *, size_t, size_t);
+char *__strcat_chk(char *, const char *, size_t);
+char *__strcpy_chk(char *, const char *, size_t);
+char *__strncat_chk(char *, const char *, size_t, size_t);
+char *__strncpy_chk(char *, const char *, size_t, size_t);
+__END_DECLS
+
+#if __SSP_FORTIFY_LEVEL > 0
+
+#define __ssp_bos_check3_typed_var(fun, dsttype, dsrvar, dst, srctype, srcvar, \
+    src, lenvar, len) ({				\
+    srctype srcvar = (src);				\
+    dsttype dstvar = (dst);				\
+    size_t lenvar = (len);				\
+    ((__ssp_bos0(dstvar) != (size_t)-1) ?		\
+    __builtin___ ## fun ## _chk(dstvar, srcvar, lenvar,	\
+        __ssp_bos0(dstvar)) :				\
+    __ ## fun ## _ichk(dstvar, srcvar, lenvar));	\
+})
+
+#define __ssp_bos_check3_typed(fun, dsttype, dst, srctype, src, len)	\
+    __ssp_bos_check3_typed_var(fun, dsttype, __ssp_var(dstv), dst,	\
+        srctype, __ssp_var(srcv), src, __ssp_var(lenv), len)
+
+#define __ssp_bos_check3(fun, dst, src, len)		\
+    __ssp_bos_check3_typed_var(fun, void *, __ssp_var(dstv), dst,	\
+        const void *, __ssp_var(srcv), src, __ssp_var(lenv), len)
+
+#define __ssp_bos_check2_var(fun, dstvar, dst, srcvar, src) ({		\
+    const void *srcvar = (src);				\
+    void *dstvar = (dst);				\
+    ((__ssp_bos0(dstvar) != (size_t)-1) ?		\
+    __builtin___ ## fun ## _chk(dstvar, srcvar,		\
+        __ssp_bos0(dstvar)) :				\
+    __ ## fun ## _ichk(dstvar, srcvar));		\
+})
+
+#define __ssp_bos_check2(fun, dst, src)			\
+    __ssp_bos_check2_var(fun, __ssp_var(dstv), dst, __ssp_var(srcv), src)
+
+#define __ssp_bos_icheck3_restrict(fun, type1, type2) \
+static __inline type1 __ ## fun ## _ichk(type1 __restrict, type2 __restrict, size_t); \
+static __inline __attribute__((__always_inline__)) type1 \
+__ ## fun ## _ichk(type1 __restrict dst, type2 __restrict src, size_t len) { \
+	return __builtin___ ## fun ## _chk(dst, src, len, __ssp_bos0(dst)); \
+}
+
+#define __ssp_bos_icheck3(fun, type1, type2) \
+static __inline type1 __ ## fun ## _ichk(type1, type2, size_t); \
+static __inline __attribute__((__always_inline__)) type1 \
+__ ## fun ## _ichk(type1 dst, type2 src, size_t len) { \
+	return __builtin___ ## fun ## _chk(dst, src, len, __ssp_bos0(dst)); \
+}
+
+#define __ssp_bos_icheck2_restrict(fun, type1, type2) \
+static __inline type1 __ ## fun ## _ichk(type1, type2); \
+static __inline __attribute__((__always_inline__)) type1 \
+__ ## fun ## _ichk(type1 __restrict dst, type2 __restrict src) { \
+	return __builtin___ ## fun ## _chk(dst, src, __ssp_bos0(dst)); \
+}
+
+__BEGIN_DECLS
+__ssp_bos_icheck3_restrict(memcpy, void *, const void *)
+__ssp_bos_icheck3(memmove, void *, const void *)
+__ssp_bos_icheck3(memset, void *, int)
+__ssp_bos_icheck2_restrict(stpcpy, char *, const char *)
+__ssp_bos_icheck3_restrict(stpncpy, char *, const char *)
+__ssp_bos_icheck2_restrict(strcpy, char *, const char *)
+__ssp_bos_icheck2_restrict(strcat, char *, const char *)
+__ssp_bos_icheck3_restrict(strncpy, char *, const char *)
+__ssp_bos_icheck3_restrict(strncat, char *, const char *)
+__END_DECLS
+
+#define memcpy(dst, src, len) __ssp_bos_check3(memcpy, dst, src, len)
+#define memmove(dst, src, len) __ssp_bos_check3(memmove, dst, src, len)
+#define memset(dst, val, len) \
+    __ssp_bos_check3_typed(memset, void *, dst, int, val, len)
+#define stpcpy(dst, src) __ssp_bos_check2(stpcpy, dst, src)
+#define stpncpy(dst, src, len) __ssp_bos_check3(stpncpy, dst, src, len)
+#define strcpy(dst, src) __ssp_bos_check2(strcpy, dst, src)
+#define strcat(dst, src) __ssp_bos_check2(strcat, dst, src)
+#define strncpy(dst, src, len) __ssp_bos_check3(strncpy, dst, src, len)
+#define strncat(dst, src, len) __ssp_bos_check3(strncat, dst, src, len)
+
+#endif /* __SSP_FORTIFY_LEVEL > 0 */
+#endif /* _SSP_STRING_H_ */
diff --git a/include/ssp/strings.h b/include/ssp/strings.h
new file mode 100644
index 000000000000..06c9c7cc0a09
--- /dev/null
+++ b/include/ssp/strings.h
@@ -0,0 +1,67 @@
+/*	$NetBSD: strings.h,v 1.3 2008/04/28 20:22:54 martin Exp $	*/
+
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SSP_STRINGS_H_
+#define _SSP_STRINGS_H_
+
+#include <ssp/ssp.h>
+#include <string.h>
+
+#if __SSP_FORTIFY_LEVEL > 0
+
+#define _ssp_bcopy(srcvar, src, dstvar, dst, lenvar,  len) ({	\
+    const void *srcvar = (src);			\
+    void *dstvar = (dst);			\
+    size_t lenvar = (len);			\
+    ((__ssp_bos0(dstvar) != (size_t)-1) ?	\
+    __builtin___memmove_chk(dstvar, srcvar, lenvar,	\
+        __ssp_bos0(dstvar)) :			\
+    __memmove_ichk(dstvar, srcvar, lenvar));	\
+})
+
+#define	bcopy(src, dst, len)			\
+    _ssp_bcopy(__ssp_var(srcv), src, __ssp_var(dstv), dst, __ssp_var(lenv), len)
+
+#define _ssp_bzero(dstvar, dst, lenvar, len) ({		\
+    void *dstvar = (dst);			\
+    size_t lenvar = (len);			\
+    ((__ssp_bos0(dstvar) != (size_t)-1) ?	\
+    __builtin___memset_chk(dstvar, 0, lenvar,	\
+        __ssp_bos0(dstvar)) : \
+    __memset_ichk(dstvar, 0, lenvar));		\
+})
+
+#define	bzero(dst, len)	_ssp_bzero(__ssp_var(dstv), dst, __ssp_var(lenv), len)
+
+#endif /* __SSP_FORTIFY_LEVEL > 0 */
+#endif /* _SSP_STRINGS_H_ */
diff --git a/include/ssp/unistd.h b/include/ssp/unistd.h
new file mode 100644
index 000000000000..2414e2baa96b
--- /dev/null
+++ b/include/ssp/unistd.h
@@ -0,0 +1,54 @@
+/*	$NetBSD: unistd.h,v 1.7 2015/06/25 18:41:03 joerg Exp $	*/
+
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SSP_UNISTD_H_
+#define _SSP_UNISTD_H_
+
+#include <ssp/ssp.h>
+
+#if __SSP_FORTIFY_LEVEL > 0
+__BEGIN_DECLS
+
+__ssp_redirect0(ssize_t, read, (int __fd, void *__buf, size_t __len), \
+    (__fd, __buf, __len));
+
+__ssp_redirect(ssize_t, readlink, (const char *__restrict __path, \
+    char *__restrict __buf, size_t __len), (__path, __buf, __len));
+
+__ssp_redirect_raw(char *, getcwd, getcwd, (char *__buf, size_t __len),
+    (__buf, __len), __buf != 0, __ssp_bos);
+
+__END_DECLS
+
+#endif /* __SSP_FORTIFY_LEVEL > 0 */
+#endif /* _SSP_UNISTD_H_ */
diff --git a/lib/libc/secure/Makefile.inc b/lib/libc/secure/Makefile.inc
index 8574c5a05dc5..3b1ad879c715 100644
--- a/lib/libc/secure/Makefile.inc
+++ b/lib/libc/secure/Makefile.inc
@@ -3,6 +3,17 @@
 
 .PATH: ${LIBC_SRCTOP}/secure
 
+# _FORTIFY_SOURCE
+SRCS+=	gets_chk.c fgets_chk.c memcpy_chk.c memmove_chk.c memset_chk.c \
+	snprintf_chk.c sprintf_chk.c stpcpy_chk.c stpncpy_chk.c \
+	strcat_chk.c strcpy_chk.c strncat_chk.c strncpy_chk.c \
+	vsnprintf_chk.c vsprintf_chk.c
+
+CFLAGS.snprintf_chk.c+=	-Wno-unused-parameter
+CFLAGS.sprintf_chk.c+=	-Wno-unused-parameter
+CFLAGS.vsnprintf_chk.c+=	-Wno-unused-parameter
+CFLAGS.vsprintf_chk.c+=	-Wno-unused-parameter
+
 # Sources common to both syscall interfaces:
 SRCS+=	stack_protector.c \
 	stack_protector_compat.c
diff --git a/lib/libc/secure/Symbol.map b/lib/libc/secure/Symbol.map
index 641f451b5421..7859fcee3821 100644
--- a/lib/libc/secure/Symbol.map
+++ b/lib/libc/secure/Symbol.map
@@ -3,3 +3,21 @@ FBSD_1.0 {
 	__stack_chk_fail;
 	__stack_chk_guard;
 };
+
+FBSD_1.8 {
+	__gets_chk;
+	__fgets_chk;
+	__memcpy_chk;
+	__memmove_chk;
+	__memset_chk;
+	__snprintf_chk;
+	__sprintf_chk;
+	__stpcpy_chk;
+	__stpncpy_chk;
+	__strcat_chk;
+	__strcpy_chk;
+	__strncat_chk;
+	__strncpy_chk;
+	__vsnprintf_chk;
+	__vsprintf_chk;
+};
diff --git a/lib/libc/secure/fgets_chk.c b/lib/libc/secure/fgets_chk.c
new file mode 100644
index 000000000000..72aa1d816ce1
--- /dev/null
+++ b/lib/libc/secure/fgets_chk.c
@@ -0,0 +1,54 @@
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: fgets_chk.c,v 1.6 2009/02/05 05:41:51 lukem Exp $");
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ssp/stdio.h>
+#include <ssp/string.h>
+#undef fgets
+
+char *
+__fgets_chk(char * __restrict buf, int len, size_t slen, FILE *fp)
+{
+	if (slen >= (size_t)INT_MAX)
+		return (fgets(buf, len, fp));
+
+	if (len >= 0 && (size_t)len > slen)
+		__chk_fail();
+
+	return (fgets(buf, len, fp));
+}
diff --git a/lib/libc/secure/gets_chk.c b/lib/libc/secure/gets_chk.c
new file mode 100644
index 000000000000..18c1e2d18f43
--- /dev/null
+++ b/lib/libc/secure/gets_chk.c
@@ -0,0 +1,74 @@
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: gets_chk.c,v 1.7 2013/10/04 20:49:16 christos Exp $");
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ssp/stdio.h>
+#include <ssp/string.h>
+
+char *__gets_unsafe(char *);
+
+char *
+__gets_chk(char * __restrict buf, size_t slen)
+{
+	char *abuf;
+	size_t len;
+
+	if (slen >= (size_t)INT_MAX)
+		return (__gets_unsafe(buf));
+
+	if ((abuf = malloc(slen + 1)) == NULL)
+		return (__gets_unsafe(buf));
+
+	if (fgets(abuf, (int)(slen + 1), stdin) == NULL) {
+		free(abuf);
+		return (NULL);
+	}
+
+	len = strlen(abuf);
+	if (len > 0 && abuf[len - 1] == '\n')
+		--len;
+
+	if (len >= slen)
+		__chk_fail();
+
+	(void)memcpy(buf, abuf, len);
+
+	buf[len] = '\0';
+	free(abuf);
+	return (buf);
+}
diff --git a/lib/libc/secure/memcpy_chk.c b/lib/libc/secure/memcpy_chk.c
new file mode 100644
index 000000000000..99cf2d5f13ff
--- /dev/null
+++ b/lib/libc/secure/memcpy_chk.c
@@ -0,0 +1,53 @@
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: memcpy_chk.c,v 1.7 2015/05/13 19:57:16 joerg Exp $");
+
+#include <string.h>
+
+#include <ssp/string.h>
+#undef memcpy
+
+#include "ssp_internal.h"
+
+void *
+__memcpy_chk(void * __restrict dst, const void * __restrict src, size_t len,
+    size_t slen)
+{
+	if (len > slen)
+		__chk_fail();
+
+	if (__ssp_overlap((const char *)src, (const char *)dst, len))
+		__chk_fail();
+
+	return (memcpy(dst, src, len));
+}
diff --git a/lib/libc/secure/memmove_chk.c b/lib/libc/secure/memmove_chk.c
new file mode 100644
index 000000000000..07f965d608fc
--- /dev/null
+++ b/lib/libc/secure/memmove_chk.c
@@ -0,0 +1,47 @@
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: memmove_chk.c,v 1.6 2020/09/05 13:37:59 mrg Exp $");
+
+#include <string.h>
+
+#include <ssp/string.h>
+#undef memmove
+
+void *
+__memmove_chk(void *dst, const void *src, size_t len,
+    size_t slen)
+{
+	if (len > slen)
+		__chk_fail();
+	return (memmove(dst, src, len));
+}
diff --git a/lib/libc/secure/memset_chk.c b/lib/libc/secure/memset_chk.c
new file mode 100644
index 000000000000..f337be98b46d
--- /dev/null
+++ b/lib/libc/secure/memset_chk.c
@@ -0,0 +1,46 @@
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: memset_chk.c,v 1.5 2014/09/17 00:39:28 joerg Exp $");
+
+#include <string.h>
+
+#include <ssp/string.h>
+#undef memset
+
+void *
+__memset_chk(void * __restrict dst, int val, size_t len, size_t slen)
+{
+	if (len > slen)
+		__chk_fail();
+	return (memset(dst, val, len));
+}
diff --git a/lib/libc/secure/snprintf_chk.c b/lib/libc/secure/snprintf_chk.c
new file mode 100644
index 000000000000..52ef874ede5b
--- /dev/null
+++ b/lib/libc/secure/snprintf_chk.c
@@ -0,0 +1,56 @@
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: snprintf_chk.c,v 1.5 2008/04/28 20:23:00 martin Exp $");
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <ssp/stdio.h>
+#undef vsnprintf
+
+int
+__snprintf_chk(char * __restrict buf, size_t len, int flags, size_t slen,
+    const char * __restrict fmt, ...)
+{
+	va_list ap;
+	int rv;
+
+	if (len > slen)
+		__chk_fail();
+
+	va_start(ap, fmt);
+	rv = vsnprintf(buf, len, fmt, ap);
+	va_end(ap);
+
+	return (rv);
+}
diff --git a/lib/libc/secure/sprintf_chk.c b/lib/libc/secure/sprintf_chk.c
new file mode 100644
index 000000000000..d4c42ccba3ce
--- /dev/null
+++ b/lib/libc/secure/sprintf_chk.c
@@ -0,0 +1,61 @@
+/*-
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
*** 1063 LINES SKIPPED ***