JsonEventSink

1. Overview

The JsonEventSink.cpp implementation persists RootGuard events as newline-delimited JSON with UTC receipt time, stable textual event/verdict names, complete identity and metadata fields, and JSON-safe escaping.

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

  • JsonEventSink.hpp
  • rootguard_shared.h
  • std::ofstream
  • std::mutex

2. Event, Verdict, and Path Names

Internal switch functions convert kernel constants to lowercase JSON strings. Unknown values are preserved as unknown; unknown path provenance falls back to basename-only.


3. Receipt Timestamp

receivedAtUtc() records userspace receipt time in UTC using the ISO-like format YYYY-MM-DDTHH:MM:SSZ. Kernel monotonic nanoseconds are written separately.


4. JSON Escaping

escape() handles quotation marks, backslashes, common control characters, and emits remaining control bytes below 0x20 as \uXXXX.


5. Serialized Schema

Each record includes receipt/kernel time, event/verdict, process IDs/EUIDs, rule and reason values, LSM/auxiliary fields, path resolution, target/actor/parent device+inode, actor start time, old/new mode and ownership, comm/parent comm, actor and parent executable, filename, and xattr name.


6. Write Behavior

The constructor opens the target path in append mode and fails if it cannot be opened. onEvent() locks the stream, writes exactly one JSON object plus newline, and flushes immediately. Any exception during logging is swallowed so the engine continues.


7. Runtime and Security Considerations

  • Thread-safe records: the mutex prevents interleaved JSON output.
  • Crash isolation: logging cannot bring down RootGuard.
  • Immediate durability preference: every event is flushed after writing.