RootGuardEvent

1. Overview

The RootGuardEvent.cpp implementation provides a lightweight parser for RootGuard’s line-oriented JSON output, formats detailed event summaries, classifies metadata activity by severity, and identifies paths belonging to supported system service definitions.

The file integrates the following components, APIs, or runtime concepts:

  • RootGuardEvent.hpp – public event model
  • rootguard_shared.h – global metadata and burst reason flags
  • std::hash – raw-record fingerprint generation

2. Lightweight JSON Field Extraction

The parser uses dedicated string, unsigned-integer, and signed-integer field extractors tailored to the stable JSONL schema emitted by RootGuard. String extraction handles common JSON escapes such as newline, carriage return, tab, backslash, and quotation mark.

Missing numeric fields default to zero; out-of-range values are rejected by conversion helpers. The event and verdict string fields are mandatory—records missing either are rejected.


3. Parsed Event Fields

parse_event_json() imports process IDs, EUIDs, rule/reason metadata, LSM flags, auxiliary counters, target/actor/parent device+inode identities, actor boot-time identity, modes, ownership, comm values, executable paths, affected filename, and path-resolution provenance.

The complete source line is copied into raw_json before validation so successful events retain their original serialized representation.


4. Human-Readable Formatting

format_event() emits a compact chronological line with verdict, event type, process identity, EUID transition, octal mode transition, ownership transition, rule number, parent and actor information, path-resolution method, filesystem identity, and hexadecimal reason flags when available.

Mode values are masked to permission bits and rendered in octal, matching administrator expectations for Unix metadata.


5. Event Fingerprints

event_fingerprint() hashes raw_json and returns the hash in hexadecimal. The GTK page uses this to suppress duplicate/dismissed notifications without altering the persisted event record.


6. Severity Classification

Records without an actionable filename or without blocked, alert, or audit verdicts remain telemetry. service-blocked records are incidents.

For permission/owner/xattr/ACL metadata events, an explicit nonzero rule_id is an incident. Unprotected global metadata is an observation, except metadata bursts which are elevated to incidents. Historical broad-surveillance records lacking the newer global-metadata semantics remain telemetry.

Protected unlink, rename, hard-link, and integrity-drift records become incidents only when tied to a protected rule.


7. System Service Path Detection

is_system_service_path() accepts service definitions under:

/etc/systemd/system
/usr/lib/systemd/system
/lib/systemd/system
/etc/init.d
/etc/conf.d
/etc/dinit.d
/usr/lib/dinit.d

Prefix matching is component-aware, so a textual prefix that is not a directory boundary does not count as the target tree.


8. Runtime and Security Considerations

  • Conservative parsing: malformed or incomplete mandatory fields return std::nullopt instead of producing a partially trusted event.
  • UI-noise control: global metadata is separated into telemetry, observation, and burst incident classes.
  • Protected identity priority: a nonzero policy rule keeps protected-object events at incident severity.