-
Notifications
You must be signed in to change notification settings - Fork 400
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests(inst): add writable data source test
- Loading branch information
1 parent
3168f18
commit 17ffd77
Showing
10 changed files
with
712 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package datasourcetest | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
lru "github.com/hashicorp/golang-lru/v2" | ||
|
||
"github.com/aquasecurity/tracee/types/detect" | ||
) | ||
|
||
type e2eWritable struct { | ||
cache *lru.Cache[string, string] | ||
} | ||
|
||
func New() detect.DataSource { | ||
cache, _ := lru.New[string, string](1024) | ||
return &e2eWritable{ | ||
cache, | ||
} | ||
} | ||
|
||
func (ctx *e2eWritable) Get(key interface{}) (map[string]interface{}, error) { | ||
val, ok := key.(string) | ||
if !ok { | ||
return nil, detect.ErrKeyNotSupported | ||
} | ||
|
||
res, ok := ctx.cache.Get(val) | ||
if !ok { | ||
return nil, detect.ErrDataNotFound | ||
} | ||
|
||
return map[string]interface{}{ | ||
"value": res, | ||
}, nil | ||
} | ||
|
||
func (ctx *e2eWritable) Version() uint { | ||
return 1 | ||
} | ||
|
||
func (ctx *e2eWritable) Keys() []string { | ||
return []string{"string"} | ||
} | ||
|
||
func (ctx *e2eWritable) Schema() string { | ||
schema := map[string]interface{}{ | ||
"value": "string", | ||
} | ||
|
||
s, _ := json.Marshal(schema) | ||
return string(s) | ||
} | ||
|
||
func (ctx *e2eWritable) Namespace() string { | ||
return "e2e_inst" | ||
} | ||
|
||
func (ctx *e2eWritable) ID() string { | ||
return "demo" | ||
} | ||
|
||
func (ctx *e2eWritable) Write(data map[interface{}]interface{}) error { | ||
for key, val := range data { | ||
err := ctx.writeDataEntry(key, val) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (ctx *e2eWritable) writeDataEntry(key, value any) error { | ||
keyStr, ok := key.(string) | ||
if !ok { | ||
return detect.ErrFailedToUnmarshal | ||
} | ||
|
||
valueStr, ok := value.(string) | ||
if !ok { | ||
return detect.ErrFailedToUnmarshal | ||
} | ||
|
||
ctx.cache.Add(keyStr, valueStr) | ||
return nil | ||
} | ||
|
||
func (ctx *e2eWritable) Values() []string { | ||
return []string{"string"} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/aquasecurity/tracee/types/detect" | ||
"github.com/aquasecurity/tracee/types/protocol" | ||
"github.com/aquasecurity/tracee/types/trace" | ||
) | ||
|
||
type e2eWritableDatasourceSig struct { | ||
cb detect.SignatureHandler | ||
writable detect.DataSource | ||
} | ||
|
||
func (sig *e2eWritableDatasourceSig) Init(ctx detect.SignatureContext) error { | ||
sig.cb = ctx.Callback | ||
writable, ok := ctx.GetDataSource("e2e_inst", "demo") | ||
if !ok { | ||
return fmt.Errorf("containers data source not registered") | ||
} | ||
if writable.Version() > 1 { | ||
return fmt.Errorf("containers data source version not supported, please update this signature") | ||
} | ||
sig.writable = writable | ||
return nil | ||
} | ||
|
||
func (sig *e2eWritableDatasourceSig) GetMetadata() (detect.SignatureMetadata, error) { | ||
return detect.SignatureMetadata{ | ||
ID: "WRITABLE_DATA_SOURCE", | ||
EventName: "WRITABLE_DATA_SOURCE", | ||
Version: "0.1.0", | ||
Name: "Writable Data Source Test", | ||
Description: "Instrumentation events E2E Tests: Writable Data Source Test", | ||
Tags: []string{"e2e", "instrumentation"}, | ||
}, nil | ||
} | ||
|
||
func (sig *e2eWritableDatasourceSig) GetSelectedEvents() ([]detect.SignatureEventSelector, error) { | ||
return []detect.SignatureEventSelector{ | ||
{Source: "tracee", Name: "sched_process_exit"}, | ||
}, nil | ||
} | ||
|
||
func (sig *e2eWritableDatasourceSig) OnEvent(event protocol.Event) error { | ||
eventObj, ok := event.Payload.(trace.Event) | ||
if !ok { | ||
return fmt.Errorf("failed to cast event's payload") | ||
} | ||
|
||
switch eventObj.EventName { | ||
case "sched_process_exit": | ||
if eventObj.ProcessName != "ds_writer" { | ||
return nil | ||
} | ||
|
||
container, err := sig.writable.Get("bruh") | ||
if err != nil { | ||
return fmt.Errorf("failed to query key \"bruh\" in data source: %v", err) | ||
} | ||
|
||
data, ok := container["value"].(string) | ||
if !ok { | ||
return fmt.Errorf("failed to unwrap value from writable data") | ||
} | ||
|
||
if data != "moment" { | ||
return fmt.Errorf("value written in data source not expected (%s)", data) | ||
} | ||
|
||
m, _ := sig.GetMetadata() | ||
|
||
sig.cb(detect.Finding{ | ||
SigMetadata: m, | ||
Event: event, | ||
Data: map[string]interface{}{}, | ||
}) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (sig *e2eWritableDatasourceSig) OnSignal(s detect.Signal) error { | ||
return nil | ||
} | ||
|
||
func (sig *e2eWritableDatasourceSig) Close() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
proctreetester | ||
ds_writer/ds_writer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
"fmt" | ||
"math/rand" | ||
"os" | ||
|
||
"google.golang.org/grpc" | ||
"google.golang.org/grpc/credentials/insecure" | ||
"google.golang.org/protobuf/types/known/structpb" | ||
|
||
"github.com/aquasecurity/tracee/api/v1beta1" | ||
) | ||
|
||
func printAndExit(msg string, args ...any) { | ||
fmt.Printf(msg, args...) | ||
os.Exit(1) | ||
} | ||
|
||
func chooseWord(list []string) string { | ||
return list[rand.Intn(len(list))] | ||
} | ||
|
||
func contaminate(client v1beta1.DataSourceServiceClient) error { | ||
stream, err := client.WriteStream(context.Background()) | ||
if err != nil { | ||
return fmt.Errorf("error establishing stream: %v", err) | ||
} | ||
for i := 0; i < 1000; i++ { | ||
randomKey := chooseWord(wordList) | ||
randomValue := chooseWord(wordList) | ||
err := stream.Send(&v1beta1.WriteDataSourceRequest{ | ||
Id: "demo", | ||
Namespace: "e2e_inst", | ||
Key: structpb.NewStringValue(randomKey), | ||
Value: structpb.NewStringValue(randomValue), | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
_, err = stream.CloseAndRecv() | ||
if err != nil { | ||
return fmt.Errorf("error closing stream: %v", err) | ||
} | ||
return nil | ||
} | ||
|
||
func main() { | ||
keyPtr := flag.String("key", "", "key to set in the data source") | ||
valuePtr := flag.String("value", "", "key to set in the data source") | ||
flag.Parse() | ||
|
||
key := *keyPtr | ||
value := *valuePtr | ||
|
||
if key == "" { | ||
printAndExit("empty key given\n") | ||
} | ||
if value == "" { | ||
printAndExit("empty value given\n") | ||
} | ||
|
||
conn, err := grpc.Dial( | ||
"unix:///tmp/tracee.sock", | ||
grpc.WithTransportCredentials(insecure.NewCredentials()), | ||
) | ||
if err != nil { | ||
printAndExit("failed to dial tracee grpc server: %v\n", err) | ||
} | ||
client := v1beta1.NewDataSourceServiceClient(conn) | ||
err = contaminate(client) | ||
if err != nil { | ||
printAndExit("error contaminating data source: %v\n", err) | ||
} | ||
_, err = client.Write(context.Background(), &v1beta1.WriteDataSourceRequest{ | ||
Id: "demo", | ||
Namespace: "e2e_inst", | ||
Key: structpb.NewStringValue("bruh"), | ||
Value: structpb.NewStringValue("moment"), | ||
}) | ||
|
||
if err != nil { | ||
printAndExit("failed to write to data source: %v\n", err) | ||
} | ||
} |
Oops, something went wrong.