Skip to content

Commit 482eef0

Browse files
committed
fix(plugins/container): redefine port binding port and IP as integers
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
1 parent e1a0753 commit 482eef0

File tree

4 files changed

+102
-26
lines changed

4 files changed

+102
-26
lines changed

plugins/container/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
99
# project metadata
1010
project(
1111
container
12-
VERSION 0.2.4
12+
VERSION 0.2.5
1313
DESCRIPTION "Falco container metadata enrichment Plugin"
1414
LANGUAGES CXX)
1515

plugins/container/go-worker/pkg/container/docker.go

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@ package container
22

33
import (
44
"context"
5+
"encoding/binary"
56
"encoding/json"
67
"errors"
8+
"fmt"
79
"github.com/docker/docker/api/types"
810
"github.com/docker/docker/api/types/container"
911
"github.com/docker/docker/api/types/events"
1012
"github.com/docker/docker/api/types/filters"
1113
"github.com/docker/docker/client"
1214
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/config"
1315
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
16+
"net/netip"
17+
"strconv"
1418
"strings"
1519
"sync"
1620
"time"
@@ -102,7 +106,7 @@ func parseHealthcheckProbe(hcheck *container.HealthConfig) *event.Probe {
102106
return &p
103107
}
104108

105-
func (dc *dockerEngine) ctrToInfo(ctx context.Context, ctr types.ContainerJSON) event.Info {
109+
func (dc *dockerEngine) ctrToInfo(ctx context.Context, ctr types.ContainerJSON) (*event.Info, error) {
106110
hostCfg := ctr.HostConfig
107111
if hostCfg == nil {
108112
hostCfg = &container.HostConfig{
@@ -139,9 +143,29 @@ func (dc *dockerEngine) ctrToInfo(ctx context.Context, ctr types.ContainerJSON)
139143
}
140144
containerPort := port.Int()
141145
for _, portBinding := range portBindings {
146+
rawHostIP, rawHostPort := portBinding.HostIP, portBinding.HostPort
147+
// Parse IP address to uint32.
148+
addr, err := netip.ParseAddr(rawHostIP)
149+
if err != nil {
150+
return nil, fmt.Errorf("error parsing port binding's host IP %s as address: %w", rawHostIP, err)
151+
}
152+
if addr.Is6() {
153+
// TODO(ekoops): handle IPv6 addresses.
154+
continue
155+
}
156+
ipv4Addr := addr.As4()
157+
hostIP := binary.BigEndian.Uint32(ipv4Addr[:])
158+
159+
// Parse port as uint16.
160+
hostPort, err := strconv.ParseUint(rawHostPort, 10, 16)
161+
if err != nil {
162+
return nil, fmt.Errorf("error converting port binding's port %s into 16-bit unsigned integer: %w",
163+
rawHostPort, err)
164+
}
165+
142166
portMappings = append(portMappings, event.PortMapping{
143-
HostIp: portBinding.HostIP,
144-
HostPort: portBinding.HostPort,
167+
HostIP: hostIP,
168+
HostPort: (uint16)(hostPort),
145169
ContainerPort: containerPort,
146170
})
147171
}
@@ -259,7 +283,7 @@ func (dc *dockerEngine) ctrToInfo(ctx context.Context, ctr types.ContainerJSON)
259283
size = *ctr.SizeRw
260284
}
261285

262-
return event.Info{
286+
return &event.Info{
263287
Container: event.Container{
264288
Type: typeDocker.ToCTValue(),
265289
ID: shortContainerID(ctr.ID),
@@ -293,17 +317,23 @@ func (dc *dockerEngine) ctrToInfo(ctx context.Context, ctr types.ContainerJSON)
293317
ReadinessProbe: readinessProbe,
294318
HealthcheckProbe: healthcheckProbe,
295319
},
296-
}
320+
}, nil
297321
}
298322

299323
func (dc *dockerEngine) get(ctx context.Context, containerId string) (*event.Event, error) {
300324
ctrJson, _, err := dc.ContainerInspectWithRaw(ctx, containerId, config.GetWithSize())
301325
if err != nil {
302326
return nil, err
303327
}
328+
329+
info, err := dc.ctrToInfo(ctx, ctrJson)
330+
if err != nil {
331+
return nil, fmt.Errorf("error converting container to info: %w", err)
332+
}
333+
304334
return &event.Event{
335+
Info: *info,
305336
IsCreate: true,
306-
Info: dc.ctrToInfo(ctx, ctrJson),
307337
}, nil
308338
}
309339

@@ -340,9 +370,14 @@ func (dc *dockerEngine) List(ctx context.Context) ([]event.Event, error) {
340370
IsCreate: true,
341371
}
342372
}
373+
info, err := dc.ctrToInfo(ctx, ctrJson)
374+
if err != nil {
375+
return nil, fmt.Errorf("error converting container %s (index %d) to info: %w", ctr.ID, idx, err)
376+
}
377+
343378
evts[idx] = event.Event{
379+
Info: *info,
344380
IsCreate: true,
345-
Info: dc.ctrToInfo(ctx, ctrJson),
346381
}
347382
}
348383
return evts, nil
@@ -379,17 +414,20 @@ func (dc *dockerEngine) Listen(ctx context.Context, wg *sync.WaitGroup) (<-chan
379414
case events.ActionCreate, events.ActionStart:
380415
ctrJson, _, err = dc.ContainerInspectWithRaw(ctx, msg.Actor.ID, config.GetWithSize())
381416
if err == nil {
382-
outCh <- event.Event{
383-
Info: dc.ctrToInfo(ctx, ctrJson),
384-
IsCreate: true,
417+
var info *event.Info
418+
if info, err = dc.ctrToInfo(ctx, ctrJson); err == nil {
419+
outCh <- event.Event{
420+
Info: *info,
421+
IsCreate: true,
422+
}
385423
}
386424
}
387425
case events.ActionDestroy:
388426
err = errors.New("inspect useless on action destroy")
389427
}
390428

391429
// This is called for ActionDestroy
392-
// AND as a fallback whenever ContainerInspectWithRaw fails.
430+
// AND as a fallback whenever ContainerInspectWithRaw or dockerEngine.ctrToInfo fail.
393431
if err != nil {
394432
// At least send an event with the minimum set of data
395433
outCh <- event.Event{

plugins/container/go-worker/pkg/container/podman.go

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ package container
44

55
import (
66
"context"
7+
"encoding/binary"
78
"encoding/json"
89
"errors"
10+
"fmt"
911
"github.com/containers/podman/v5/libpod/define"
1012
"github.com/containers/podman/v5/pkg/bindings"
1113
"github.com/containers/podman/v5/pkg/bindings/containers"
@@ -15,6 +17,7 @@ import (
1517
"github.com/docker/docker/api/types/events"
1618
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/config"
1719
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
20+
"net/netip"
1821
"strconv"
1922
"strings"
2023
"sync"
@@ -41,7 +44,7 @@ func (pc *podmanEngine) copy(ctx context.Context) (Engine, error) {
4144
return newPodmanEngine(ctx, pc.socket)
4245
}
4346

44-
func (pc *podmanEngine) ctrToInfo(ctr *define.InspectContainerData) event.Info {
47+
func (pc *podmanEngine) ctrToInfo(ctr *define.InspectContainerData) (*event.Info, error) {
4548
cfg := ctr.Config
4649
if cfg == nil {
4750
cfg = &define.InspectContainerConfig{}
@@ -80,9 +83,30 @@ func (pc *podmanEngine) ctrToInfo(ctr *define.InspectContainerData) event.Info {
8083
continue
8184
}
8285
for _, portBinding := range portBindings {
86+
rawHostIP, rawHostPort := portBinding.HostIP, portBinding.HostPort
87+
88+
// Parse IP address to uint32.
89+
addr, err := netip.ParseAddr(rawHostIP)
90+
if err != nil {
91+
return nil, fmt.Errorf("error parsing port binding's host IP %s as address: %w", rawHostIP, err)
92+
}
93+
if addr.Is6() {
94+
// TODO(ekoops): handle IPv6 addresses.
95+
continue
96+
}
97+
ipv4Addr := addr.As4()
98+
hostIP := binary.BigEndian.Uint32(ipv4Addr[:])
99+
100+
// Parse port as uint16.
101+
hostPort, err := strconv.ParseUint(rawHostPort, 10, 16)
102+
if err != nil {
103+
return nil, fmt.Errorf("error converting port binding's port %s into 16-bit unsigned integer: %w",
104+
rawHostPort, err)
105+
}
106+
83107
portMappings = append(portMappings, event.PortMapping{
84-
HostIp: portBinding.HostIP,
85-
HostPort: portBinding.HostPort,
108+
HostIP: hostIP,
109+
HostPort: (uint16)(hostPort),
86110
ContainerPort: containerPort,
87111
})
88112
}
@@ -149,7 +173,7 @@ func (pc *podmanEngine) ctrToInfo(ctr *define.InspectContainerData) event.Info {
149173
size = *ctr.SizeRw
150174
}
151175

152-
return event.Info{
176+
return &event.Info{
153177
Container: event.Container{
154178
Type: typePodman.ToCTValue(),
155179
ID: shortContainerID(ctr.ID),
@@ -183,7 +207,7 @@ func (pc *podmanEngine) ctrToInfo(ctr *define.InspectContainerData) event.Info {
183207
ReadinessProbe: readinessProbe,
184208
HealthcheckProbe: healthcheckProbe,
185209
},
186-
}
210+
}, nil
187211
}
188212

189213
func (pc *podmanEngine) get(_ context.Context, containerId string) (*event.Event, error) {
@@ -192,8 +216,14 @@ func (pc *podmanEngine) get(_ context.Context, containerId string) (*event.Event
192216
if err != nil {
193217
return nil, err
194218
}
219+
220+
info, err := pc.ctrToInfo(ctrInfo)
221+
if err != nil {
222+
return nil, fmt.Errorf("error converting container to info: %w", err)
223+
}
224+
195225
return &event.Event{
196-
Info: pc.ctrToInfo(ctrInfo),
226+
Info: *info,
197227
IsCreate: true,
198228
}, nil
199229
}
@@ -214,7 +244,7 @@ func (pc *podmanEngine) List(_ context.Context) ([]event.Event, error) {
214244
if err != nil {
215245
return nil, err
216246
}
217-
for _, c := range cList {
247+
for idx, c := range cList {
218248
ctrInfo, err := containers.Inspect(pc.pCtx, c.ID, &containers.InspectOptions{Size: &size})
219249
if err != nil {
220250
evts = append(evts, event.Event{
@@ -231,8 +261,13 @@ func (pc *podmanEngine) List(_ context.Context) ([]event.Event, error) {
231261
IsCreate: true,
232262
})
233263
} else {
264+
info, err := pc.ctrToInfo(ctrInfo)
265+
if err != nil {
266+
return nil, fmt.Errorf("error converting container %s (index %d) to info: %w", ctrInfo.ID, idx, err)
267+
}
268+
234269
evts = append(evts, event.Event{
235-
Info: pc.ctrToInfo(ctrInfo),
270+
Info: *info,
236271
IsCreate: true,
237272
})
238273
}
@@ -290,17 +325,20 @@ func (pc *podmanEngine) Listen(ctx context.Context, wg *sync.WaitGroup) (<-chan
290325
case events.ActionCreate, events.ActionStart:
291326
ctr, err = containers.Inspect(pc.pCtx, ev.Actor.ID, &containers.InspectOptions{Size: &size})
292327
if err == nil {
293-
outCh <- event.Event{
294-
Info: pc.ctrToInfo(ctr),
295-
IsCreate: true,
328+
var info *event.Info
329+
if info, err = pc.ctrToInfo(ctr); err == nil {
330+
outCh <- event.Event{
331+
Info: *info,
332+
IsCreate: true,
333+
}
296334
}
297335
}
298336
case events.ActionRemove:
299337
err = errors.New("inspect useless on action destroy")
300338
}
301339

302340
// This is called for ActionRemove
303-
// AND as a fallback whenever Inspect fails.
341+
// AND as a fallback whenever Inspect or podmanEngine.ctrToInfo fail.
304342
if err != nil {
305343
// At least send an event with the minimal set of data
306344
outCh <- event.Event{

plugins/container/go-worker/pkg/event/event.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package event
33
import "encoding/json"
44

55
type PortMapping struct {
6-
HostIp string `json:"HostIp"`
7-
HostPort string `json:"HostPort"`
6+
HostIP uint32 `json:"HostIp"`
7+
HostPort uint16 `json:"HostPort"`
88
ContainerPort int `json:"ContainerPort"`
99
}
1010

0 commit comments

Comments
 (0)