bpf-socket-bind: fix unexpected behavior with either 0 allow or deny rules
authornetworkException <git@nwex.de>
Sun, 10 Mar 2024 17:55:06 +0000 (18:55 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sun, 24 Mar 2024 11:08:58 +0000 (11:08 +0000)
commitf2cb9d17da9c47d11ebeac00c75dd3d788ec1fc3
tree025588207d02a027ad6b0fcfa5f3e25b04d5a403
parent5011038f1dcf3958f0bf0b2e11126f52e8486269
bpf-socket-bind: fix unexpected behavior with either 0 allow or deny rules

This patch fixes an issue where, when not specifiying either at least one
`SocketBindAllow` or `SocketBindDeny` rule, behavior for the bind syscall
filtering would be unexpected.

For example, when trying to bind to a port with only "SocketBindDeny=any"
given, the syscall would succeed:

> systemd-run -t -p "SocketBindDeny=any" nc -l 8080

Expected with this set of rules (also in accordance with the documentation)
would be an Operation not permitted error.

This behavior occurs because a default initialized socket_bind_rule struct
matches what "any" represents. When creating the bpf list all elements get
default initialized, as such represeting "any". Seemingly it is necressarry
to set the size of the map to at least one, as such if no allow rule is
given default initialization and minimal map size cause one any allow rule
to be in the map, causing the behavior observed above.

This patch solves this by introducing a new "match nothing" magic stored in
the rule's address family and setting such a rule as the first one if no
rule is given, making sure that default initialized rule structs are never
used.

Resolves #30556
src/core/bpf-socket-bind.c
src/core/bpf/socket_bind/socket-bind-api.bpf.h
src/core/bpf/socket_bind/socket-bind.bpf.c
test/units/testsuite-07.exec-context.sh