Repository navigation
Unlisted hostname request terminates policy boundary instead of returning a clean denial #3577
Description
This was generated by AI during triage.
Summary
A network request to a hostname that is completely absent from the sandbox policy can terminate the policy boundary instead of returning a normal deny result. The OpenShell exec client then loses its relay before receiving the command's exit status, and the sandbox transitions out of Ready.
The equivalent negative test against an allowed hostname on a disallowed port fails cleanly with EACCES, emits a DENIED audit event, and leaves the sandbox Ready.
Environment
- Kubernetes on Linux/amd64
- RuntimeClass:
kata-qemu - Kata Containers: 4.2.0
- OpenShell development builds, including the sandbox-runtime change from PR fix(sandbox): qualify task memory against workload child #3574
The gateway and supervisor used mutable development tags and may have been from different builds. Version skew is a plausible contributing factor and should be checked during triage.
Policy
version: 1
filesystem_policy:
include_workdir: true
read_only: [/usr, /lib, /proc, /dev/urandom, /app, /etc, /var/log]
read_write: [/sandbox, /tmp, /dev/null]
landlock:
compatibility: best_effort
network_policies:
example_http:
name: example-http
endpoints:
- host: example.com
port: 80
protocol: tcp
binaries:
- { path: "/**" }Reproduction
-
Create a sandbox with the policy above and wait until policy version 1 is loaded.
-
Confirm the allowed request succeeds:
bash -c 'exec 3<>/dev/tcp/example.com/80; printf "GET / HTTP/1.0\r\nHost: example.com\r\nConnection: close\r\n\r\n" >&3; IFS= read -r line <&3; printf "%s\n" "$line"'Observed:
HTTP/1.1 200 OK. -
Attempt a request to a hostname absent from the policy:
bash -c 'exec 3<>/dev/tcp/example.org/80'
Actual behavior
The exec client reports:
The service is currently unavailable: exec relay closed before the command reported an exit status
The supervisor reports a mediated-DNS failure followed by loss of its boundary channel:
mediated DNS accept failed; retrying
boundary terminated: boundary lost during wait: transport error
The supervisor terminates and the sandbox transitions from Ready to Stopped/DependenciesNotReady.
Expected behavior
- The request to
example.org:80is denied normally. - The caller receives a deterministic nonzero result such as
EACCES. - A
DENIEDaudit event records the destination and denial reason. - The policy boundary, supervisor, and sandbox remain healthy and Ready.
Control case
With the same policy, connecting to the allowed hostname on an unauthorized port behaves correctly:
/usr/bin/bash: connect: Permission denied
Audit output:
OCSF NET:OPEN [MED] DENIED /usr/bin/bash(0) -> 198.18.0.0:81 [reason:transparent_tcp_mapping_denied]
The sandbox remains Ready afterward.
Suggested validation
- Add an end-to-end test for DNS resolution/connection to a hostname absent from all network policy endpoints.
- Assert that the request is denied and audited without terminating the boundary or supervisor.
- Run the test with matching component builds and, separately, with a supported mixed-version configuration if version skew is expected to work.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsPlanning
Activity
drew commentedon Sep 23, 2026
Implementation Plan
Issue type:
fixComplexity: High
Confidence: Low — the reported failure is credible, but its initiating fault is not identified.
Summary
An unlisted hostname should produce a policy DNS refusal and audit event while the sandbox remains usable. The current DNS evaluator and wire handler already implement those responses; the reported boundary loss may arise elsewhere in the mediation path or from mismatched images. Validate the full path before changing production logic.
Scope
e2e/rust/tests/policy_dns_denial.rs: exercise an unlisted hostname, assert the denial audit and a subsequent successful exec.Implementation Steps
Test Plan
REFUSEDand no upstream lookup; add a focused test if the production fault is isolated.policy_dns_ineligibleaudit, and successful subsequent exec. Run the Kubernetes lane on AMD64 Kata when available.Risks & Open Questions
EACCESand an audit destination ofexample.org:80are not stable expectations. The DNS denial identifies the name at port 53./proc, or LSM behavior change is planned; reassess if the fault is in that area.Documentation Impact
None until a production behavior or operational change is identified.
Revision 1 — initial validation plan
drew commentedon Sep 23, 2026
Validation update
I traced the current DNS path. A name absent from all network policy endpoints returns
PolicyDnsError::Ineligible; the wire handler converts it to DNSREFUSEDand the OCSF event carriesDENIEDwithpolicy_dns_ineligible. The mediated runtime sends the DNS response through the normal query channel. The existingineligible_query_is_refused_without_upstream_callunit test covers the evaluator and wire response.I added a full-path regression test in a local branch and ran it against gateway, supervisor, and sandbox images built from the same checkout on ARM64 Docker. It passed: unlisted-name resolution failed, the same audit line contained the hostname,
DENIED, andpolicy_dns_ineligible, and a later exec in the same sandbox succeeded. This does not reproduce or resolve the reported AMD64 Kata boundary loss.To isolate that loss, please provide the exact gateway, supervisor, and sandbox image digests, plus the sandbox/container exit reason and the first sandbox, Kata, or host error preceding
mediated DNS accept failed; retrying. The reported mutable development tags leave version skew unresolved.For a DNS-stage refusal, a nonzero name-resolution result is the stable caller outcome; a TCP
EACCESor destination audit forexample.org:80is not guaranteed because no TCP connect has occurred.github-actions commentedon Oct 15, 2026
This issue has had no activity for 14 days and is now marked stale. It may be closed in 14 days if there is no further activity. Comment or remove the state:stale label to keep it open.