1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! `NetworkDenyAll` lowering for the Linux backend (proof-spine S9 / D3), split out of
//! `backend_impl.rs` to hold it under the non-overridable file-size cap.
//!
//! THE LOWERING (mirrors the S4/S5 seam): the admitted [`NetPolicy`] DRIVES whether the
//! launch plan engages an EMPTY network namespace. For [`NetPolicy::DenyAll`] the launcher
//! births the workload child in a NEW, EMPTY netns (`CLONE_NEWNET`, alongside the S8
//! `CLONE_NEWUSER` rendezvous it requires): the netns has NO external interface — only a
//! loopback `lo` (which the kernel reports `IFF_UP`, like every loopback, but with NO address
//! assigned and NO routes, so neither `127.0.0.1` nor any external destination is reachable) —
//! so the workload is STRUCTURALLY unable to reach any IP/packet network. Combined with the S5 fd-scrub (which already closes every
//! undeclared inherited fd, including any inherited routable socket), this realizes the D3
//! "network" definition: no inherited IP/packet/netlink/undeclared-Unix sockets, no
//! externally-routable socket op succeeds, isolated netns, loopback unavailable unless
//! separately admitted, no iface-config / no joining another netns.
//!
//! HOSTCONTROL CARVE-OUT (D3): the launcher's OWN declared private control channels (the
//! protocol Unix-socket / error-pipe / userns-sync-pipe fds it fd-PASSES to the child) are
//! HostControl, NOT workload network authority. netns isolation does not affect already-open
//! fd-passed sockets, so the launcher protocol still runs the workload to a verdict. "Deny
//! network" is therefore about UNDECLARED network authority, never the launcher's own
//! declared control plumbing.
//!
//! `NetPolicy::AllowList(..)` is OUT OF SCOPE (S9 — no broker in v1). It is absent from the
//! ceiling so it never admits, but defense-in-depth this gate ALSO refuses it: were it ever
//! to reach `execute()` (a future ceiling change without a broker lowering), the workload
//! must NOT run with the empty-netns silently realizing the wrong policy (deny-everything
//! instead of the scoped allow-list — an unrealized guarantee). SAFE std; the OS work
//! (`CLONE_NEWNET` + the userns rendezvous) is the launcher's.
use LinuxBackend;
use crate;
use crate;
use crateObservedFact;
/// The outcome of lowering the admitted network policy: whether the launch plan must
/// engage the empty network namespace (`NetworkDenyAll`), carried with the observed facts.
pub
/// LOWER the plan's admitted [`Capability::Network`] policy onto the launcher's empty-netns
/// engagement. On a policy the lowering does not realize (`AllowList` — no broker in v1) it
/// returns `Err(observed)` with a `network_lowering_failed` fact appended, so the caller
/// FAILS CLOSED — the workload never runs under an unrealized network guarantee. With NO
/// `Network` capability admitted (the spec declared none) `deny_network` is `false` — the
/// no-netns path is unchanged (the default is NOT to confine a guarantee the spec did not
/// request; admission already refused any spec needing a network guarantee this backend
/// cannot back).
///
/// `_backend` is unused today (the netns needs no host resolver) but kept in the signature
/// so the seam matches `lower_environment` / `lower_inherited_fds`.
pub
/// The admitted [`NetPolicy`] to realize: the admitted `Network` capability's policy, or
/// `None` when the spec declared no `Network` capability. The plan was admitted against our
/// ceiling, so any admitted `Network` capability whose key is `NetworkDenyAll` is `DenyAll`.