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
//! Windows backend — **not yet native**. What runs on Windows today is the
//! [portable floor](super::FloorSandbox), and the trace says so.
//!
//! The Job Object was designed but never implemented: no Win32 API is called
//! here, so there is **no** job object, **no** kill-on-close process-tree
//! teardown, **no** active-process limit, and **no** restricted token. The CPU
//! and memory caps are unenforced too — the shared path applies them via
//! `RLIMIT_CPU` and an RSS monitor over `ps`, all unix-only. What a Windows run
//! does get is the floor: a fresh subprocess in an ephemeral workdir,
//! `kill_on_drop`, the wall-clock timeout, and the best-effort proxy-env strip.
//! Filesystem scoping and the wall cap, nothing stronger.
//!
//! **On Windows the floor enforces the wall clock and nothing else.** Stated
//! plainly because it is the whole contract here:
//!
//! - **Wall clock** — enforced, and the kill reaches the whole process tree via
//! `taskkill /T` (Windows has no signals and no `ps`; `taskkill` ships with the
//! OS, so this costs no dependency). It is the only thing standing between a
//! Windows run and running forever, so `max_wall_secs: None` there means
//! *unbounded*.
//! - **CPU, memory, processes** — not applied. `SandboxLimits` still carries
//! them, and `JobLimits` still maps them, but nothing enforces them until the
//! Job Object lands. They are never *claimed* either: a Windows outcome never
//! reports [`super::Cap::Cpu`] or [`super::Cap::Memory`], and the first run
//! configured with either cap logs a warning saying so.
//! - **Network** — no kernel boundary. Only the floor's proxy-env strip, which a
//! payload that does not read those variables ignores entirely.
//!
//! So [`WindowsSandbox::run`] reports [`Backend::PortableFloor`] rather than
//! [`Backend::WindowsJobObject`]: a run that creates no job object must not name
//! one in an audit trail. The real implementation needs `windows-sys`, which is
//! a new runtime dependency, and lands in its own release; until then the type
//! stays as the wiring point [`super::select`] already targets.
use ;
use crateResult;
/// The Windows backend. Currently the portable floor — see the module docs; the
/// Job Object is not implemented yet.
;
/// The Job Object limits derived from [`super::SandboxLimits`], as the flags and
/// values a `JOBOBJECT_EXTENDED_LIMIT_INFORMATION` would carry. Factored out as
/// pure data so it is unit-testable without the Win32 API.
///
/// **Prepared but not applied.** Nothing consumes this yet — it is the mapping
/// the real Job Object implementation will use once it exists.
pub