| /* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * Copyright (c) 2016-2017 Nest Labs, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /** |
| * @file |
| * Implementation of the fault-injection utilities for CHIP. |
| */ |
| #include "CHIPFaultInjection.h" |
| |
| #include <nlassert.h> |
| |
| #include <string.h> |
| |
| namespace chip { |
| namespace FaultInjection { |
| |
| static nl::FaultInjection::Record sFaultRecordArray[kFault_NumItems]; |
| static int32_t sFault_CHIPNotificationSize_Arguments[1]; |
| static int32_t sFault_FuzzExchangeHeader_Arguments[1]; |
| static class nl::FaultInjection::Manager sChipFaultInMgr; |
| static const nl::FaultInjection::Name sManagerName = "chip"; |
| static const nl::FaultInjection::Name sFaultNames[] = { |
| "AllocExchangeContext", |
| "DropIncomingUDPMsg", |
| "DropOutgoingUDPMsg", |
| "AllocBinding", |
| "SendAlarm", |
| "HandleAlarm", |
| "FuzzExchangeHeaderTx", |
| "RMPDoubleTx", |
| "RMPSendError", |
| "BDXBadBlockCounter", |
| "BDXAllocTransfer", |
| "SecMgrBusy", |
| "IMInvoke_SeparateResponses", |
| "IMInvoke_SeparateResponsesInvertResponseOrder", |
| "IMInvoke_SkipSecondResponse", |
| #if CONFIG_NETWORK_LAYER_BLE |
| "CHIPOBLESend", |
| #endif // CONFIG_NETWORK_LAYER_BLE |
| "CASEServerBusy", |
| }; |
| |
| /** |
| * Get the singleton FaultInjection::Manager for Inet faults |
| */ |
| nl::FaultInjection::Manager & GetManager() |
| { |
| if (0 == sChipFaultInMgr.GetNumFaults()) |
| { |
| sChipFaultInMgr.Init(kFault_NumItems, sFaultRecordArray, sManagerName, sFaultNames); |
| memset(&sFault_CHIPNotificationSize_Arguments, 0, sizeof(sFault_CHIPNotificationSize_Arguments)); |
| memset(&sFault_FuzzExchangeHeader_Arguments, 0, sizeof(sFault_FuzzExchangeHeader_Arguments)); |
| sFaultRecordArray[kFault_FuzzExchangeHeaderTx].mArguments = sFault_FuzzExchangeHeader_Arguments; |
| sFaultRecordArray[kFault_FuzzExchangeHeaderTx].mLengthOfArguments = |
| static_cast<uint8_t>(sizeof(sFault_FuzzExchangeHeader_Arguments) / sizeof(sFault_FuzzExchangeHeader_Arguments[0])); |
| } |
| return sChipFaultInMgr; |
| } |
| |
| /** |
| * Fuzz a byte of a CHIP Exchange Header |
| * |
| * @param[in] p Pointer to the encoded Exchange Header |
| * @param[in] arg An index from 0 to (CHIP_FAULT_INJECTION_NUM_FUZZ_VALUES * 5 -1) |
| * that specifies the byte to be corrupted and the value to use. |
| */ |
| DLL_EXPORT void FuzzExchangeHeader(uint8_t * p, int32_t arg) |
| { |
| // CHIP is little endian; this function alters the |
| // least significant byte of the header fields. |
| const uint8_t offsets[] = { |
| 0, // flags and version |
| 1, // MessageType |
| 2, // ExchangeId |
| 4, // ProfileId |
| 8 // AckMessageCounter |
| }; |
| const uint8_t values[CHIP_FAULT_INJECTION_NUM_FUZZ_VALUES] = { 0x1, 0x2, 0xFF }; |
| size_t offsetIndex = 0; |
| size_t valueIndex = 0; |
| size_t numOffsets = sizeof(offsets) / sizeof(offsets[0]); |
| offsetIndex = static_cast<uint32_t>(arg) % (numOffsets); |
| valueIndex = (static_cast<uint32_t>(arg) / numOffsets) % CHIP_FAULT_INJECTION_NUM_FUZZ_VALUES; |
| p[offsetIndex] ^= values[valueIndex]; |
| } |
| |
| } // namespace FaultInjection |
| } // namespace chip |