Seccomp cannot filter socketcall(2) arguments because the address
family is behind a userspace pointer that BPF cannot dereference.
Only an LSM (AppArmor or SELinux) can deny AF_ALG via the
security_socket_create hook in the socketcall path.
Skip the socketcall_int80 subtest when neither AppArmor nor SELinux
is reported by the daemon, since the test would always fail without
an LSM to enforce the deny rule.
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
| ... | ... |
@@ -3,6 +3,7 @@ package container |
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
_ "embed" |
| 6 |
+ "slices" |
|
| 6 | 7 |
"strings" |
| 7 | 8 |
"testing" |
| 8 | 9 |
|
| ... | ... |
@@ -94,6 +95,12 @@ func TestExecSocketDenied(t *testing.T) {
|
| 94 | 94 |
// to set the address family and socket type at compile time. |
| 95 | 95 |
t.Run("socketcall_int80", func(t *testing.T) {
|
| 96 | 96 |
skip.If(t, !isAmd64, "int $0x80 ia32 compat only available on amd64") |
| 97 |
+ // Seccomp cannot filter socketcall arguments (the address family |
|
| 98 |
+ // is behind a userspace pointer). Only an LSM (AppArmor or |
|
| 99 |
+ // SELinux) can deny AF_ALG via the security_socket_create hook. |
|
| 100 |
+ hasLSM := slices.Contains(testEnv.DaemonInfo.SecurityOptions, "name=apparmor") || |
|
| 101 |
+ slices.Contains(testEnv.DaemonInfo.SecurityOptions, "name=selinux") |
|
| 102 |
+ skip.If(t, !hasLSM, "socketcall filtering requires AppArmor or SELinux") |
|
| 97 | 103 |
|
| 98 | 104 |
srcPath := "/tmp/socketcall.c" |
| 99 | 105 |
res := container.ExecT(ctx, t, apiClient, cID, []string{
|
| ... | ... |
@@ -101,9 +108,10 @@ func TestExecSocketDenied(t *testing.T) {
|
| 101 | 101 |
}) |
| 102 | 102 |
res.AssertSuccess(t) |
| 103 | 103 |
|
| 104 |
- // AF_ALG (38) via socketcall must be denied by AppArmor's |
|
| 105 |
- // "deny network alg" rule, which catches it at the kernel |
|
| 106 |
- // socket layer even though seccomp cannot filter socketcall args. |
|
| 104 |
+ // AF_ALG (38) via socketcall must be denied by the LSM |
|
| 105 |
+ // (AppArmor's "deny network alg" or SELinux's alg_socket deny), |
|
| 106 |
+ // which catches it at the security_socket_create hook even |
|
| 107 |
+ // though seccomp cannot filter socketcall args. |
|
| 107 | 108 |
t.Run("AF_ALG", func(t *testing.T) {
|
| 108 | 109 |
binPath := "/tmp/socketcall_af_alg" |
| 109 | 110 |
res := container.ExecT(ctx, t, apiClient, cID, append(gcc, |