Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp944210pxb; Sun, 22 Aug 2021 00:59:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz06IP3Y6ES4MPFfepVFzIVeq5OeROaSnV16EBL2JixrhLDJ6PqXIDGlr85kmL7liS6hWqg X-Received: by 2002:a17:906:3e1b:: with SMTP id k27mr1254800eji.284.1629619140417; Sun, 22 Aug 2021 00:59:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629619140; cv=none; d=google.com; s=arc-20160816; b=rbp1m5rxRWxQn76GcWGnqukLRwF3JskzW8EDs+GqoXZD/ztIStKjwNVafG6SY4h6dN ToGiAh984/wzDoypB0aBdsdB5xSoEwPVMOvG6oTaTP1yCWjfh0YgFO6ePYetETSbrK+B kEzkJ5Ifk8n2+fXEXKY9ldFFdmD42vB16VnmM4P1ncMLWcItX5s+DkOdTG/dov07zE+6 9TiN7fgEQd+JJHR7vpdG11n0p1+LIm4/gTOT6RZazT7atT9fpkij2498ww4Blpv/DPIF 4EmrAF+IKIqsQV6J8w91xahEhYyy5YnrrkGJ+T4uGb4DGCnDPqBljM472IKeV9ht9jEe GSEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=esTuixCLLKpApTRPX2HCFeqFboPKiGroJFfFu+WSZ+c=; b=ej480kdJjTtwJbr/pyLBpQsmcns+pSmzUFTJEUJGQsFHGjIcgEH/m09jyPA7E1QlH6 I/A0DZZ6QVipB2blbjCH7aQCJfywOzu6S9FJ5H1/1Nz0IhqByFX4DPjn5p1cYhK/Czcq 75CgjvolzpUOXQ6utR9fYuHcV97/mGH5OFH7e+BbH9r2xQbQCIvB3ugKmAWs2bUHx65P O9kc6AwE6xDBpP4ordvSxawtY1gtNpRNsrB990aZlziWc7/QmoQ2OYVRKHbMb9qceAGj Nos6WZPMBxBZ0zy64jVMj+zBup16XKsQEs1/q/rrB9IFkboMR9riH8awtJWKhJXkvTt6 nVSQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=GKUtY8Zr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id jz19si13341051ejb.37.2021.08.22.00.58.38; Sun, 22 Aug 2021 00:59:00 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=GKUtY8Zr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232841AbhHVH5x (ORCPT + 99 others); Sun, 22 Aug 2021 03:57:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231821AbhHVH5j (ORCPT ); Sun, 22 Aug 2021 03:57:39 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12D9EC061575 for ; Sun, 22 Aug 2021 00:56:59 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id n13-20020a17090a4e0d00b0017946980d8dso16615081pjh.5 for ; Sun, 22 Aug 2021 00:56:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=esTuixCLLKpApTRPX2HCFeqFboPKiGroJFfFu+WSZ+c=; b=GKUtY8ZrZ4YxyomQrw3mctoYe3dAP1PnMS0oH7ETjsmOWcGnzH36Ggp0utlA9FaGJ1 u1cxfGaSuq85aAwt3PInT80bQRHWLJfRvEXw/TYYwmghCjwvNXBJgscwf+nt3Co9q1qS ZxoYlFZa21Mv2qWzBdh2u0QB9kPUEQWehtXBo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=esTuixCLLKpApTRPX2HCFeqFboPKiGroJFfFu+WSZ+c=; b=jRw89Ig8chQahNB4y2WagZo9I5Xo4jYoZ8ufeF/YXFsSq84pFIAv5lNQ4vHqHyod3r xMgVJinHdM/YP2Sd21w9Y/MNm19t3sP0BvNjIg2Z3qw4sjfOeBXwGjnnwHQKdTB/zfqi CVKeAmaK3Ux6CQt921sXlUzQQOFsz0z7IKNwR2vdoR4chz020qRAkKj/5TGEMSDzP3qh 62eYo95uCPpf48mNLFoHAU+KNYAfqp+tjPCddlarQyrYTXLZCP24xSM5J3dazcwrYIRJ tmsBitN5P/LXR2Etz9Yl2jkFUp02vgtvhJr6PnFMQjAYl6GFhti9aR5EzYwIDg3la+do j4/A== X-Gm-Message-State: AOAM532be1+OuXkq+ZQOlLax5XoTWfg5AGXC0iQhPS2v8TLSI/2Ll61D neuvEeo75loDXGKK+euHssrBiA== X-Received: by 2002:a17:902:a40c:b029:12c:17cf:ab6f with SMTP id p12-20020a170902a40cb029012c17cfab6fmr23344154plq.71.1629619018562; Sun, 22 Aug 2021 00:56:58 -0700 (PDT) Received: from www.outflux.net (smtp.outflux.net. [198.145.64.163]) by smtp.gmail.com with ESMTPSA id x19sm12550691pfo.40.2021.08.22.00.56.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Aug 2021 00:56:57 -0700 (PDT) From: Kees Cook To: linux-kernel@vger.kernel.org Cc: Kees Cook , Rasmus Villemoes , Daniel Micay , Francis Laniel , Bart Van Assche , David Gow , linux-mm@kvack.org, clang-built-linux@googlegroups.com, linux-hardening@vger.kernel.org Subject: [PATCH for-next 20/25] fortify: Add compile-time FORTIFY_SOURCE tests Date: Sun, 22 Aug 2021 00:51:17 -0700 Message-Id: <20210822075122.864511-21-keescook@chromium.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210822075122.864511-1-keescook@chromium.org> References: <20210822075122.864511-1-keescook@chromium.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=14487; h=from:subject; bh=d6cDtDi6tN5v08m75LtOJYNhyRaS100VqVCmwytOPcA=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBhIgH5ERUpR7c+mr4L29WRtM/FRs2vNUIC5P2B2Vhn t9DCo3uJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCYSIB+QAKCRCJcvTf3G3AJqHbEA CvBOupzpzAqKpudZfOWXmv6P7Rp4Ydmmt21tYPMRTgrUXM0kUkrpQYgJwUIIK6lDPhndiIS0pjsxZO adadaKlLyh1ZAo3I1qLdrxNgl9iEeTiB9yLXVJB8i+1dCVnppO6AesG77zl2Fvku+4mtZzeHvqZV0a n+sF2GLTt0s/mT30JCo3yktg9egOrws4a7ltpSDjNe4PY4kL4VSD501QjGvkJxiacFMJUb8HWBu9IV W/zGJ6til24TARTtvOXxTvOc1WI8uk2FKUToOA6pRJEaM+IICKp/YBJ0jWM8DFyZtuCcKbEtY8uaCr 4yDE7VTOED9w7uSvCOIod5JGQFxKHUmRZ8W0+LiP/YAoF8fGoQI2wnpsujy18ATF40cdjYNZOXkve6 STYbwV0Go/BCiMT75p8TVboQJzQeuJEMw+MkqGSw1SE0Y92ysetyTv+P9pOfDZGiNTB7qsgH+MuQDl ylRzlYqiYAHETYMDuEkICUmfpxZxVq5aZCGsfznDFeijK+aAeFENs6L7U+QS/s85C70WRsPdU6SVoS giWJzqZf25zLjEd1T0AHLCA5z3LFlJyG9prGFIGoslQyAmpOLWO/0bnLPnd5Y2NIbJ/6CHwtKybd9X P02jcYFpzKpayUTPgY2SzN71CYpawRiaELNkz+YBPxx+sJCnsEXzZsdx2S6g== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org While the run-time testing of FORTIFY_SOURCE is already present in LKDTM, there is no testing of the expected compile-time detections. In preparation for correctly supporting FORTIFY_SOURCE under Clang, adding additional FORTIFY_SOURCE defenses, and making sure FORTIFY_SOURCE doesn't silently regress with GCC, introduce a build-time test suite that checks each expected compile-time failure condition. As this is relatively backwards from standard build rules in the sense that a successful test is actually a compile _failure_, create a wrapper script to check for the correct errors, and wire it up as a dummy dependency to lib/string.o, collecting the results into a log file artifact. Signed-off-by: Kees Cook --- lib/.gitignore | 2 + lib/Makefile | 33 +++++++++++ lib/test_fortify/read_overflow-memchr.c | 5 ++ lib/test_fortify/read_overflow-memchr_inv.c | 5 ++ lib/test_fortify/read_overflow-memcmp.c | 5 ++ lib/test_fortify/read_overflow-memscan.c | 5 ++ lib/test_fortify/read_overflow2-memcmp.c | 5 ++ lib/test_fortify/read_overflow2-memcpy.c | 5 ++ lib/test_fortify/read_overflow2-memmove.c | 5 ++ lib/test_fortify/test_fortify.h | 35 +++++++++++ lib/test_fortify/write_overflow-memcpy.c | 5 ++ lib/test_fortify/write_overflow-memmove.c | 5 ++ lib/test_fortify/write_overflow-memset.c | 5 ++ lib/test_fortify/write_overflow-strcpy-lit.c | 5 ++ lib/test_fortify/write_overflow-strcpy.c | 5 ++ lib/test_fortify/write_overflow-strlcpy-src.c | 5 ++ lib/test_fortify/write_overflow-strlcpy.c | 5 ++ lib/test_fortify/write_overflow-strncpy-src.c | 5 ++ lib/test_fortify/write_overflow-strncpy.c | 5 ++ lib/test_fortify/write_overflow-strscpy.c | 5 ++ scripts/test_fortify.sh | 59 +++++++++++++++++++ 21 files changed, 214 insertions(+) create mode 100644 lib/test_fortify/read_overflow-memchr.c create mode 100644 lib/test_fortify/read_overflow-memchr_inv.c create mode 100644 lib/test_fortify/read_overflow-memcmp.c create mode 100644 lib/test_fortify/read_overflow-memscan.c create mode 100644 lib/test_fortify/read_overflow2-memcmp.c create mode 100644 lib/test_fortify/read_overflow2-memcpy.c create mode 100644 lib/test_fortify/read_overflow2-memmove.c create mode 100644 lib/test_fortify/test_fortify.h create mode 100644 lib/test_fortify/write_overflow-memcpy.c create mode 100644 lib/test_fortify/write_overflow-memmove.c create mode 100644 lib/test_fortify/write_overflow-memset.c create mode 100644 lib/test_fortify/write_overflow-strcpy-lit.c create mode 100644 lib/test_fortify/write_overflow-strcpy.c create mode 100644 lib/test_fortify/write_overflow-strlcpy-src.c create mode 100644 lib/test_fortify/write_overflow-strlcpy.c create mode 100644 lib/test_fortify/write_overflow-strncpy-src.c create mode 100644 lib/test_fortify/write_overflow-strncpy.c create mode 100644 lib/test_fortify/write_overflow-strscpy.c create mode 100644 scripts/test_fortify.sh diff --git a/lib/.gitignore b/lib/.gitignore index 5e7fa54c4536..e5e217b8307b 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -4,3 +4,5 @@ /gen_crc32table /gen_crc64table /oid_registry_data.c +/test_fortify.log +/test_fortify/*.log diff --git a/lib/Makefile b/lib/Makefile index 5efd1b435a37..bd17c2bf43e1 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -360,3 +360,36 @@ obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o + +# FORTIFY_SOURCE compile-time behavior tests +TEST_FORTIFY_SRCS = $(wildcard $(srctree)/$(src)/test_fortify/*-*.c) +TEST_FORTIFY_LOGS = $(patsubst $(srctree)/$(src)/%.c, %.log, $(TEST_FORTIFY_SRCS)) +TEST_FORTIFY_LOG = test_fortify.log + +quiet_cmd_test_fortify = TEST $@ + cmd_test_fortify = $(CONFIG_SHELL) $(srctree)/scripts/test_fortify.sh \ + $< $@ "$(NM)" $(CC) $(c_flags) \ + $(call cc-disable-warning,fortify-source) + +targets += $(TEST_FORTIFY_LOGS) +clean-files += $(TEST_FORTIFY_LOGS) +clean-files += $(addsuffix .o, $(TEST_FORTIFY_LOGS)) +$(obj)/test_fortify/%.log: $(src)/test_fortify/%.c \ + $(src)/test_fortify/test_fortify.h \ + $(srctree)/include/linux/fortify-string.h \ + $(srctree)/scripts/test_fortify.sh \ + FORCE + $(call if_changed,test_fortify) + +quiet_cmd_gen_fortify_log = GEN $@ + cmd_gen_fortify_log = cat /dev/null > $@ || true + +targets += $(TEST_FORTIFY_LOG) +clean-files += $(TEST_FORTIFY_LOG) +$(obj)/$(TEST_FORTIFY_LOG): $(addprefix $(obj)/, $(TEST_FORTIFY_LOGS)) FORCE + $(call if_changed,gen_fortify_log) + +# Fake dependency to trigger the fortify tests. +ifeq ($(CONFIG_FORTIFY_SOURCE),y) +$(obj)/string.o: $(obj)/$(TEST_FORTIFY_LOG) +endif diff --git a/lib/test_fortify/read_overflow-memchr.c b/lib/test_fortify/read_overflow-memchr.c new file mode 100644 index 000000000000..2743084b32af --- /dev/null +++ b/lib/test_fortify/read_overflow-memchr.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memchr(small, 0x7A, sizeof(small) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/read_overflow-memchr_inv.c b/lib/test_fortify/read_overflow-memchr_inv.c new file mode 100644 index 000000000000..b26e1f1bc217 --- /dev/null +++ b/lib/test_fortify/read_overflow-memchr_inv.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memchr_inv(small, 0x7A, sizeof(small) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/read_overflow-memcmp.c b/lib/test_fortify/read_overflow-memcmp.c new file mode 100644 index 000000000000..d5d301ff64ef --- /dev/null +++ b/lib/test_fortify/read_overflow-memcmp.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memcmp(small, large, sizeof(small) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/read_overflow-memscan.c b/lib/test_fortify/read_overflow-memscan.c new file mode 100644 index 000000000000..c1a97f2df0f0 --- /dev/null +++ b/lib/test_fortify/read_overflow-memscan.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memscan(small, 0x7A, sizeof(small) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/read_overflow2-memcmp.c b/lib/test_fortify/read_overflow2-memcmp.c new file mode 100644 index 000000000000..c6091e640f76 --- /dev/null +++ b/lib/test_fortify/read_overflow2-memcmp.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memcmp(large, small, sizeof(small) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/read_overflow2-memcpy.c b/lib/test_fortify/read_overflow2-memcpy.c new file mode 100644 index 000000000000..07b62e56cf16 --- /dev/null +++ b/lib/test_fortify/read_overflow2-memcpy.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memcpy(large, instance.buf, sizeof(large)) + +#include "test_fortify.h" diff --git a/lib/test_fortify/read_overflow2-memmove.c b/lib/test_fortify/read_overflow2-memmove.c new file mode 100644 index 000000000000..34edfab040a3 --- /dev/null +++ b/lib/test_fortify/read_overflow2-memmove.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memmove(large, instance.buf, sizeof(large)) + +#include "test_fortify.h" diff --git a/lib/test_fortify/test_fortify.h b/lib/test_fortify/test_fortify.h new file mode 100644 index 000000000000..d22664fff197 --- /dev/null +++ b/lib/test_fortify/test_fortify.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include +#include +#include + +void do_fortify_tests(void); + +#define __BUF_SMALL 16 +#define __BUF_LARGE 32 +struct fortify_object { + int a; + char buf[__BUF_SMALL]; + int c; +}; + +#define LITERAL_SMALL "AAAAAAAAAAAAAAA" +#define LITERAL_LARGE "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" +const char small_src[__BUF_SMALL] = LITERAL_SMALL; +const char large_src[__BUF_LARGE] = LITERAL_LARGE; + +char small[__BUF_SMALL]; +char large[__BUF_LARGE]; +struct fortify_object instance; +size_t size; + +void do_fortify_tests(void) +{ + /* Normal initializations. */ + memset(&instance, 0x32, sizeof(instance)); + memset(small, 0xA5, sizeof(small)); + memset(large, 0x5A, sizeof(large)); + + TEST; +} diff --git a/lib/test_fortify/write_overflow-memcpy.c b/lib/test_fortify/write_overflow-memcpy.c new file mode 100644 index 000000000000..3b3984e428fb --- /dev/null +++ b/lib/test_fortify/write_overflow-memcpy.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memcpy(instance.buf, large_src, sizeof(large_src)) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-memmove.c b/lib/test_fortify/write_overflow-memmove.c new file mode 100644 index 000000000000..640437c3b3e0 --- /dev/null +++ b/lib/test_fortify/write_overflow-memmove.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memmove(instance.buf, large_src, sizeof(large_src)) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-memset.c b/lib/test_fortify/write_overflow-memset.c new file mode 100644 index 000000000000..36e34908cfb3 --- /dev/null +++ b/lib/test_fortify/write_overflow-memset.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + memset(instance.buf, 0x5A, sizeof(large_src)) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-strcpy-lit.c b/lib/test_fortify/write_overflow-strcpy-lit.c new file mode 100644 index 000000000000..51effb3e50f9 --- /dev/null +++ b/lib/test_fortify/write_overflow-strcpy-lit.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + strcpy(small, LITERAL_LARGE) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-strcpy.c b/lib/test_fortify/write_overflow-strcpy.c new file mode 100644 index 000000000000..84f1c56a64c8 --- /dev/null +++ b/lib/test_fortify/write_overflow-strcpy.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + strcpy(small, large_src) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-strlcpy-src.c b/lib/test_fortify/write_overflow-strlcpy-src.c new file mode 100644 index 000000000000..91bf83ebd34a --- /dev/null +++ b/lib/test_fortify/write_overflow-strlcpy-src.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + strlcpy(small, large_src, sizeof(small) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-strlcpy.c b/lib/test_fortify/write_overflow-strlcpy.c new file mode 100644 index 000000000000..1883db7c0cd6 --- /dev/null +++ b/lib/test_fortify/write_overflow-strlcpy.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + strlcpy(instance.buf, large_src, sizeof(instance.buf) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-strncpy-src.c b/lib/test_fortify/write_overflow-strncpy-src.c new file mode 100644 index 000000000000..8dcfb8c788dd --- /dev/null +++ b/lib/test_fortify/write_overflow-strncpy-src.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + strncpy(small, large_src, sizeof(small) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-strncpy.c b/lib/test_fortify/write_overflow-strncpy.c new file mode 100644 index 000000000000..b85f079c815d --- /dev/null +++ b/lib/test_fortify/write_overflow-strncpy.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + strncpy(instance.buf, large_src, sizeof(instance.buf) + 1) + +#include "test_fortify.h" diff --git a/lib/test_fortify/write_overflow-strscpy.c b/lib/test_fortify/write_overflow-strscpy.c new file mode 100644 index 000000000000..38feddf377dc --- /dev/null +++ b/lib/test_fortify/write_overflow-strscpy.c @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define TEST \ + strscpy(instance.buf, large_src, sizeof(instance.buf) + 1) + +#include "test_fortify.h" diff --git a/scripts/test_fortify.sh b/scripts/test_fortify.sh new file mode 100644 index 000000000000..622c7a0b15e5 --- /dev/null +++ b/scripts/test_fortify.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +set -e + +# Argument 1: Source file to build. +IN="$1" +shift +# Extract just the filename for error messages below. +FILE="${IN##*/}" +# Extract the function name for error messages below. +FUNC="${FILE#*-}" +FUNC="${FUNC%%-*}" +FUNC="${FUNC%%.*}" +# Extract the symbol to test for in build/symbol test below. +WANT="__${FILE%%-*}" + +# Argument 2: Where to write the build log. +OUT="$1" +shift +TMP="${OUT}.tmp" + +# Argument 3: Path to "nm" tool. +NM="$1" +shift + +# Remaining arguments are: $(CC) $(c_flags) + +# Clean up temporary file at exit. +__cleanup() { + rm -f "$TMP" +} +trap __cleanup EXIT + +status= +# Attempt to build a source that is expected to fail with a specific warning. +if "$@" -Werror -c "$IN" -o "$OUT".o 2> "$TMP" ; then + # If the build succeeds, either the test has failed or the + # warning may only happen at link time (Clang). In that case, + # make sure the expected symbol is unresolved in the symbol list. + # If so, FORTIFY is working for this case. + if ! $NM -A "$OUT".o | grep -m1 "\bU ${WANT}$" >>"$TMP" ; then + status="warning: unsafe ${FUNC}() usage lacked '$WANT' symbol in $IN" + fi +else + # If the build failed, check for the warning in the stderr (gcc). + if ! grep -q -m1 "error:.*\b${WANT}'" "$TMP" ; then + status="warning: unsafe ${FUNC}() usage lacked '$WANT' warning in $IN" + fi +fi + +if [ -n "$status" ]; then + # Report on failure results, including compilation warnings. + echo "$status" | tee "$OUT" >&2 + cat "$TMP" | tee -a "$OUT" >&2 +else + # Report on good results, and save any compilation output to log. + echo "ok: unsafe ${FUNC}() usage correctly detected with '$WANT' in $IN" >"$OUT" + cat "$TMP" >>"$OUT" +fi -- 2.30.2