From nobody Thu Dec 28 17:20:12 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4T1Fd92jK9z56Bs9; Thu, 28 Dec 2023 17:20:13 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4T1Fd91417z3ZXK; Thu, 28 Dec 2023 17:20:13 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1703784013; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Yc0Os2VmO5z9gHrnJTUeGqlTowigh+jdcM4cMbhdLfw=; b=GGY/BtY/r8axKgOk+Nto3jBiWBKsugJaix+cygGDPQOKc5rFkLiNFBao7XEEcB0ZyPhe5v LSjrHnL01mIIdzdjMpYuhrkWmU/BZBMWSynolrt5dccYLeksl3l95z/5yE2NGv3vDfbI9B CVon9FqdEAYBMwzYJq7hqiDUxDjM3D9pi0l6sMVAPGIEde18c2PZnOZUedD/C2cNOcJAMX V5uVAb98E0vZlH9er+3MhEDt6RJKjy5HDOnJJah7eRDQ/9Pv8m5cFLpTMMxAkXD0I3I8ks KKXqEOYvlPcxwOvuqvF+wEZpzbl5FF2A1V7zt27KQ2acgK/NZTLsL+UeaxA7Qw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1703784013; a=rsa-sha256; cv=none; b=tkcf0dWtBn6AehIWfZuPB7z+/2nJtfudAIEqlI9FUsnz/z6TpWMJEkug3OR2Ahpuk/kk0N itF6WwQ23IhtOpGRtk6VcARRYfu5htIXHlp1IBKzH09Tf0zz5HgP6uksslnXdnvVHyfZvt CqdLYuOlU/X1aib6Tn8TFgMxAdaT6W0s1MW8/g+qlkLQOg3AUSf/BjI3aELbR2gWheJs1T rDfFGxqLtZXVB74WOqZ2y/Gpcx7TnnEEhMdbuJ3ecPTTlplVLgzn8P0BKB0TGfzOpYu0Va ZJuuBuHj8Nsb5+CBr4QZOaqsK4CjfmvQ391jG5qK5/QXaYD7py3BUmdbaytdkw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1703784013; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Yc0Os2VmO5z9gHrnJTUeGqlTowigh+jdcM4cMbhdLfw=; b=l2Xq9GUM7zKzTXnNhrhlHwjo73wpuBnjwDz9QEIjB9Ck5t+VX7mM9uofKE+lVJI4dsRphT Ihi4x6Rh0RU/le1cFd3ugcNfAjVrSXIvQ43R9iQA/ASyLDlGiJTsfrdu5aAkICRh56jg42 ehvCFFmqkjXE4E9sadWz7q8fuBAceQxGuTu0g5gBeQ86rJX/DtJUELC3uOlQv3xIFY2wdC /NUZIncCuhkuIt1g2UpI+9jWvE59RKuLfXY5T6BM/9OWqUXMTYZcsfQnlayjg7MDa91edT sgBnEGEJB1cOF8RIr9As0PInzDaWrCMFnsocXRQoEooDqhqKfDegZuU9wkhIuw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4T1Fd908b1zXQq; Thu, 28 Dec 2023 17:20:13 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3BSHKCVV079367; Thu, 28 Dec 2023 17:20:12 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3BSHKCqB079359; Thu, 28 Dec 2023 17:20:12 GMT (envelope-from git) Date: Thu, 28 Dec 2023 17:20:12 GMT Message-Id: <202312281720.3BSHKCqB079359@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Robert Clausecker Subject: git: c91cfb7f9e7d - stable/14 - lib/libc/tests/string: expand memcmp test to bcmp, timingsafe_{b,mem}cmp List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: fuz X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: c91cfb7f9e7de392ca47b3092e981bf7c2fca86b Auto-Submitted: auto-generated The branch stable/14 has been updated by fuz: URL: https://cgit.FreeBSD.org/src/commit/?id=c91cfb7f9e7de392ca47b3092e981bf7c2fca86b commit c91cfb7f9e7de392ca47b3092e981bf7c2fca86b Author: Robert Clausecker AuthorDate: 2023-08-30 15:30:24 +0000 Commit: Robert Clausecker CommitDate: 2023-12-28 17:02:41 +0000 lib/libc/tests/string: expand memcmp test to bcmp, timingsafe_{b,mem}cmp The four functions more or less perform the same operation. Reuse the same unit test with slight changes so we can cover them all. Constant-time operation is not verified for the timingsafe_* functions. Sponsored by: The FreeBSD Foundation Approved by: ngie MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D41528 (cherry picked from commit c6cc06d465a98270ef734ffec7c9012ec3a1bd17) --- lib/libc/tests/string/Makefile | 3 + lib/libc/tests/string/bcmp_test.c | 32 ++++++++++ lib/libc/tests/string/memcmp_test.c | 82 ++++++++++++++++++-------- lib/libc/tests/string/timingsafe_bcmp_test.c | 32 ++++++++++ lib/libc/tests/string/timingsafe_memcmp_test.c | 32 ++++++++++ 5 files changed, 155 insertions(+), 26 deletions(-) diff --git a/lib/libc/tests/string/Makefile b/lib/libc/tests/string/Makefile index e9b066cacac7..a090e1bd3463 100644 --- a/lib/libc/tests/string/Makefile +++ b/lib/libc/tests/string/Makefile @@ -2,6 +2,7 @@ # ensure libc functions are tested, not clang's builtins CFLAGS+= -fno-builtin +ATF_TESTS_C+= bcmp_test ATF_TESTS_C+= ffs_test ATF_TESTS_C+= ffsl_test ATF_TESTS_C+= ffsll_test @@ -17,6 +18,8 @@ ATF_TESTS_C+= strerror2_test ATF_TESTS_C+= strspn_test ATF_TESTS_C+= strverscmp_test ATF_TESTS_C+= strxfrm_test +ATF_TESTS_C+= timingsafe_bcmp_test +ATF_TESTS_C+= timingsafe_memcmp_test ATF_TESTS_C+= wcscasecmp_test ATF_TESTS_C+= wcscoll_test ATF_TESTS_C+= wcsnlen_test diff --git a/lib/libc/tests/string/bcmp_test.c b/lib/libc/tests/string/bcmp_test.c new file mode 100644 index 000000000000..fdf5e48b3eb4 --- /dev/null +++ b/lib/libc/tests/string/bcmp_test.c @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2023 The FreeBSD Foundation + * + * This software was developed by Robert Clausecker + * under sponsorship from the FreeBSD Foundation. + * + * 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 + */ + +#define MEMCMP bcmp +#define RES(x) ((x) != 0) + +#include "memcmp_test.c" diff --git a/lib/libc/tests/string/memcmp_test.c b/lib/libc/tests/string/memcmp_test.c index 824e0d27ac0e..5286a0b994f3 100644 --- a/lib/libc/tests/string/memcmp_test.c +++ b/lib/libc/tests/string/memcmp_test.c @@ -1,7 +1,11 @@ /*- * Copyright (c) 2016 Jilles Tjoelker + * Copyright (c) 2023 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by Robert Clausecker + * under sponsorship from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -32,14 +36,40 @@ #include +#ifndef MEMCMP +#define MEMCMP memcmp +#endif + +/* + * On FreeBSD we demand that memcmp returns the difference between the + * characters at the first site of mismatch. However, ISO/IEC 9899:1990 + * only specifies that a number greater than, equal to, or less than + * zero shall be returned. If a unit test for this less strict + * behaviour is desired, define RES(x) to be (((x) > 0) - ((x) < 0)). + */ +#ifndef RES +#define RES(x) (x) +#endif + static int (*memcmp_fn)(const void *, const void *, size_t); +static void +check_memcmp(const char *a, const char *b, size_t len, int expected) +{ + int got; + + got = memcmp_fn(a, b, len); + ATF_CHECK_EQ_MSG(RES(expected), RES(got), + "%s(%p, %p, %zu) gave %d, but wanted %d", + __XSTRING(MEMCMP), a, b, len, got, expected); +} + ATF_TC_WITHOUT_HEAD(zero); ATF_TC_BODY(zero, tc) { - assert(memcmp_fn("a", "b", 0) == 0); - assert(memcmp_fn("", "", 0) == 0); + check_memcmp("a", "b", 0, 0); + check_memcmp("", "", 0, 0); } ATF_TC_WITHOUT_HEAD(eq); @@ -51,9 +81,9 @@ ATF_TC_BODY(eq, tc) for (i = 0; i < 256; i++) data1[i] = data2[i] = i ^ 0x55; for (i = 1; i < 256; i++) - assert(memcmp_fn(data1, data2, i) == 0); + check_memcmp(data1, data2, i, 0); for (i = 1; i < 256; i++) - assert(memcmp_fn(data1 + i, data2 + i, 256 - i) == 0); + check_memcmp(data1 + i, data2 + i, 256 - i, 0); } ATF_TC_WITHOUT_HEAD(neq); @@ -67,9 +97,9 @@ ATF_TC_BODY(neq, tc) data2[i] = i ^ 0x55; } for (i = 1; i < 256; i++) - assert(memcmp_fn(data1, data2, i) != 0); + check_memcmp(data1, data2, i, -0x55); for (i = 1; i < 256; i++) - assert(memcmp_fn(data1 + i, data2 + i, 256 - i) != 0); + check_memcmp(data1 + i, data2 + i, 256 - i, i - (i ^ 0x55)); } ATF_TC_WITHOUT_HEAD(diff); @@ -83,32 +113,32 @@ ATF_TC_BODY(diff, tc) data1[128] = 255; data2[128] = 0; for (i = 1; i < 66; i++) { - assert(memcmp_fn(data1 + 128, data2 + 128, i) == 255); - assert(memcmp_fn(data2 + 128, data1 + 128, i) == -255); - assert(memcmp_fn(data1 + 129 - i, data2 + 129 - i, i) == 255); - assert(memcmp_fn(data2 + 129 - i, data1 + 129 - i, i) == -255); - assert(memcmp_fn(data1 + 129 - i, data2 + 129 - i, i * 2) == 255); - assert(memcmp_fn(data2 + 129 - i, data1 + 129 - i, i * 2) == -255); + check_memcmp(data1 + 128, data2 + 128, i, 255); + check_memcmp(data2 + 128, data1 + 128, i, -255); + check_memcmp(data1 + 129 - i, data2 + 129 - i, i, 255); + check_memcmp(data2 + 129 - i, data1 + 129 - i, i, -255); + check_memcmp(data1 + 129 - i, data2 + 129 - i, i * 2, 255); + check_memcmp(data2 + 129 - i, data1 + 129 - i, i * 2, -255); } data1[128] = 'c'; data2[128] = 'e'; for (i = 1; i < 66; i++) { - assert(memcmp_fn(data1 + 128, data2 + 128, i) == -2); - assert(memcmp_fn(data2 + 128, data1 + 128, i) == 2); - assert(memcmp_fn(data1 + 129 - i, data2 + 129 - i, i) == -2); - assert(memcmp_fn(data2 + 129 - i, data1 + 129 - i, i) == 2); - assert(memcmp_fn(data1 + 129 - i, data2 + 129 - i, i * 2) == -2); - assert(memcmp_fn(data2 + 129 - i, data1 + 129 - i, i * 2) == 2); + check_memcmp(data1 + 128, data2 + 128, i, -2); + check_memcmp(data2 + 128, data1 + 128, i, 2); + check_memcmp(data1 + 129 - i, data2 + 129 - i, i, -2); + check_memcmp(data2 + 129 - i, data1 + 129 - i, i, 2); + check_memcmp(data1 + 129 - i, data2 + 129 - i, i * 2, -2); + check_memcmp(data2 + 129 - i, data1 + 129 - i, i * 2, 2); } memset(data1 + 129, 'A', sizeof(data1) - 129); memset(data2 + 129, 'Z', sizeof(data2) - 129); for (i = 1; i < 66; i++) { - assert(memcmp_fn(data1 + 128, data2 + 128, i) == -2); - assert(memcmp_fn(data2 + 128, data1 + 128, i) == 2); - assert(memcmp_fn(data1 + 129 - i, data2 + 129 - i, i) == -2); - assert(memcmp_fn(data2 + 129 - i, data1 + 129 - i, i) == 2); - assert(memcmp_fn(data1 + 129 - i, data2 + 129 - i, i * 2) == -2); - assert(memcmp_fn(data2 + 129 - i, data1 + 129 - i, i * 2) == 2); + check_memcmp(data1 + 128, data2 + 128, i, -2); + check_memcmp(data2 + 128, data1 + 128, i, 2); + check_memcmp(data1 + 129 - i, data2 + 129 - i, i, -2); + check_memcmp(data2 + 129 - i, data1 + 129 - i, i, 2); + check_memcmp(data1 + 129 - i, data2 + 129 - i, i * 2, -2); + check_memcmp(data2 + 129 - i, data1 + 129 - i, i * 2, 2); } } @@ -117,9 +147,9 @@ ATF_TP_ADD_TCS(tp) void *dl_handle; dl_handle = dlopen(NULL, RTLD_LAZY); - memcmp_fn = dlsym(dl_handle, "test_memcmp"); + memcmp_fn = dlsym(dl_handle, "test_" __XSTRING(MEMCMP)); if (memcmp_fn == NULL) - memcmp_fn = memcmp; + memcmp_fn = MEMCMP; ATF_TP_ADD_TC(tp, zero); ATF_TP_ADD_TC(tp, eq); diff --git a/lib/libc/tests/string/timingsafe_bcmp_test.c b/lib/libc/tests/string/timingsafe_bcmp_test.c new file mode 100644 index 000000000000..96bf789633f2 --- /dev/null +++ b/lib/libc/tests/string/timingsafe_bcmp_test.c @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2023 The FreeBSD Foundation + * + * This software was developed by Robert Clausecker + * under sponsorship from the FreeBSD Foundation. + * + * 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 + */ + +#define MEMCMP timingsafe_bcmp +#define RES(x) ((x) != 0) + +#include "memcmp_test.c" diff --git a/lib/libc/tests/string/timingsafe_memcmp_test.c b/lib/libc/tests/string/timingsafe_memcmp_test.c new file mode 100644 index 000000000000..5f97e41fcf8a --- /dev/null +++ b/lib/libc/tests/string/timingsafe_memcmp_test.c @@ -0,0 +1,32 @@ +/*- + * Copyright (c) 2023 The FreeBSD Foundation + * + * This software was developed by Robert Clausecker + * under sponsorship from the FreeBSD Foundation. + * + * 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 + */ + +#define MEMCMP timingsafe_memcmp +#define RES(x) (((x) > 0) - ((x) < 0)) + +#include "memcmp_test.c"