Add event-driven memory syscall telemetry

This commit is contained in:
Luna 2026-06-13 05:45:30 -07:00
parent 893409b549
commit a51478fa22
18 changed files with 589 additions and 32 deletions

View file

@ -0,0 +1,71 @@
# SPDX-License-Identifier: GPL-3.0-or-later
"""Tests for event-driven syscall rules; pure, no BPF needed."""
import unittest
from enodia_sentinel.alert import Severity
from enodia_sentinel.events.syscall_event import SyscallEvent
from enodia_sentinel.events.syscall_rules import SyscallRuleEngine
def ev(syscall, arg0=0, arg1=0, arg2=0, arg3=0, text="", pid=10):
return SyscallEvent(
pid=pid, ppid=1, uid=1000, comm="hoxha", syscall=syscall,
arg0=arg0, arg1=arg1, arg2=arg2, arg3=arg3, text=text,
)
class TestSyscallEvent(unittest.TestCase):
def test_json_shape(self):
d = ev("memfd_create", arg0=1, text="stage").to_dict()
self.assertEqual(d["syscall"], "memfd_create")
self.assertEqual(d["args"][0], 1)
self.assertEqual(d["text"], "stage")
class TestDefaultSyscallRules(unittest.TestCase):
def setUp(self):
self.engine = SyscallRuleEngine()
def sids(self, event):
return {a.sid for a in self.engine.match(event)}
def alert(self, event):
return next(iter(self.engine.match(event)))
def test_mprotect_rwx_alerts(self):
self.assertIn(100060, self.sids(ev("mprotect", arg2=0x6)))
def test_mprotect_read_exec_ignored(self):
self.assertNotIn(100060, self.sids(ev("mprotect", arg2=0x5)))
def test_mmap_rwx_alerts(self):
self.assertIn(100061, self.sids(ev("mmap", arg2=0x7)))
def test_memfd_create_alerts(self):
alert = self.alert(ev("memfd_create", text="payload"))
self.assertEqual(alert.sid, 100062)
self.assertEqual(alert.severity, Severity.MEDIUM)
self.assertIn("payload", alert.detail)
def test_ptrace_sensitive_requests_alert(self):
self.assertIn(100063, self.sids(ev("ptrace", arg0=16)))
self.assertIn(100063, self.sids(ev("ptrace", arg0=0x4206)))
def test_ptrace_other_request_ignored(self):
self.assertNotIn(100063, self.sids(ev("ptrace", arg0=3)))
def test_seccomp_alerts_from_prctl_or_syscall(self):
self.assertIn(100064, self.sids(ev("prctl", arg0=22)))
self.assertIn(100064, self.sids(ev("seccomp")))
def test_process_vm_alerts(self):
self.assertIn(100065, self.sids(ev("process_vm_readv", arg0=4242)))
self.assertIn(100065, self.sids(ev("process_vm_writev", arg0=4242)))
def test_mlock_alerts(self):
self.assertIn(100066, self.sids(ev("mlock")))
self.assertIn(100066, self.sids(ev("mlockall")))
if __name__ == "__main__":
unittest.main()