diff --git a/BUILD b/BUILD index ba3b540541..b7e68d4c9d 100644 --- a/BUILD +++ b/BUILD @@ -87,6 +87,10 @@ docs( "bundle": "//score/result:docs", "mount_at": "baselibs/components/result", }, + { + "bundle": "//score/analysis/tracing:docs", + "mount_at": "baselibs/components/analysis/tracing", + }, { "bundle": "//score/static_reflection_with_serialization:docs", "mount_at": "baselibs/components/static_reflection_with_serialization", diff --git a/docs/baselibs/components/index.rst b/docs/baselibs/components/index.rst index 75aac0dcd8..addc50fd21 100644 --- a/docs/baselibs/components/index.rst +++ b/docs/baselibs/components/index.rst @@ -55,3 +55,4 @@ Overview - *mw::log*: Logging frontend. - :need:`doc__utils`: Provides a collection of small, reusable utilities that do not fit into the other base libraries. +- :need:`doc__analysis_tracing`: Provides tracing utilities that detect corruption of wrapped data. diff --git a/score/analysis/tracing/BUILD b/score/analysis/tracing/BUILD new file mode 100644 index 0000000000..0930df3fca --- /dev/null +++ b/score/analysis/tracing/BUILD @@ -0,0 +1,20 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@score_docs_as_code//:docs.bzl", "docs_bundle") + +docs_bundle( + name = "docs", + source_dir = "docs", + visibility = ["//visibility:public"], +) diff --git a/score/analysis/tracing/common/canary_wrapper/test/canary_wrapper_test.cpp b/score/analysis/tracing/common/canary_wrapper/test/canary_wrapper_test.cpp index 340611a178..ea200df85d 100644 --- a/score/analysis/tracing/common/canary_wrapper/test/canary_wrapper_test.cpp +++ b/score/analysis/tracing/common/canary_wrapper/test/canary_wrapper_test.cpp @@ -25,6 +25,11 @@ namespace tracing // Test with uint64_t canaries (default) TEST(CanaryWrapperTest, DefaultConstructorInitializesCanariesUint64) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that the default wrapper initializes 64-bit canaries and exposes a default value."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); const CanaryWrapper wrapper; EXPECT_TRUE(wrapper.GetData().has_value()); auto data = wrapper.GetData(); @@ -35,6 +40,11 @@ TEST(CanaryWrapperTest, DefaultConstructorInitializesCanariesUint64) // Test with uint32_t canaries TEST(CanaryWrapperTest, DefaultConstructorInitializesCanariesUint32) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that the wrapper supports 32-bit canaries while preserving access to a default value."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); const CanaryWrapper wrapper; EXPECT_TRUE(wrapper.GetData().has_value()); auto data = wrapper.GetData(); @@ -44,6 +54,11 @@ TEST(CanaryWrapperTest, DefaultConstructorInitializesCanariesUint32) TEST(CanaryWrapperTest, ConstructorForwardsSingleArgument) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that single-argument construction stores the supplied value behind valid canaries."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); CanaryWrapper wrapper(42); EXPECT_TRUE(wrapper.GetData().has_value()); auto data = wrapper.GetData(); @@ -53,6 +68,12 @@ TEST(CanaryWrapperTest, ConstructorForwardsSingleArgument) TEST(CanaryWrapperTest, ConstructorForwardsMultipleArguments) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty( + "Description", + "Check that multiple constructor arguments are forwarded to the wrapped type without losing integrity checks."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); struct TestStruct { int a; @@ -70,6 +91,11 @@ TEST(CanaryWrapperTest, ConstructorForwardsMultipleArguments) TEST(CanaryWrapperTest, ConstructorForwardsStringArgument) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that a string value can be constructed and retrieved through a 32-bit canary wrapper."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); std::string str = "hello"; CanaryWrapper wrapper(str); EXPECT_TRUE(wrapper.GetData().has_value()); @@ -80,6 +106,12 @@ TEST(CanaryWrapperTest, ConstructorForwardsStringArgument) TEST(CanaryWrapperTest, GetDataReturnsEmptyOptionalWhenCorrupted) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty( + "Description", + "Check that corrupting a canary changes data access from an engaged reference to an empty optional."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "error-guessing"); CanaryWrapper wrapper(42); EXPECT_TRUE(wrapper.GetData().has_value()); @@ -100,6 +132,11 @@ TEST(CanaryWrapperTest, GetDataReturnsEmptyOptionalWhenCorrupted) TEST(CanaryWrapperTest, DetectsStartCanaryCorruption) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that corruption of the start canary is detected before wrapped data is returned."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "error-guessing"); CanaryWrapper wrapper(42); EXPECT_TRUE(wrapper.GetData().has_value()); @@ -111,6 +148,11 @@ TEST(CanaryWrapperTest, DetectsStartCanaryCorruption) TEST(CanaryWrapperTest, DetectsEndCanaryCorruption) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that corruption of the end canary is detected before wrapped data is returned."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "error-guessing"); CanaryWrapper wrapper(42); EXPECT_TRUE(wrapper.GetData().has_value()); @@ -123,6 +165,12 @@ TEST(CanaryWrapperTest, DetectsEndCanaryCorruption) TEST(CanaryWrapperTest, IsCorruptedAllConditions) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty( + "Description", + "Check that each valid and corrupted combination of the two canaries produces the expected access decision."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "equivalence-classes"); // Test condition 1: canary_start != kCanaryStart → true (corrupted) { CanaryWrapper wrapper(42); @@ -175,6 +223,10 @@ TEST(CanaryWrapperTest, IsCorruptedAllConditions) TEST(CanaryWrapperTest, DetectsBothCanariesCorrupted) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", "Check that simultaneous corruption of both 32-bit canaries is rejected."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "error-guessing"); CanaryWrapper wrapper(42); EXPECT_TRUE(wrapper.GetData().has_value()); @@ -189,6 +241,11 @@ TEST(CanaryWrapperTest, DetectsBothCanariesCorrupted) TEST(CanaryWrapperTest, DataAccessible) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that valid wrapped data can be read and modified while canary checks remain valid."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); CanaryWrapper wrapper(100); // Read access @@ -208,6 +265,12 @@ TEST(CanaryWrapperTest, DataAccessible) TEST(CanaryWrapperTest, MemoryLayoutCorrect) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty( + "Description", + "Check that the 32-bit wrapper stores start canary, aligned data, and end canary in the required layout."); + RecordProperty("TestType", "interface-test"); + RecordProperty("DerivationTechnique", "design-analysis"); CanaryWrapper wrapper(42); // Verify memory layout: canary_start, data, canary_end @@ -223,6 +286,11 @@ TEST(CanaryWrapperTest, MemoryLayoutCorrect) TEST(CanaryWrapperTest, ComplexTypeWrapper) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that a complex aggregate can be wrapped, initialized, and retrieved with intact canaries."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); struct ComplexType { int x; @@ -245,6 +313,11 @@ TEST(CanaryWrapperTest, ComplexTypeWrapper) TEST(CanaryWrapperTest, CopyConstructorPreservesDataAndRefreshesCanaries) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that copying a valid wrapper preserves its data and yields valid canary checks."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); CanaryWrapper original(42); EXPECT_TRUE(original.GetData().has_value()); @@ -257,6 +330,10 @@ TEST(CanaryWrapperTest, CopyConstructorPreservesDataAndRefreshesCanaries) TEST(CanaryWrapperTest, CopyConstructorCopiesCorruptionState) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", "Check that copying a corrupted wrapper does not hide its invalid canary state."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "equivalence-classes"); CanaryWrapper original(42); // Corrupt original @@ -273,6 +350,11 @@ TEST(CanaryWrapperTest, CopyConstructorCopiesCorruptionState) TEST(CanaryWrapperTest, CopyAssignmentPreservesDataAndRefreshesCanaries) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that copy assignment transfers valid data while preserving canary protection."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); CanaryWrapper original(42); CanaryWrapper copy(0); @@ -285,6 +367,10 @@ TEST(CanaryWrapperTest, CopyAssignmentPreservesDataAndRefreshesCanaries) TEST(CanaryWrapperTest, CopyAssignmentCopiesCorruptionState) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", "Check that copy assignment preserves detection of a corrupted source wrapper."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "equivalence-classes"); CanaryWrapper original(42); CanaryWrapper copy(0); @@ -302,6 +388,10 @@ TEST(CanaryWrapperTest, CopyAssignmentCopiesCorruptionState) TEST(CanaryWrapperTest, MoveConstructorPreservesDataAndCanaries) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", "Check that moving a valid string wrapper preserves its data and valid canaries."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); std::string str = "hello"; CanaryWrapper original(str); EXPECT_TRUE(original.GetData().has_value()); @@ -315,6 +405,11 @@ TEST(CanaryWrapperTest, MoveConstructorPreservesDataAndCanaries) TEST(CanaryWrapperTest, MoveAssignmentPreservesDataAndCanaries) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that move assignment transfers valid wrapped data without invalidating canary checks."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "equivalence-classes"); std::string str1 = "hello"; std::string str2 = "world"; CanaryWrapper original(str1); @@ -329,6 +424,10 @@ TEST(CanaryWrapperTest, MoveAssignmentPreservesDataAndCanaries) TEST(CanaryWrapperTest, MoveConstructorCopiesCorruptionState) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", "Check that moving a corrupted wrapper preserves the corruption indication."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "equivalence-classes"); std::string str = "hello"; CanaryWrapper original(str); @@ -344,6 +443,10 @@ TEST(CanaryWrapperTest, MoveConstructorCopiesCorruptionState) TEST(CanaryWrapperTest, MoveAssignmentCopiesCorruptionState) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", "Check that move assignment preserves detection of a corrupted source wrapper."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "equivalence-classes"); std::string str1 = "hello"; std::string str2 = "world"; CanaryWrapper original(str1); @@ -361,6 +464,11 @@ TEST(CanaryWrapperTest, MoveAssignmentCopiesCorruptionState) TEST(CanaryWrapperTest, DetectsOnlyStartCanaryCorruptionWithValidEnd) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that corrupting only the start canary is rejected while the end canary remains valid."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "boundary-values"); CanaryWrapper wrapper(42); // Verify initial state is valid @@ -377,6 +485,11 @@ TEST(CanaryWrapperTest, DetectsOnlyStartCanaryCorruptionWithValidEnd) TEST(CanaryWrapperTest, DetectsOnlyEndCanaryCorruptionWithValidStart) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", + "Check that corrupting only the end canary is rejected while the start canary remains valid."); + RecordProperty("TestType", "fault-injection"); + RecordProperty("DerivationTechnique", "boundary-values"); CanaryWrapper wrapper(42); // Verify initial state is valid @@ -394,6 +507,10 @@ TEST(CanaryWrapperTest, DetectsOnlyEndCanaryCorruptionWithValidStart) TEST(CanaryWrapperTest, BothCanariesValidReturnsData) { + RecordProperty("PartiallyVerifies", "comp_req__analysis_tracing__canary_integrity"); + RecordProperty("Description", "Check that data remains available when both canaries retain their valid values."); + RecordProperty("TestType", "requirements-based"); + RecordProperty("DerivationTechnique", "boundary-values"); CanaryWrapper wrapper(42); // Both canaries are valid - this tests the "all false" path diff --git a/score/analysis/tracing/docs/architecture/index.rst b/score/analysis/tracing/docs/architecture/index.rst new file mode 100644 index 0000000000..1069a0d9bd --- /dev/null +++ b/score/analysis/tracing/docs/architecture/index.rst @@ -0,0 +1,34 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Analysis Tracing Architecture +############################## + +.. document:: Analysis Tracing Architecture + :id: doc__analysis_tracing_architecture + :status: draft + :version: 1 + :safety: ASIL_B + :security: YES + :realizes: wp__component_arch[version==1] + +.. comp:: Analysis Tracing + :id: comp__baselibs_analysis_tracing + :security: YES + :safety: ASIL_B + :status: valid + :version: 1 + :belongs_to: feat__baselibs[version==1] + + The Analysis Tracing component contains tracing utilities for detecting corruption of wrapped data. \ No newline at end of file diff --git a/score/analysis/tracing/docs/index.rst b/score/analysis/tracing/docs/index.rst new file mode 100644 index 0000000000..9c563f9dc7 --- /dev/null +++ b/score/analysis/tracing/docs/index.rst @@ -0,0 +1,33 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Tracing +####### + +.. document:: Analysis Tracing + :id: doc__analysis_tracing + :status: draft + :version: 1 + :safety: ASIL_B + :security: YES + :realizes: wp__cmpt_request[version==1] + +.. toctree:: + :hidden: + + requirements/index.rst + architecture/index.rst + +The Analysis Tracing component provides tracing support utilities that protect +wrapped data from undetected memory corruption. \ No newline at end of file diff --git a/score/analysis/tracing/docs/requirements/index.rst b/score/analysis/tracing/docs/requirements/index.rst new file mode 100644 index 0000000000..001066be79 --- /dev/null +++ b/score/analysis/tracing/docs/requirements/index.rst @@ -0,0 +1,41 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Requirements +############ + +.. document:: Analysis Tracing Requirements + :id: doc__analysis_tracing_requirements + :status: draft + :version: 1 + :safety: ASIL_B + :security: YES + :realizes: wp__requirements_comp[version==1] + :tags: requirements, analysis_tracing + +Functional Requirements +======================= + +.. comp_req:: Canary-Protected Data Integrity + :id: comp_req__analysis_tracing__canary_integrity + :reqtype: Functional + :security: YES + :safety: ASIL_B + :derived_from: feat_req__com__data_corruption[version==1] + :status: valid + :version: 1 + :tags: inspected + :satisfied_by: comp__baselibs_analysis_tracing[version==1] + + The Analysis Tracing component shall wrap arbitrary data with configurable start and end canary values, detect corruption of either canary during data access, and report corrupted data as unavailable. \ No newline at end of file