Skip to content

Commit 28f1d64

Browse files
committed
bound cf_table reads when building the cfg and call graph
1 parent 88f66c0 commit 28f1d64

4 files changed

Lines changed: 24 additions & 6 deletions

File tree

‎centipede/call_graph.cc‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,18 @@ void CallGraph::InitializeCallGraph(const CFTable &cf_table,
4343
if (IsFunctionEntry(current_pc)) current_function_entry = current_pc;
4444

4545
// Iterate over successors.
46-
while (cf_table[j]) {
46+
while (j < cf_table.size() && cf_table[j]) {
4747
++j;
4848
}
4949
++j; // Step over the delimeter.
5050

5151
// Iterate over callees.
52-
while (cf_table[j]) {
52+
while (j < cf_table.size() && cf_table[j]) {
5353
current_callees.push_back(cf_table[j]);
5454
++j;
5555
}
5656
++j; // Step over the delimeter.
57-
FUZZTEST_CHECK_LE(j, cf_table.size());
57+
FUZZTEST_CHECK_LE(j, cf_table.size()) << "Malformed CF table";
5858

5959
if (current_callees.empty()) continue;
6060
basic_block_callees_[current_pc] = current_callees;

‎centipede/call_graph_test.cc‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ TEST(CallGraphDeathTest, CgNoneExistentPc) {
7272
EXPECT_DEATH(call_graph.GetBasicBlockCallees(666), "");
7373
}
7474

75+
TEST(CallGraphDeathTest, CgTruncatedCfTable) {
76+
// The record for PC 1 is missing both of its delimiters, which is what a
77+
// partially written cf-table file looks like.
78+
static const CFTable truncated_cf_table = {1, 2, 3};
79+
CallGraph call_graph;
80+
EXPECT_DEATH(call_graph.InitializeCallGraph(truncated_cf_table, g_pc_table),
81+
"Malformed CF table");
82+
}
83+
7584
TEST(CallGraph, BuildCgFromCfTable) {
7685
CallGraph call_graph;
7786
call_graph.InitializeCallGraph(g_cf_table, g_pc_table);

‎centipede/control_flow.cc‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ void ControlFlowGraph::InitializeControlFlowGraph(const CFTable &cf_table,
145145
++j;
146146

147147
// Iterate over successors.
148-
while (cf_table[j]) {
148+
while (j < cf_table.size() && cf_table[j]) {
149149
successors.push_back(cf_table[j]);
150150
++j;
151151
}
@@ -157,11 +157,11 @@ void ControlFlowGraph::InitializeControlFlowGraph(const CFTable &cf_table,
157157
FUZZTEST_VLOG(100) << "Added PC: " << curr_pc;
158158

159159
// Iterate over callees.
160-
while (cf_table[j]) {
160+
while (j < cf_table.size() && cf_table[j]) {
161161
++j;
162162
}
163163
++j; // Step over the delimiter.
164-
FUZZTEST_CHECK_LE(j, cf_table.size());
164+
FUZZTEST_CHECK_LE(j, cf_table.size()) << "Malformed CF table";
165165
}
166166
// Calculate cyclomatic complexity for all functions.
167167
for (PCIndex i = 0; i < pc_table.size(); ++i) {

‎centipede/control_flow_test.cc‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ TEST(CFTable, MakeCfgFromCfTable) {
9898
FUZZTEST_CHECK_EQ(cfg.GetCyclomaticComplexity(1), 2);
9999
}
100100

101+
TEST(CFTableDeathTest, MakeCfgFromTruncatedCfTable) {
102+
// The record for PC 1 is missing both of its delimiters, which is what a
103+
// partially written cf-table file looks like.
104+
static const CFTable truncated_cf_table = {1, 2, 3};
105+
ControlFlowGraph cfg;
106+
EXPECT_DEATH(cfg.InitializeControlFlowGraph(truncated_cf_table, g_pc_table),
107+
"Malformed CF table");
108+
}
109+
101110
TEST(CFTable, SerializesAndDeserializesCfTable) {
102111
std::stringstream stream;
103112
WriteCfTable(g_cf_table, stream);

0 commit comments

Comments
 (0)