From: Roy Marples Date: Sun, 21 Jun 2026 15:40:51 +0000 (+0100) Subject: auth: clear keys with memset_explicit X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cc05008e73be346d8d84d8dd3a70e7affc16a444;p=thirdparty%2Fdhcpcd.git auth: clear keys with memset_explicit Supply compat/memset_explicit for platforms which lack it. Adpat compat/arc4random.c for it. Reported by NVIDIA Project Vanessa --- diff --git a/compat/arc4random.c b/compat/arc4random.c index a07f84e3..f99c7651 100644 --- a/compat/arc4random.c +++ b/compat/arc4random.c @@ -204,16 +204,7 @@ _rs_stir(void) _rs_init(rnd, sizeof(rnd)); else _rs_rekey(rnd, sizeof(rnd)); -#if defined(HAVE_EXPLICIT_BZERO) - explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */ -#elif defined(HAVE_MEMSET_EXPLICIT) (void)memset_explicit(rnd, 0, sizeof(rnd)); -#elif defined(HAVE_MEMSET_S) - (void)memset_s(rnd, sizeof(rnd), 0, sizeof(rnd)); -#else -#warning potentially insecure use of memset discarding the source seed - (void)memset(rnd, 0, sizeof(rnd)); /* discard source seed */ -#endif /* invalidate rs_buf */ rs->rs_have = 0; diff --git a/compat/memset_explicit.c b/compat/memset_explicit.c new file mode 100644 index 00000000..72ad6469 --- /dev/null +++ b/compat/memset_explicit.c @@ -0,0 +1,53 @@ +/* + * memset_explicit compat + * SPDX-License-Identifier: BSD-2-Clause + * Copyright (c) 2026 Roy Marples + * All rights reserved + + * 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 AUTHOR 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 AUTHOR 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 "config.h" + +#define __STDC_WANT_LIB_EXT1__ 1 +#include + +void * +memset_explicit(void *b, int c, size_t len) +{ +#if defined(HAVE_EXPLICIT_MEMSET) + return explicit_memset(b, c, len); +#else +#if defined(HAVE_MEMSET_S) + if (memset_s(b, len, c, len) == 0) + return b; +#elif defined(HAVE_EXPLICIT_BZERO) + if (c == 0) { + explicit_bzero(b, len); + return b; + } +#endif + void * (* const volatile vmemset)(void *, int, size_t) = memset; + return vmemset(b, c, len); +#endif +} diff --git a/compat/memset_explicit.h b/compat/memset_explicit.h new file mode 100644 index 00000000..564c4a8f --- /dev/null +++ b/compat/memset_explicit.h @@ -0,0 +1,36 @@ +/* + * memset_explicit compat + * SPDX-License-Identifier: BSD-2-Clause + * Copyright (c) 2026 Roy Marples + * All rights reserved + + * 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 AUTHOR 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 AUTHOR 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 MEMSET_EXPLICIT_H +#define MEMSET_EXPLICIT_H + +#include + +void * memset_explicit(void *, int, size_t); + +#endif diff --git a/configure b/configure index 3fbb7354..959b777a 100755 --- a/configure +++ b/configure @@ -938,7 +938,6 @@ if [ "$ARC4RANDOM_UNIFORM" = no ]; then echo "#include \"compat/arc4random_uniform.h\"" >>$CONFIG_H fi -# Our arc4random compat needs memset_explicit, explicit_bzero or memset_s if [ -z "$MEMSET_EXPLICIT" ]; then printf "Testing for memset_explicit ... " cat <_memset_explicit.c @@ -957,11 +956,34 @@ EOF echo "$MEMSET_EXPLICIT" rm -rf _memset_explicit.* _memset_explicit fi -if [ "$MEMSET_EXPLICIT" = yes ]; then - echo "#define HAVE_MEMSET_EXPLICIT" >>$CONFIG_H +if [ "$MEMSET_EXPLICIT" = no ]; then + echo "COMPAT_SRCS+= compat/memset_explicit.c" >>$CONFIG_MK + echo "#include \"compat/memset_explicit.h\"" >>$CONFIG_H fi -if [ -z "$EXPLICIT_BZERO" ]; then +if [ "$MEMSET_EXPLICIT" = no ] && [ -z "$EXPLICIT_MEMSET" ]; then + printf "Testing for explicit_memset ... " + cat <_explicit_memset.c +#include +int main(void) { + int a; + (void)explicit_memset(&a, 0, sizeof(a)); + return 0; +} +EOF + if $XCC _explicit_memset.c -o _explicit_memset 2>&3; then + EXPLICIT_MEMSET=yes + else + EXPLICIT_MEMSET=no + fi + echo "$EXPLICIT_MEMSET" + rm -rf _explicit_memset.* _explicit_memset +fi +if [ "$EXPLICIT_MEMSET" = yes ]; then + echo "#define HAVE_EXPLICIT_MEMSET" >>$CONFIG_H +fi + +if [ "$MEMSET_EXPLICIT" = no ] && [ -z "$EXPLICIT_BZERO" ]; then printf "Testing for explicit_bzero ... " cat <_explicit_bzero.c #define _BSD_SOURCE // musl, will be added for Linux in config.h @@ -984,7 +1006,7 @@ if [ "$EXPLICIT_BZERO" = yes ]; then echo "#define HAVE_EXPLICIT_BZERO" >>$CONFIG_H fi -if [ -z "$MEMSET_S" ]; then +if [ "$MEMSET_EXPLICIT" = no ] && [ -z "$MEMSET_S" ]; then printf "Testing for memset_s ... " cat <_memset_s.c #define __STDC_WANT_LIB_EXT1__ 1 @@ -1004,7 +1026,6 @@ EOF rm -rf _memset_s.* _memset_s fi if [ "$MEMSET_S" = yes ]; then - echo "#define __STDC_WANT_LIB_EXT1__ 1" >>$CONFIG_H echo "#define HAVE_MEMSET_S" >>$CONFIG_H fi diff --git a/src/auth.c b/src/auth.c index 597f10c9..33aaa5c8 100644 --- a/src/auth.c +++ b/src/auth.c @@ -77,20 +77,29 @@ #define HMAC_LENGTH 16 +static void +free_token(struct token *t) +{ + if (t == NULL) + return; + + if (t->key != NULL) + (void)memset_explicit(t->key, 0, t->key_len); + free(t->key); + free(t->realm); + free(t); +} + void dhcp_auth_reset(struct authstate *state) { state->replay = 0; - if (state->token) { - free(state->token->key); - free(state->token->realm); - free(state->token); + if (state->token != NULL) { + free_token(state->token); state->token = NULL; } if (state->reconf) { - free(state->reconf->key); - free(state->reconf->realm); - free(state->reconf); + free_token(state->reconf); state->reconf = NULL; } }