github.com/DataDog/datadog-agent/pkg/security/secl@v0.55.0-devel.0.20240517055856-10c4965fea94/model/marshallers_linux.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the Apache License Version 2.0. 3 // This product includes software developed at Datadog (https://www.datadoghq.com/). 4 // Copyright 2016-present Datadog, Inc. 5 6 // Package model holds model related files 7 package model 8 9 import ( 10 "encoding/binary" 11 "math" 12 "time" 13 ) 14 15 // BinaryMarshaler interface implemented by every event type 16 type BinaryMarshaler interface { 17 MarshalBinary(data []byte) (int, error) 18 } 19 20 // MarshalBinary calls a series of BinaryMarshaler 21 func MarshalBinary(data []byte, binaryMarshalers ...BinaryMarshaler) (int, error) { 22 written := 0 23 for _, marshaler := range binaryMarshalers { 24 n, err := marshaler.MarshalBinary(data[written:]) 25 written += n 26 if err != nil { 27 return written, err 28 } 29 } 30 return written, nil 31 } 32 33 // MarshalBinary marshals a binary representation of itself 34 func (e *FileFields) MarshalBinary(data []byte) (int, error) { 35 if len(data) < 72 { 36 return 0, ErrNotEnoughSpace 37 } 38 binary.NativeEndian.PutUint64(data[0:8], e.Inode) 39 binary.NativeEndian.PutUint32(data[8:12], e.MountID) 40 binary.NativeEndian.PutUint32(data[12:16], e.PathID) 41 binary.NativeEndian.PutUint32(data[16:20], uint32(e.Flags)) 42 43 // +4 for padding 44 45 binary.NativeEndian.PutUint32(data[24:28], e.UID) 46 binary.NativeEndian.PutUint32(data[28:32], e.GID) 47 binary.NativeEndian.PutUint32(data[32:36], e.NLink) 48 binary.NativeEndian.PutUint16(data[36:38], e.Mode) 49 50 // +2 for padding 51 52 timeSec := time.Unix(0, int64(e.CTime)).Unix() 53 timeNsec := time.Unix(0, int64(e.CTime)).UnixNano() 54 timeNsec = timeNsec - timeSec*int64(math.Pow10(9)) 55 if timeNsec < 0 { 56 timeNsec = 0 57 } 58 binary.NativeEndian.PutUint64(data[40:48], uint64(timeSec)) 59 binary.NativeEndian.PutUint64(data[48:56], uint64(timeNsec)) 60 61 timeSec = time.Unix(0, int64(e.MTime)).Unix() 62 timeNsec = time.Unix(0, int64(e.MTime)).UnixNano() 63 timeNsec = timeNsec - timeSec*int64(math.Pow10(9)) 64 if timeNsec < 0 { 65 timeNsec = 0 66 } 67 binary.NativeEndian.PutUint64(data[56:64], uint64(timeSec)) 68 binary.NativeEndian.PutUint64(data[64:72], uint64(timeNsec)) 69 return 72, nil 70 } 71 72 // MarshalProcCache marshals a binary representation of itself 73 func (e *Process) MarshalProcCache(data []byte, bootTime time.Time) (int, error) { 74 // Marshal proc_cache_t 75 if len(data) < ContainerIDLen { 76 return 0, ErrNotEnoughSpace 77 } 78 copy(data[0:ContainerIDLen], e.ContainerID) 79 written := ContainerIDLen 80 81 toAdd, err := MarshalBinary(data[written:], &e.FileEvent) 82 if err != nil { 83 return 0, err 84 } 85 written += toAdd 86 87 if len(data[written:]) < 88 { 88 return 0, ErrNotEnoughSpace 89 } 90 91 marshalTime(data[written:written+8], e.ExecTime.Sub(bootTime)) 92 written += 8 93 94 copy(data[written:written+64], e.TTYName) 95 written += 64 96 97 copy(data[written:written+16], e.Comm) 98 written += 16 99 return written, nil 100 } 101 102 func marshalTime(data []byte, t time.Duration) { 103 binary.NativeEndian.PutUint64(data, uint64(t.Nanoseconds())) 104 } 105 106 // MarshalBinary marshalls a binary representation of itself 107 func (e *Credentials) MarshalBinary(data []byte) (int, error) { 108 if len(data) < 40 { 109 return 0, ErrNotEnoughSpace 110 } 111 112 binary.NativeEndian.PutUint32(data[0:4], e.UID) 113 binary.NativeEndian.PutUint32(data[4:8], e.GID) 114 binary.NativeEndian.PutUint32(data[8:12], e.EUID) 115 binary.NativeEndian.PutUint32(data[12:16], e.EGID) 116 binary.NativeEndian.PutUint32(data[16:20], e.FSUID) 117 binary.NativeEndian.PutUint32(data[20:24], e.FSGID) 118 binary.NativeEndian.PutUint64(data[24:32], e.CapEffective) 119 binary.NativeEndian.PutUint64(data[32:40], e.CapPermitted) 120 return 40, nil 121 } 122 123 // MarshalPidCache marshals a binary representation of itself 124 func (e *Process) MarshalPidCache(data []byte, bootTime time.Time) (int, error) { 125 // Marshal pid_cache_t 126 if len(data) < 80 { 127 return 0, ErrNotEnoughSpace 128 } 129 binary.NativeEndian.PutUint64(data[0:8], e.Cookie) 130 binary.NativeEndian.PutUint32(data[8:12], e.PPid) 131 132 // padding 133 134 marshalTime(data[16:24], e.ForkTime.Sub(bootTime)) 135 marshalTime(data[24:32], e.ExitTime.Sub(bootTime)) 136 binary.NativeEndian.PutUint64(data[32:40], e.UserSession.ID) 137 written := 40 138 139 n, err := MarshalBinary(data[written:], &e.Credentials) 140 if err != nil { 141 return 0, err 142 } 143 written += n 144 145 return written, nil 146 } 147 148 // MarshalBinary marshals a binary representation of itself 149 func (adlc *ActivityDumpLoadConfig) MarshalBinary() ([]byte, error) { 150 raw := make([]byte, 48) 151 152 var eventMask uint64 153 for _, evt := range adlc.TracedEventTypes { 154 eventMask |= 1 << (evt - FirstDiscarderEventType) 155 } 156 binary.NativeEndian.PutUint64(raw[0:8], eventMask) 157 binary.NativeEndian.PutUint64(raw[8:16], uint64(adlc.Timeout)) 158 binary.NativeEndian.PutUint64(raw[16:24], adlc.WaitListTimestampRaw) 159 binary.NativeEndian.PutUint64(raw[24:32], adlc.StartTimestampRaw) 160 binary.NativeEndian.PutUint64(raw[32:40], adlc.EndTimestampRaw) 161 binary.NativeEndian.PutUint32(raw[40:44], adlc.Rate) 162 binary.NativeEndian.PutUint32(raw[44:48], adlc.Paused) 163 164 return raw, nil 165 }