Coverage Report

Created: 2026-07-25 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fuzz_fru_parser.cpp
Line
Count
Source
1
// Copyright 2026 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <cstdint>
16
#include <cstddef>
17
#include <vector>
18
#include <memory>
19
#include <string>
20
21
#include "frup.hpp"
22
#include "fru_area.hpp"
23
#include "writefrudata.hpp"
24
25
using FruAreaVector = std::vector<std::unique_ptr<IPMIFruArea>>;
26
27
int ipmiValidateCommonHeader(const uint8_t* fruData, const size_t dataLen);
28
int ipmiPopulateFruAreas(uint8_t* fruData, const size_t dataLen,
29
                         FruAreaVector& fruAreaVec);
30
ipmi_fru_area_type getFruAreaType(uint8_t areaOffset);
31
32
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
33
525
{
34
525
    if (data == nullptr || size < 8)
35
4
    {
36
4
        return 0;
37
4
    }
38
39
    // 1. Direct Fuzzing of raw FRU Area Parsing for all FRU area types
40
521
    IPMIFruInfo fruInfo = {};
41
521
    parse_fru_area(IPMI_FRU_AREA_INTERNAL_USE, data, size, fruInfo);
42
521
    parse_fru_area(IPMI_FRU_AREA_CHASSIS_INFO, data, size, fruInfo);
43
521
    parse_fru_area(IPMI_FRU_AREA_BOARD_INFO, data, size, fruInfo);
44
521
    parse_fru_area(IPMI_FRU_AREA_PRODUCT_INFO, data, size, fruInfo);
45
521
    parse_fru_area(IPMI_FRU_AREA_MULTI_RECORD, data, size, fruInfo);
46
47
    // 2. Fuzzing IPMI Common Header Validation and Area Extraction
48
521
    if (ipmiValidateCommonHeader(data, size) == 0)
49
218
    {
50
218
        FruAreaVector fruAreaVec;
51
        // Pre-populate fruAreaVec with expected areas as done in writefrudata
52
218
        for (uint8_t fruEntry = IPMI_FRU_INTERNAL_OFFSET;
53
1.30k
             fruEntry < (sizeof(struct common_header) - 2); fruEntry++)
54
1.09k
        {
55
1.09k
            fruAreaVec.emplace_back(
56
1.09k
                std::make_unique<IPMIFruArea>(0, getFruAreaType(fruEntry)));
57
1.09k
        }
58
59
        // Test populating areas from fuzzed image buffer
60
218
        std::vector<uint8_t> fruBuffer(data, data + size);
61
218
        ipmiPopulateFruAreas(fruBuffer.data(), fruBuffer.size(), fruAreaVec);
62
63
        // Test each individual extracted area
64
218
        for (auto& area : fruAreaVec)
65
1.01k
        {
66
1.01k
            if (area->getLength() >= 8 && area->getData() != nullptr)
67
365
            {
68
365
                IPMIFruInfo areaInfo = {};
69
365
                parse_fru_area(area->getType(), area->getData(), area->getLength(), areaInfo);
70
365
            }
71
1.01k
        }
72
218
    }
73
74
521
    return 0;
75
525
}