Skip to content

Commit

Permalink
pkg/selectors: deduplicate generic type arguments
Browse files Browse the repository at this point in the history
There are two versions of the same generic type arguments currently in use.

This patch unifies them by bringing all arguments into the pkg/generictypes/generictypes.go class.

Fixes: #530

Signed-off-by: Luigi De Matteis <[email protected]>
  • Loading branch information
h3x-eilidh committed Feb 2, 2024
1 parent 92dbc44 commit b0d041c
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 124 deletions.
3 changes: 3 additions & 0 deletions pkg/generictypes/generictypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ const (
GenericS8Type = 31
GenericU8Type = 32

GenericUrlType = 33
GenericFqdnType = 34

GenericNopType = -1
GenericInvalidType = -2
)
Expand Down
136 changes: 56 additions & 80 deletions pkg/selectors/kernel.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/cilium/tetragon/api/v1/tetragon"
"github.com/cilium/tetragon/pkg/api/processapi"
gt "github.com/cilium/tetragon/pkg/generictypes"
"github.com/cilium/tetragon/pkg/idtable"
"github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1"
"github.com/cilium/tetragon/pkg/kernels"
Expand Down Expand Up @@ -153,69 +154,44 @@ var capabilitiesTypeTable = map[string]uint32{
"permitted": capsPermitted,
}

const (
argTypeInt = 1
argTypeCharBuf = 2
argTypeCharIovec = 3
argTypeSizet = 4
argTypeSkb = 5
argTypeString = 6
argTypeSock = 7

argTypeS64 = 10
argTypeU64 = 11
argTypeS32 = 12
argTypeU32 = 13

argTypePath = 15
argTypeFile = 16
argTypeFd = 17

argTypeUrl = 18
argTypeFqdn = 19

// mirrors gt.GenericSyscall64
argTypeSyscall64 = 28
)

var argTypeTable = map[string]uint32{
"int": argTypeInt,
"uint32": argTypeU32,
"int32": argTypeS32,
"uint64": argTypeU64,
"int64": argTypeS64,
"char_buf": argTypeCharBuf,
"char_iovec": argTypeCharIovec,
"sizet": argTypeSizet,
"skb": argTypeSkb,
"string": argTypeString,
"fd": argTypeFd,
"path": argTypePath,
"file": argTypeFile,
"sock": argTypeSock,
"url": argTypeUrl,
"fqdn": argTypeFqdn,
"syscall64": argTypeSyscall64,
"int": gt.GenericIntType,
"uint32": gt.GenericU32Type,
"int32": gt.GenericS32Type,
"uint64": gt.GenericU64Type,
"int64": gt.GenericS64Type,
"char_buf": gt.GenericCharBuffer,
"char_iovec": gt.GenericCharIovec,
"sizet": gt.GenericSizeType,
"skb": gt.GenericSkbType,
"string": gt.GenericStringType,
"fd": gt.GenericFdType,
"path": gt.GenericPathType,
"file": gt.GenericFileType,
"sock": gt.GenericSockType,
"url": gt.GenericUrlType,
"fqdn": gt.GenericFqdnType,
"syscall64": gt.GenericSyscall64,
}

var argTypeStringTable = map[uint32]string{
argTypeInt: "int",
argTypeU32: "uint32",
argTypeS32: "int32",
argTypeU64: "uint64",
argTypeS64: "int64",
argTypeCharBuf: "char_buf",
argTypeCharIovec: "char_iovec",
argTypeSizet: "sizet",
argTypeSkb: "skb",
argTypeString: "string",
argTypeFd: "fd",
argTypeFile: "file",
argTypePath: "path",
argTypeSock: "sock",
argTypeUrl: "url",
argTypeFqdn: "fqdn",
argTypeSyscall64: "syscall64",
gt.GenericIntType: "int",
gt.GenericU32Type: "uint32",
gt.GenericS32Type: "int32",
gt.GenericU64Type: "uint64",
gt.GenericS64Type: "int64",
gt.GenericCharBuffer: "char_buf",
gt.GenericCharIovec: "char_iovec",
gt.GenericSizeType: "sizet",
gt.GenericSkbType: "skb",
gt.GenericStringType: "string",
gt.GenericFdType: "fd",
gt.GenericFileType: "file",
gt.GenericPathType: "path",
gt.GenericSockType: "sock",
gt.GenericUrlType: "url",
gt.GenericFqdnType: "fqdn",
gt.GenericSyscall64: "syscall64",
}

const (
Expand Down Expand Up @@ -474,14 +450,14 @@ func writeRangeInMap(v string, ty uint32, op uint32, m *ValueMap) error {
}
for idx := 0; idx < 2; idx++ {
switch ty {
case argTypeS64, argTypeInt:
case gt.GenericS64Type, gt.GenericIntType:
i, err := strconv.ParseInt(rangeStr[idx], 10, 64)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
}
sRangeVal[idx] = i

case argTypeU64:
case gt.GenericU64Type:
i, err := strconv.ParseUint(rangeStr[idx], 10, 64)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
Expand All @@ -492,7 +468,7 @@ func writeRangeInMap(v string, ty uint32, op uint32, m *ValueMap) error {
}
}
switch ty {
case argTypeS64, argTypeInt:
case gt.GenericS64Type, gt.GenericIntType:
if sRangeVal[0] > sRangeVal[1] {
sRangeVal[0], sRangeVal[1] = sRangeVal[1], sRangeVal[0]
}
Expand All @@ -502,7 +478,7 @@ func writeRangeInMap(v string, ty uint32, op uint32, m *ValueMap) error {
m.Data[valByte] = struct{}{}
}

case argTypeU64:
case gt.GenericU64Type:
if uRangeVal[0] > uRangeVal[1] {
uRangeVal[0], uRangeVal[1] = uRangeVal[1], uRangeVal[0]
}
Expand Down Expand Up @@ -540,9 +516,9 @@ func writeListValuesInMap(k *KernelSelectorState, v string, ty uint32, m *ValueM
var val [8]byte

switch ty {
case argTypeS64, argTypeInt, argTypeSyscall64:
case gt.GenericS64Type, gt.GenericIntType, gt.GenericSyscall64:
binary.LittleEndian.PutUint64(val[:], uint64(values[idx]))
case argTypeU64:
case gt.GenericU64Type:
binary.LittleEndian.PutUint64(val[:], uint64(values[idx]))
default:
return fmt.Errorf("Unknown type: %d", ty)
Expand Down Expand Up @@ -573,13 +549,13 @@ func writeMatchValuesInMap(k *KernelSelectorState, values []string, ty uint32, o
continue
}
switch ty {
case argTypeS64, argTypeInt, argTypeSyscall64:
case gt.GenericS64Type, gt.GenericIntType, gt.GenericSyscall64:
i, err := strconv.ParseInt(v, 10, 64)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
}
binary.LittleEndian.PutUint64(val[:], uint64(i))
case argTypeU64:
case gt.GenericU64Type:
i, err := strconv.ParseUint(v, 10, 64)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
Expand Down Expand Up @@ -686,33 +662,33 @@ func writeMatchValues(k *KernelSelectorState, values []string, ty, op uint32) er
for _, v := range values {
base := getBase(v)
switch ty {
case argTypeS32, argTypeInt, argTypeSizet:
case gt.GenericS32Type, gt.GenericIntType, gt.GenericSizeType:
i, err := strconv.ParseInt(v, base, 32)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
}
WriteSelectorInt32(&k.data, int32(i))
case argTypeU32:
case gt.GenericU32Type:
i, err := strconv.ParseUint(v, base, 32)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
}
WriteSelectorUint32(&k.data, uint32(i))
case argTypeS64:
case gt.GenericS64Type:
i, err := strconv.ParseInt(v, base, 64)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
}
WriteSelectorInt64(&k.data, int64(i))
case argTypeU64:
case gt.GenericU64Type:
i, err := strconv.ParseUint(v, base, 64)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
}
WriteSelectorUint64(&k.data, uint64(i))
case argTypeSock, argTypeSkb:
case gt.GenericSockType, gt.GenericSkbType:
return fmt.Errorf("MatchArgs type sock and skb do not support operator %s", selectorOpStringTable[op])
case argTypeCharIovec:
case gt.GenericCharIovec:
return fmt.Errorf("MatchArgs values %s unsupported", v)
}
}
Expand All @@ -723,7 +699,7 @@ func writeMatchStrings(k *KernelSelectorState, values []string, ty uint32) error
maps := k.createStringMaps()

for _, v := range values {
trimNulSuffix := ty == argTypeString
trimNulSuffix := ty == gt.GenericStringType
value, size, err := ArgStringSelectorValue(v, trimNulSuffix)
if err != nil {
return fmt.Errorf("MatchArgs value %s invalid: %w", v, err)
Expand Down Expand Up @@ -777,7 +753,7 @@ func writePostfixStrings(k *KernelSelectorState, values []string, ty uint32) err
for _, v := range values {
var value []byte
var size uint32
if ty == argTypeCharBuf {
if ty == gt.GenericCharBuffer {
value, size = ArgPostfixSelectorValue(v, false)
} else {
value, size = ArgPostfixSelectorValue(v, true)
Expand Down Expand Up @@ -835,7 +811,7 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al
}
case SelectorOpEQ, SelectorOpNEQ:
switch ty {
case argTypeFd, argTypeFile, argTypePath, argTypeString, argTypeCharBuf:
case gt.GenericFdType, gt.GenericFileType, gt.GenericPathType, gt.GenericStringType, gt.GenericCharBuffer:
err := writeMatchStrings(k, arg.Values, ty)
if err != nil {
return fmt.Errorf("writeMatchStrings error: %w", err)
Expand All @@ -857,15 +833,15 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al
return fmt.Errorf("writePostfixStrings error: %w", err)
}
case SelectorOpSport, SelectorOpDport, SelectorOpNotSport, SelectorOpNotDport, SelectorOpProtocol, SelectorOpFamily, SelectorOpState:
if ty != argTypeSock && ty != argTypeSkb {
if ty != gt.GenericSockType && ty != gt.GenericSkbType {
return fmt.Errorf("sock/skb operators specified for non-sock/skb type")
}
err := writeMatchRangesInMap(k, arg.Values, argTypeU64, op) // force type for ports and protocols as ty is sock/skb
err := writeMatchRangesInMap(k, arg.Values, gt.GenericU64Type, op) // force type for ports and protocols as ty is sock/skb
if err != nil {
return fmt.Errorf("writeMatchRangesInMap error: %w", err)
}
case SelectorOpSaddr, SelectorOpDaddr, SelectorOpNotSaddr, SelectorOpNotDaddr:
if ty != argTypeSock && ty != argTypeSkb {
if ty != gt.GenericSockType && ty != gt.GenericSkbType {
return fmt.Errorf("sock/skb operators specified for non-sock/skb type")
}
err := writeMatchAddrsInMap(k, arg.Values)
Expand All @@ -874,7 +850,7 @@ func ParseMatchArg(k *KernelSelectorState, arg *v1alpha1.ArgSelector, sig []v1al
}
case SelectorOpSportPriv, SelectorOpDportPriv, SelectorOpNotSportPriv, SelectorOpNotDportPriv:
// These selectors do not take any values, but we do check that they are only used for sock/skb.
if ty != argTypeSock && ty != argTypeSkb {
if ty != gt.GenericSockType && ty != gt.GenericSkbType {
return fmt.Errorf("sock/skb operators specified for non-sock/skb type")
}
default:
Expand Down
89 changes: 45 additions & 44 deletions pkg/selectors/kernel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strings"
"testing"

gt "github.com/cilium/tetragon/pkg/generictypes"
"github.com/cilium/tetragon/pkg/idtable"
"github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1"
"github.com/cilium/tetragon/pkg/kernels"
Expand Down Expand Up @@ -551,34 +552,34 @@ func TestMultipleSelectorsExample(t *testing.T) {
}

// value absolute offset explanation
expU32Push(2) // off: 0 number of selectors
expU32Push(8) // off: 4 relative ofset of 1st selector (4 + 8 = 12)
expU32Push(100) // off: 8 relative ofset of 2nd selector (8 + 124 = 132)
expU32Push(96) // off: 12 selector1: length (76 + 12 = 96)
expU32Push(24) // off: 16 selector1: MatchPIDs: len
expU32Push(SelectorOpNotIn) // off: 20 selector1: MatchPIDs[0]: op
expU32Push(0) // off: 24 selector1: MatchPIDs[0]: flags
expU32Push(2) // off: 28 selector1: MatchPIDs[0]: number of values
expU32Push(33) // off: 32 selector1: MatchPIDs[0]: val1
expU32Push(44) // off: 36 selector1: MatchPIDs[0]: val2
expU32Push(4) // off: 40 selector1: MatchNamespaces: len
expU32Push(4) // off: 44 selector1: MatchCapabilities: len
expU32Push(4) // off: 48 selector1: MatchNamespaceChanges: len
expU32Push(4) // off: 52 selector1: MatchCapabilityChanges: len
expU32Push(48) // off: 80 selector1: matchArgs: len
expU32Push(24) // off: 84 selector1: matchArgs[0]: offset
expU32Push(0) // off: 88 selector1: matchArgs[1]: offset
expU32Push(0) // off: 92 selector1: matchArgs[2]: offset
expU32Push(0) // off: 96 selector1: matchArgs[3]: offset
expU32Push(0) // off: 100 selector1: matchArgs[4]: offset
expU32Push(1) // off: 104 selector1: matchArgs: arg0: index
expU32Push(SelectorOpEQ) // off: 108 selector1: matchArgs: arg0: operator
expU32Push(16) // off: 112 selector1: matchArgs: arg0: len of vals
expU32Push(argTypeInt) // off: 116 selector1: matchArgs: arg0: type
expU32Push(10) // off: 120 selector1: matchArgs: arg0: val0: 10
expU32Push(20) // off: 124 selector1: matchArgs: arg0: val1: 20
expU32Push(4) // off: 128 selector1: matchActions: length
expU32Push(96) // off: 132 selector2: length
expU32Push(2) // off: 0 number of selectors
expU32Push(8) // off: 4 relative ofset of 1st selector (4 + 8 = 12)
expU32Push(100) // off: 8 relative ofset of 2nd selector (8 + 124 = 132)
expU32Push(96) // off: 12 selector1: length (76 + 12 = 96)
expU32Push(24) // off: 16 selector1: MatchPIDs: len
expU32Push(SelectorOpNotIn) // off: 20 selector1: MatchPIDs[0]: op
expU32Push(0) // off: 24 selector1: MatchPIDs[0]: flags
expU32Push(2) // off: 28 selector1: MatchPIDs[0]: number of values
expU32Push(33) // off: 32 selector1: MatchPIDs[0]: val1
expU32Push(44) // off: 36 selector1: MatchPIDs[0]: val2
expU32Push(4) // off: 40 selector1: MatchNamespaces: len
expU32Push(4) // off: 44 selector1: MatchCapabilities: len
expU32Push(4) // off: 48 selector1: MatchNamespaceChanges: len
expU32Push(4) // off: 52 selector1: MatchCapabilityChanges: len
expU32Push(48) // off: 80 selector1: matchArgs: len
expU32Push(24) // off: 84 selector1: matchArgs[0]: offset
expU32Push(0) // off: 88 selector1: matchArgs[1]: offset
expU32Push(0) // off: 92 selector1: matchArgs[2]: offset
expU32Push(0) // off: 96 selector1: matchArgs[3]: offset
expU32Push(0) // off: 100 selector1: matchArgs[4]: offset
expU32Push(1) // off: 104 selector1: matchArgs: arg0: index
expU32Push(SelectorOpEQ) // off: 108 selector1: matchArgs: arg0: operator
expU32Push(16) // off: 112 selector1: matchArgs: arg0: len of vals
expU32Push(gt.GenericIntType) // off: 116 selector1: matchArgs: arg0: type
expU32Push(10) // off: 120 selector1: matchArgs: arg0: val0: 10
expU32Push(20) // off: 124 selector1: matchArgs: arg0: val1: 20
expU32Push(4) // off: 128 selector1: matchActions: length
expU32Push(96) // off: 132 selector2: length
// ... everything else should be the same as selector1 ...

if bytes.Equal(expected[:expectedLen], b[:expectedLen]) == false {
Expand Down Expand Up @@ -877,22 +878,22 @@ func TestReturnSelectorArgInt(t *testing.T) {
expectedLen += 4
}

expU32Push(1) // off: 0 number of selectors
expU32Push(4) // off: 4 relative ofset of selector (4 + 4 = 8)
expU32Push(56) // off: 8 selector: length
expU32Push(48) // off: 12 selector: matchReturnArgs length
expU32Push(24) // off: 16 selector: matchReturnArgs arg offset[0]
expU32Push(0) // off: 20 selector: matchReturnArgs arg offset[1]
expU32Push(0) // off: 24 selector: matchReturnArgs arg offset[2]
expU32Push(0) // off: 28 selector: matchReturnArgs arg offset[3]
expU32Push(0) // off: 32 selector: matchReturnArgs arg offset[4]
expU32Push(0) // off: 36 selector: matchReturnArgs[0].Index
expU32Push(SelectorOpEQ) // off: 40 selector: matchReturnArgs[0].Operator
expU32Push(16) // off: 44 selector: length (4 + 3*4) = 16
expU32Push(argTypeInt) // off: 48 selector: matchReturnArgs[0].Type
expU32Push(10) // off: 52 selector: matchReturnArgs[0].Values[0]
expU32Push(20) // off: 56 selector: matchReturnArgs[0].Values[1]
expU32Push(4) // off: 60 selector: MatchActions length
expU32Push(1) // off: 0 number of selectors
expU32Push(4) // off: 4 relative ofset of selector (4 + 4 = 8)
expU32Push(56) // off: 8 selector: length
expU32Push(48) // off: 12 selector: matchReturnArgs length
expU32Push(24) // off: 16 selector: matchReturnArgs arg offset[0]
expU32Push(0) // off: 20 selector: matchReturnArgs arg offset[1]
expU32Push(0) // off: 24 selector: matchReturnArgs arg offset[2]
expU32Push(0) // off: 28 selector: matchReturnArgs arg offset[3]
expU32Push(0) // off: 32 selector: matchReturnArgs arg offset[4]
expU32Push(0) // off: 36 selector: matchReturnArgs[0].Index
expU32Push(SelectorOpEQ) // off: 40 selector: matchReturnArgs[0].Operator
expU32Push(16) // off: 44 selector: length (4 + 3*4) = 16
expU32Push(gt.GenericIntType) // off: 48 selector: matchReturnArgs[0].Type
expU32Push(10) // off: 52 selector: matchReturnArgs[0].Values[0]
expU32Push(20) // off: 56 selector: matchReturnArgs[0].Values[1]
expU32Push(4) // off: 60 selector: MatchActions length

if bytes.Equal(expected[:expectedLen], b[:expectedLen]) == false {
t.Errorf("\ngot: %v\nexp: %v\n", b[:expectedLen], expected[:expectedLen])
Expand Down

0 comments on commit b0d041c

Please sign in to comment.