Skip to content

Commit 8dd5ac7

Browse files
author
Alan Jowett
committed
PR feedback
Signed-off-by: Alan Jowett <alan.jowett@microsoft.com>
1 parent 510c0a8 commit 8dd5ac7

File tree

5 files changed

+34
-26
lines changed

5 files changed

+34
-26
lines changed

src/config.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ const ebpf_verifier_options_t ebpf_verifier_default_options = {
1414
.allow_division_by_zero = true,
1515
.setup_constraints = true,
1616
.big_endian = false,
17-
.store_pre_invariants = false,
17+
.store_pre_invariants = false, // Enable this to permit usage of the ebpf_check_constraints_at_label and ebpf_get_invariants_at_label functions.
1818
};

src/crab_verifier.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,13 @@ static checks_db get_analysis_report(std::ostream& s, cfg_t& cfg, const crab::in
162162
return db;
163163
}
164164

165-
static thread_local std::optional<crab::invariant_table_t> save_pre_invariants = std::nullopt;
165+
static thread_local std::optional<crab::invariant_table_t> saved_pre_invariants = std::nullopt;
166+
167+
static void save_invariants_if_needed(const crab::invariant_table_t& pre_invariants) {
168+
if (thread_local_options.store_pre_invariants) {
169+
saved_pre_invariants = pre_invariants;
170+
}
171+
}
166172

167173
static checks_db get_ebpf_report(std::ostream& s, cfg_t& cfg, program_info info, const ebpf_verifier_options_t* options,
168174
const std::optional<InstructionSeq>& prog = std::nullopt) {
@@ -175,9 +181,7 @@ static checks_db get_ebpf_report(std::ostream& s, cfg_t& cfg, program_info info,
175181
// Get dictionaries of pre-invariants and post-invariants for each basic block.
176182
ebpf_domain_t entry_dom = ebpf_domain_t::setup_entry(true);
177183
auto [pre_invariants, post_invariants] = run_forward_analyzer(cfg, std::move(entry_dom));
178-
if (thread_local_options.store_pre_invariants) {
179-
save_pre_invariants = pre_invariants;
180-
}
184+
save_invariants_if_needed(pre_invariants);
181185
return get_analysis_report(s, cfg, pre_invariants, post_invariants, prog);
182186
} catch (std::runtime_error& e) {
183187
// Convert verifier runtime_error exceptions to failure.
@@ -227,9 +231,7 @@ std::tuple<string_invariant, bool> ebpf_analyze_program_for_test(std::ostream& o
227231
try {
228232
cfg_t cfg = prepare_cfg(prog, info, options.simplify, false);
229233
auto [pre_invariants, post_invariants] = run_forward_analyzer(cfg, std::move(entry_inv));
230-
if (thread_local_options.store_pre_invariants) {
231-
save_pre_invariants = pre_invariants;
232-
}
234+
save_invariants_if_needed(pre_invariants);
233235
const checks_db report = get_analysis_report(std::cerr, cfg, pre_invariants, post_invariants);
234236
print_report(os, report, prog, false);
235237

@@ -276,21 +278,21 @@ void ebpf_verifier_clear_thread_local_state() {
276278
global_program_info.clear();
277279
crab::domains::clear_thread_local_state();
278280
crab::domains::SplitDBM::clear_thread_local_state();
279-
save_pre_invariants = std::nullopt;
281+
saved_pre_invariants = std::nullopt;
280282
}
281283

282284
bool ebpf_check_constraints_at_label(std::ostream& os, const std::string& label_string,
283285
const std::set<std::string>& constraints) try {
284286
label_t label = label_t(label_string);
285-
if (!save_pre_invariants.has_value()) {
287+
if (!saved_pre_invariants.has_value()) {
286288
os << "No pre-invariants available\n";
287289
return false;
288290
}
289-
if (save_pre_invariants.value().find(label) == save_pre_invariants.value().end()) {
291+
if (saved_pre_invariants.value().find(label) == saved_pre_invariants.value().end()) {
290292
os << "No pre-invariants available for label " << label << "\n";
291293
return false;
292294
}
293-
ebpf_domain_t from_inv(save_pre_invariants.value().at(label));
295+
ebpf_domain_t from_inv(saved_pre_invariants.value().at(label));
294296
auto concrete_domain = ebpf_domain_t::from_constraints(constraints, false);
295297

296298
if (concrete_domain.is_bottom()) {
@@ -327,12 +329,14 @@ bool ebpf_check_constraints_at_label(std::ostream& os, const std::string& label_
327329

328330
std::set<std::string> ebpf_get_invariants_at_label(const std::string& label)
329331
{
332+
// If the label is malformed, throw an exception so the caller can handle it.
330333
label_t l = label_t(label);
331-
if (!save_pre_invariants.has_value()) {
334+
335+
if (!saved_pre_invariants.has_value()) {
332336
return {};
333337
}
334-
if (save_pre_invariants.value().find(l) == save_pre_invariants.value().end()) {
338+
if (saved_pre_invariants.value().find(l) == saved_pre_invariants.value().end()) {
335339
return {};
336340
}
337-
return save_pre_invariants.value().at(l).to_set().value();
341+
return saved_pre_invariants.value().at(l).to_set().value();
338342
}

src/crab_verifier.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ void ebpf_verifier_clear_thread_local_state();
3232
* verifier constraints at the label. Requires the `store_pre_invariants` option to be set.
3333
*
3434
* Abstract constraints are computed by the verifier and stored if the `store_pre_invariants` option is set.
35+
* These constraints represent the program state at a specific point in the control flow graph,
36+
* as determined by the static analysis performed by the verifier.
3537
*
3638
* @param[in,out] os Print output to this stream.
3739
* @param[in] label The location in the CFG to check against.

src/test/ebpf_yaml.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static std::set<string> as_set_empty_default(const YAML::Node& optional_node) {
128128
}
129129

130130
static std::map<std::string, std::set<std::string>> parse_invariants_to_check(const YAML::Node& case_node) {
131-
if (!case_node["invariants-to-check"].IsDefined()) {
131+
if (!case_node["invariants-to-check"].IsDefined() || case_node["invariants-to-check"].IsNull()) {
132132
return {};
133133
}
134134

@@ -278,12 +278,14 @@ std::optional<Failure> run_yaml_test_case(TestCase test_case, bool debug) {
278278
std::set<string> actual_messages = extract_messages(ss.str());
279279

280280
for (auto& [label, expected_invariant] : test_case.invariants_to_check) {
281+
ss.str("");
282+
ss.clear();
281283
if (!ebpf_check_constraints_at_label(ss, label, expected_invariant)) {
282284
// If debug is enabled, print the output of ebpf_check_constraints_at_label.
283285
if (debug) {
284286
std::cout << ss.str();
285287
}
286-
actual_messages.insert(label + ": Concrete invariants at do not match abstract invariants");
288+
actual_messages.insert(label + ": Concrete invariants do not match abstract invariants");
287289
}
288290
}
289291

test-data/add.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,19 +189,19 @@ code:
189189
r0 = r1
190190
191191
invariants-to-check:
192-
1:
192+
1: # After the first assignment, r1 should be 1.
193193
- r1.type=number
194194
- r1.svalue=1
195195
- r1.uvalue=1
196-
2:
196+
2: # After the second assignment, r2 should be 2.
197197
- r2.type=number
198198
- r2.svalue=2
199199
- r2.uvalue=2
200-
3:
200+
3: # After the addition, r1 should be 3.
201201
- r1.type=number
202202
- r1.svalue=3
203203
- r1.uvalue=3
204-
-2:
204+
-2: # After the last assignment, r0 should be 3.
205205
- r0.type=number
206206
- r0.svalue=3
207207
- r0.uvalue=3
@@ -229,19 +229,19 @@ code:
229229
r0 = r1
230230
231231
invariants-to-check:
232-
1:
232+
1: # After the first assignment, r1 should be 1.
233233
- r1.type=number
234234
- r1.svalue=1
235235
- r1.uvalue=1
236-
2:
236+
2: # After the second assignment, r2 should be 2.
237237
- r2.type=number
238238
- r2.svalue=2
239239
- r2.uvalue=2
240-
3:
240+
3: # After the addition, r1 should be 3. Invalid invariant to test negative case.
241241
- r1.type=number
242242
- r1.svalue=2
243243
- r1.uvalue=2
244-
-2:
244+
-2: # After the last assignment, r0 should be 3.
245245
- r0.type=number
246246
- r0.svalue=3
247247
- r0.uvalue=3
@@ -258,4 +258,4 @@ post:
258258
- r2.uvalue=2
259259

260260
messages:
261-
- "3: Concrete invariants at do not match abstract invariants"
261+
- "3: Concrete invariants do not match abstract invariants"

0 commit comments

Comments
 (0)