Skip to content

Commit fa86257

Browse files
committed
feat(datastores): add SyscallStore for syscall ID/name mapping
Implement a new SyscallStore datastore that provides: - GetSyscallName(id int32): lookup syscall name by ID - GetSyscallID(name string): lookup syscall ID by name The store wraps events.Core and provides architecture-specific syscall information (x86 vs ARM). Uses int32 for syscall IDs to match kernel ABI and protobuf definitions. This enables detectors to resolve syscall names without direct access to internal pkg/events structures. Includes comprehensive unit tests
1 parent e889c44 commit fa86257

File tree

6 files changed

+422
-0
lines changed

6 files changed

+422
-0
lines changed

api/v1beta1/datastores/interfaces.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,18 @@ type SystemStore interface {
101101
// This data is immutable and never changes during the Tracee process lifetime
102102
GetSystemInfo() *SystemInfo
103103
}
104+
105+
// SyscallStore provides access to syscall metadata for the current architecture
106+
type SyscallStore interface {
107+
DataStore
108+
109+
// GetSyscallName returns the syscall name for a given ID
110+
// Returns empty string and false if the syscall ID is not found
111+
// Note: Syscall IDs are architecture-specific (x86 vs ARM)
112+
GetSyscallName(id int32) (string, bool)
113+
114+
// GetSyscallID returns the syscall ID for a given name
115+
// Returns 0 and false if the syscall name is not found
116+
// Note: Syscall IDs are architecture-specific (x86 vs ARM)
117+
GetSyscallID(name string) (int32, bool)
118+
}

api/v1beta1/datastores/registry.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ type Registry interface {
1717
// System returns the system information datastore
1818
System() SystemStore
1919

20+
// Syscalls returns the syscall information datastore
21+
Syscalls() SyscallStore
22+
2023
// GetCustom retrieves a custom datastore by name
2124
// Returns ErrNotFound if the datastore is not registered
2225
GetCustom(name string) (DataStore, error)

pkg/datastores/registry.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type Registry struct {
2020
kernelSymbolStore datastores.KernelSymbolStore
2121
dnsStore datastores.DNSStore
2222
systemStore datastores.SystemStore
23+
syscallStore datastores.SyscallStore
2324
}
2425

2526
// NewRegistry creates a new datastore registry
@@ -84,6 +85,10 @@ func (r *Registry) RegisterStore(name string, store datastores.DataStore, requir
8485
if ss, ok := store.(datastores.SystemStore); ok {
8586
r.systemStore = ss
8687
}
88+
case "syscall":
89+
if sc, ok := store.(datastores.SyscallStore); ok {
90+
r.syscallStore = sc
91+
}
8792
}
8893

8994
r.stores[name] = store
@@ -116,6 +121,11 @@ func (r *Registry) System() datastores.SystemStore {
116121
return r.systemStore
117122
}
118123

124+
// Syscalls returns the syscall information datastore
125+
func (r *Registry) Syscalls() datastores.SyscallStore {
126+
return r.syscallStore
127+
}
128+
119129
// GetCustom returns a custom datastore by name with type safety
120130
func (r *Registry) GetCustom(name string) (datastores.DataStore, error) {
121131
r.mu.RLock()

pkg/datastores/syscall/store.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package syscall
2+
3+
import (
4+
"time"
5+
6+
"github.com/aquasecurity/tracee/api/v1beta1/datastores"
7+
"github.com/aquasecurity/tracee/pkg/events"
8+
)
9+
10+
// Store implements the SyscallStore interface by wrapping events.DefinitionGroup
11+
// It provides access to syscall metadata for the current architecture
12+
type Store struct {
13+
eventCore *events.DefinitionGroup
14+
}
15+
16+
// New creates a new SyscallStore with the provided event definitions
17+
func New(eventCore *events.DefinitionGroup) datastores.SyscallStore {
18+
return &Store{
19+
eventCore: eventCore,
20+
}
21+
}
22+
23+
// Name returns the datastore name
24+
func (s *Store) Name() string {
25+
return "syscall"
26+
}
27+
28+
// GetHealth returns the health status of the datastore
29+
// SyscallStore is always healthy since it wraps immutable event definitions
30+
func (s *Store) GetHealth() *datastores.HealthInfo {
31+
return &datastores.HealthInfo{
32+
Status: datastores.HealthHealthy,
33+
Message: "syscall store operational",
34+
LastCheck: time.Now(),
35+
}
36+
}
37+
38+
// GetMetrics returns operational metrics for the datastore
39+
func (s *Store) GetMetrics() *datastores.DataStoreMetrics {
40+
return &datastores.DataStoreMetrics{
41+
ItemCount: 0, // Not tracked for syscall store
42+
SuccessCount: 0,
43+
ErrorCount: 0,
44+
CacheHits: 0,
45+
CacheMisses: 0,
46+
LastAccess: time.Now(),
47+
}
48+
}
49+
50+
// GetSyscallName returns the syscall name for a given ID
51+
// Returns empty string and false if the syscall ID is not found or is not a syscall
52+
func (s *Store) GetSyscallName(id int32) (string, bool) {
53+
def := s.eventCore.GetDefinitionByID(events.ID(id))
54+
55+
// Check if definition was found (Undefined means not found)
56+
if def.GetID() == events.Undefined {
57+
return "", false
58+
}
59+
60+
// Only return name if this is actually a syscall
61+
if !def.IsSyscall() {
62+
return "", false
63+
}
64+
65+
return def.GetName(), true
66+
}
67+
68+
// GetSyscallID returns the syscall ID for a given name
69+
// Returns 0 and false if the syscall name is not found or is not a syscall
70+
func (s *Store) GetSyscallID(name string) (int32, bool) {
71+
id, found := s.eventCore.GetDefinitionIDByName(name)
72+
if !found {
73+
return 0, false
74+
}
75+
76+
// Verify this is actually a syscall
77+
def := s.eventCore.GetDefinitionByID(id)
78+
if def.GetID() == events.Undefined || !def.IsSyscall() {
79+
return 0, false
80+
}
81+
82+
return int32(id), true
83+
}

0 commit comments

Comments
 (0)