Skip to content

Robustness: panics on malformed rule YAML and malformed binaries; one bad instruction aborts whole-file analysis #20

Description

@mnaza

capa-rs parses untrusted input (both rule YAML and binaries), but several sites panic or abort the whole analysis on malformed data instead of returning an error or skipping the bad item. Found by code review on master (0.5.2); each has a regression test in the linked PR.

Panics on malformed rule YAML

  1. number/ / offset/ with an empty or missing bitness suffixsrc/rules/mod.rs:478,483: &parts[1].trim()[1..] slices out of bounds when the suffix is empty (number/). The documented form is number/x32 (capa-rules doc/format.md), so stripping the first byte is intended for the x — but nothing validates it, and an over-u32 suffix silently truncates via as u32.
  2. string: / or string: /isrc/rules/features.rs:1318,1329: &value[1..value.len()-1] is [1..0] for a bare / → slice panic. StringFactory accepts it (starts+ends with /), the panic happens in RegexFeature::new.
  3. Negative count wraps to u32::MAXsrc/rules/mod.rs:1056-1063: count(api(x)): -1 in YAML hits *i as u32 → 4294967295. The string forms were hardened in 0.4.2 (parse_count_u32), the integer arm was missed.
  4. Public topologically_order_rules panics on a missing dependencysrc/rules/mod.rs:1841: rules_by_name[&dep] indexes the map directly.

Panics / aborts on malformed binaries

  1. One bad instruction kills the whole filesrc/lib.rs:1041: extractor.extract_insn_features(f, insn)? propagates any per-instruction error up through the rayon loop, aborting analysis of the entire binary. Should be best-effort: log and skip the instruction.
  2. detect_ascii_len errors on a string ending exactly at end of buffersrc/extractor/smda.rs:1678: a printable string at EOF with no trailing NUL is treated as "buffer overflow" and (via ? in read_string) aborts feature extraction for that instruction. read_bytes already clamps; returning the length is enough.
  3. read_bytes underflows when offset < base_addrsrc/extractor/smda.rs:1626 (offset - report.base_addr without checked_sub; sibling detect_ascii_len already does the checked version).
  4. is_security_cookie panics on single-operand formattingsrc/extractor/smda.rs:1727: operands[1] when format_operands produced no comma.
  5. .NET extractor panics on empty method bodies and null tokenssrc/extractor/dnfile.rs:106 (instructions[0] on an empty body) and src/extractor/dnfile.rs:1276 (t.rid() - 1 underflow when rid == 0).

Smaller correctness fixes in the same area

  • count(mnemonic(mov) (missing closing paren) silently mangles the argument to mosrc/rules/mod.rs:1028-1036.
  • Inline descriptions split on every " = " instead of the first, losing the tail — src/rules/mod.rs:543-551splitn(2, …).

PR with fixes + regression tests follows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions