Summary
The AWF agent container seccomp profile (containers/agent/seccomp-profile.json) includes name_to_handle_at (NR 303) and open_by_handle_at (NR 304) in the SCMP_ACT_ALLOW list. Docker's default seccomp profile explicitly blocks both syscalls to prevent the Shocker container-escape attack (CVE-2014-9357), where an attacker obtains a raw inode handle via name_to_handle_at and then opens it in a privileged context using open_by_handle_at to escape the container namespace. The current gh-aw-firewall configuration stops this chain only at the second step — via the capability bounding set (CAP_DAC_READ_SEARCH absent, NoNewPrivs=1) — rather than at both the seccomp and capability layers as Docker's recommended hardening prescribes.
Affected Area
Container isolation / kernel attack surface — AWF agent container seccomp profile (containers/agent/seccomp-profile.json) and associated tests (src/seccomp-profile.test.ts).
Reproduction Outline
- Run a workflow inside the AWF agent container (custom seccomp profile active,
seccomp=unconfined not set).
- Call
name_to_handle_at(AT_FDCWD, "/etc/passwd", ...) via syscall — returns ret=0 with a valid inode handle and mnt_id for the ext4 bind-mounted path.
- Attempt
open_by_handle_at(mount_fd, handle, O_RDONLY) — returns ret=-1, errno=1 (EPERM) due to missing CAP_DAC_READ_SEARCH, not due to a seccomp block.
- Observe that step 2 is not blocked by seccomp (confirmed with
EFAULT on null-ptr probes: errno=14, not errno=1), while Docker's reference profile would block it with ENOSYS.
- Verify that
containers/agent/seccomp-profile.json lists both NR 303 and NR 304 in the single SCMP_ACT_ALLOW rule (lines ~192 and ~196) with no corresponding deny entry.
Observed Behavior
name_to_handle_at completes successfully, returning valid inode handles for host-bind-mounted ext4 paths (/etc/passwd, /home/runner/work, /bin/sh). The Shocker escape chain is halted only at open_by_handle_at by the capability bounding set. src/seccomp-profile.test.ts does not assert that NR 303 or NR 304 are blocked.
Expected Behavior
Both name_to_handle_at and open_by_handle_at should be denied at the seccomp layer (returned as SCMP_ACT_ERRNO), matching Docker's default hardening posture and providing two independent defense layers against the Shocker escape chain.
Security Relevance
The Shocker attack (CVE-2014-9357) uses name_to_handle_at + open_by_handle_at to escape container namespaces by obtaining a host-filesystem handle. While the capability bounding set currently prevents exploitation, relying on a single control means that any future configuration drift — capability grant, privilege escalation within the container, or a Linux kernel capability-check bypass — would leave the escape path fully open. Docker's explicit rationale for blocking these two syscalls is precisely this attack scenario.
Additional Context
This deviation from Docker's default seccomp policy is not documented in gh-aw's architecture or container isolation pages (introduction/overview/, introduction/architecture/). If allowing these syscalls is an intentional design choice (e.g., for legitimate filesystem handle use cases in workflows), that assumption should be documented explicitly alongside the capability-based mitigation that compensates for the missing seccomp block.
Suggested fix: Move name_to_handle_at (NR 303) and open_by_handle_at (NR 304) from the SCMP_ACT_ALLOW list to the SCMP_ACT_ERRNO deny list in containers/agent/seccomp-profile.json, and add assertions to src/seccomp-profile.test.ts confirming both are blocked (consistent with existing tests for ptrace, kexec_load, init_module).
gh-aw version: v0.68.3
Original finding: https://github.com/githubnext/gh-aw-security/issues/2064
Generated by File Issue · ● 243.4K · ◷
Summary
The AWF agent container seccomp profile (
containers/agent/seccomp-profile.json) includesname_to_handle_at(NR 303) andopen_by_handle_at(NR 304) in theSCMP_ACT_ALLOWlist. Docker's default seccomp profile explicitly blocks both syscalls to prevent the Shocker container-escape attack (CVE-2014-9357), where an attacker obtains a raw inode handle vianame_to_handle_atand then opens it in a privileged context usingopen_by_handle_atto escape the container namespace. The current gh-aw-firewall configuration stops this chain only at the second step — via the capability bounding set (CAP_DAC_READ_SEARCHabsent,NoNewPrivs=1) — rather than at both the seccomp and capability layers as Docker's recommended hardening prescribes.Affected Area
Container isolation / kernel attack surface — AWF agent container seccomp profile (
containers/agent/seccomp-profile.json) and associated tests (src/seccomp-profile.test.ts).Reproduction Outline
seccomp=unconfinednot set).name_to_handle_at(AT_FDCWD, "/etc/passwd", ...)via syscall — returnsret=0with a valid inode handle andmnt_idfor the ext4 bind-mounted path.open_by_handle_at(mount_fd, handle, O_RDONLY)— returnsret=-1, errno=1 (EPERM)due to missingCAP_DAC_READ_SEARCH, not due to a seccomp block.EFAULTon null-ptr probes: errno=14, not errno=1), while Docker's reference profile would block it withENOSYS.containers/agent/seccomp-profile.jsonlists both NR 303 and NR 304 in the singleSCMP_ACT_ALLOWrule (lines ~192 and ~196) with no corresponding deny entry.Observed Behavior
name_to_handle_atcompletes successfully, returning valid inode handles for host-bind-mounted ext4 paths (/etc/passwd,/home/runner/work,/bin/sh). The Shocker escape chain is halted only atopen_by_handle_atby the capability bounding set.src/seccomp-profile.test.tsdoes not assert that NR 303 or NR 304 are blocked.Expected Behavior
Both
name_to_handle_atandopen_by_handle_atshould be denied at the seccomp layer (returned asSCMP_ACT_ERRNO), matching Docker's default hardening posture and providing two independent defense layers against the Shocker escape chain.Security Relevance
The Shocker attack (CVE-2014-9357) uses
name_to_handle_at+open_by_handle_atto escape container namespaces by obtaining a host-filesystem handle. While the capability bounding set currently prevents exploitation, relying on a single control means that any future configuration drift — capability grant, privilege escalation within the container, or a Linux kernel capability-check bypass — would leave the escape path fully open. Docker's explicit rationale for blocking these two syscalls is precisely this attack scenario.Additional Context
This deviation from Docker's default seccomp policy is not documented in gh-aw's architecture or container isolation pages (
introduction/overview/,introduction/architecture/). If allowing these syscalls is an intentional design choice (e.g., for legitimate filesystem handle use cases in workflows), that assumption should be documented explicitly alongside the capability-based mitigation that compensates for the missing seccomp block.Suggested fix: Move
name_to_handle_at(NR 303) andopen_by_handle_at(NR 304) from theSCMP_ACT_ALLOWlist to theSCMP_ACT_ERRNOdeny list incontainers/agent/seccomp-profile.json, and add assertions tosrc/seccomp-profile.test.tsconfirming both are blocked (consistent with existing tests forptrace,kexec_load,init_module).gh-aw version: v0.68.3
Original finding: https://github.com/githubnext/gh-aw-security/issues/2064