Re: git: be04fec42638 - main - Import _FORTIFY_SOURCE implementation from NetBSD

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Sun, 19 May 2024 02:08:48 UTC

On 5/18/24 20:09, Pedro Giffuni wrote:
> (sorry for top posting .. my mailer just sucks)
> Hi;
> 
> I used to like the limited static checking FORTIFY_SOURCE provides and 
> when I ran it over FreeBSD it did find a couple of minor issues. It only 
> works for GCC though.
> 

I don't think this is particularly true anymore; I haven't found a case 
yet where __builtin_object_size(3) doesn't give me the correct size 
while GCC did.  I'd welcome counter-examples here, though -- we have 
funding to both finish the project (widen the _FORTIFY_SOURCE net to 
more of libc/libsys) and add tests to demonstrate that it's both 
functional and correct.  It would be useful to also document 
deficiencies in the tests.

> I guess it doesn't really hurt to have FORTIFY_SOURCE around and NetBSD 
> had the least intrusive implementation the last time I checked but I 
> would certainly request it should never be activated by default, 
> specially with clang. The GCC version has seen more development on glibc 
> but I still think its a dead end.
> 

I don't see a compelling reason to avoid enabling it by default; see 
above, the functionality that we need in clang appears to be just fine 
(and, iirc, was also fine when I checked at the beginning of working on 
this in 2021) and it provides useful

> What I would like to see working on FreeBSD is Safestack as a 
> replacement for the stack protector, which we were so very slow to adopt 
> even when it was originally developed in FreeBSD. I think other projects 
> based on FreeBSD (Chimera and hardenedBSD) have been using it but I 
> don't know the details.
> 

No comment there, though I think Shawn Webb / HardenedBSD had been 
playing around with SafeStack (and might have enabled it? I haven't 
actually looked in a while now).

> This is just all my $0.02
> 
> Pedro.

Thanks,

Kyle Evans

> 
> On Saturday, May 18, 2024 at 05:54:42 PM GMT-5, Kyle Evans 
> <kaevans@fastmail.com> wrote:
> 
> 
> 
> 
> On May 18, 2024 13:42, Pedro Giffuni <pfg@freebsd.org> wrote:
> 
>     Oh no .. please not...
> 
>     We went into that in a GSoC:
> 
>     https://wiki.freebsd.org/SummerOfCode2015/FreeBSDLibcSecurityExtensions <https://wiki.freebsd.org/SummerOfCode2015/FreeBSDLibcSecurityExtensions>
> 
> 
>     Ultimately it proved to be useless since stack-protector-strong.
> 
> 
> Respectfully, I disagree with your conclusion here:
> 
> 1.) _FORTIFY_SOURCE provides more granular detection of overflow; I 
> don't have to overflow all the way into the canary at the end of the 
> frame to be detected, so my minor bug now can be caught before something 
> causes the stack frame to be rearranged and turn it into a security 
> issue later
> 
> 2.) __builtin_object_size doesn't work on heap objects, but it actually 
> can work on subobjects from a heap allocation (e.g., &foo->name), so the 
> coverage extends beyond the stack into starting to detect other kinds of 
> overflow
> 
> While the security value over stack-protector-strong may be marginal (I 
> won't debate this specifically), the feature still has value in general.
> 
> Thanks,
> 
> Kyle Evans
> 
>     The NetBSD code was not well adapted to clang either.
> 
>     Ask me more if you really want to dig into it, but we don't want this.
> 
>     Pedro.
> 
> 
>     On Monday, May 13, 2024 at 12:24:13 AM GMT-5, Kyle Evans
>     <kevans@freebsd.org> wrote:
> 
> 
>     The branch main has been updated by kevans:
> 
>     URL:
>     https://cgit.FreeBSD.org/src/commit/?id=be04fec42638f30f50b5b55fd8e3634c0fb89928 <https://cgit.FreeBSD.org/src/commit/?id=be04fec42638f30f50b5b55fd8e3634c0fb89928>
> 
>     commit be04fec42638f30f50b5b55fd8e3634c0fb89928
>     Author:    Kyle Evans <kevans@FreeBSD.org <mailto:kevans@FreeBSD.org>>
>     AuthorDate: 2024-05-13 05:23:49 +0000
>     Commit:    Kyle Evans <kevans@FreeBSD.org <mailto: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
>     <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 ***
> 
>