• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

NVIDIA / nvrc / 20358693314

19 Dec 2025 03:18AM UTC coverage: 68.196% (+39.6%) from 28.618%
20358693314

Pull #84

github

web-flow
Merge d80170c79 into 5b8b670d9
Pull Request #84: NVRC complete code coverage

34 of 45 new or added lines in 6 files covered. (75.56%)

4 existing lines in 4 files now uncovered.

223 of 327 relevant lines covered (68.2%)

1.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.38
/src/mount.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright (c) NVIDIA CORPORATION
3

4
//! Filesystem setup for the minimal init environment.
5
//!
6
//! Coverage note: ~80% is the safe maximum. `setup()` mounts filesystems
7
//! and can only be tested in ephemeral VMs.
8

9
use crate::coreutils::{ln, mknod};
10
use anyhow::{Context, Result};
11
use nix::mount::{self, MsFlags};
12
use nix::sys::stat;
13
use std::fs;
14
use std::path::Path;
15

16
/// Check if path is mounted (exact match on mountpoint, not substring).
17
/// Uses exact field matching to avoid false positives like "/dev" matching "/dev/pts".
18
fn is_mounted_in(mounts: &str, path: &str) -> bool {
1✔
19
    mounts
20
        .lines()
21
        .any(|line| line.split_whitespace().nth(1) == Some(path))
3✔
22
}
23

24
/// Check if a filesystem type is available in the kernel.
25
/// Some filesystems (securityfs, efivarfs) may not be present in all kernels.
26
fn fs_available_in(filesystems: &str, fs: &str) -> bool {
1✔
27
    filesystems.lines().any(|line| line.contains(fs))
3✔
28
}
29

30
/// Mount filesystem only if not already mounted.
31
/// Idempotent: safe to call multiple times. Uses pre-read mounts snapshot
32
/// to avoid TOCTOU races between check and mount.
33
fn mount_cached(
1✔
34
    mounts: &str,
35
    source: &str,
36
    target: &str,
37
    fstype: &str,
38
    flags: MsFlags,
39
    data: Option<&str>,
40
) -> Result<()> {
41
    if !is_mounted_in(mounts, target) {
1✔
42
        mount::mount(Some(source), target, Some(fstype), flags, data)
3✔
43
            .with_context(|| format!("Failed to mount {source} on {target}"))?;
4✔
44
    }
45
    Ok(())
1✔
46
}
47

48
/// Remount a filesystem as read-only.
49
/// Security hardening: prevents writes to the root filesystem after init,
50
/// reducing attack surface in the confidential VM.
51
pub fn readonly(target: &str) -> Result<()> {
1✔
52
    let flags = MsFlags::MS_NOSUID | MsFlags::MS_NODEV | MsFlags::MS_RDONLY | MsFlags::MS_REMOUNT;
1✔
53
    mount::mount(None::<&str>, target, None::<&str>, flags, None::<&str>)
1✔
54
        .with_context(|| format!("Failed to remount {target} readonly"))
3✔
55
}
56

57
/// Mount filesystem only if the fstype is available AND the target exists.
58
/// Used for optional filesystems like securityfs and efivarfs that may not
59
/// be present on all systems or kernel configurations.
60
fn mount_if_cached(
1✔
61
    mounts: &str,
62
    filesystems: &str,
63
    fstype: &str,
64
    source: &str,
65
    target: &str,
66
    flags: MsFlags,
67
    data: Option<&str>,
68
) -> Result<()> {
69
    if fs_available_in(filesystems, fstype) && Path::new(target).exists() {
2✔
70
        mount_cached(mounts, source, target, fstype, flags, data)?;
1✔
71
    }
72
    Ok(())
1✔
73
}
74

75
/// Create /dev symlinks pointing to /proc entries.
76
/// Standard Unix convention: /dev/stdin, /dev/stdout, /dev/stderr should
77
/// exist for programs that expect them. /dev/fd provides access to open
78
/// file descriptors via /proc/self/fd.
79
fn proc_symlinks() -> Result<()> {
1✔
80
    for (src, dst) in [
2✔
81
        ("/proc/kcore", "/dev/core"),
1✔
82
        ("/proc/self/fd", "/dev/fd"),
1✔
83
        ("/proc/self/fd/0", "/dev/stdin"),
1✔
84
        ("/proc/self/fd/1", "/dev/stdout"),
1✔
85
        ("/proc/self/fd/2", "/dev/stderr"),
1✔
86
    ] {
87
        ln(src, dst)?;
2✔
88
    }
89
    Ok(())
1✔
90
}
91

92
/// Create essential /dev device nodes for basic I/O.
93
/// These character devices are fundamental Unix primitives:
94
/// - /dev/null: discard output, read returns EOF
95
/// - /dev/zero: infinite stream of zeros
96
/// - /dev/random, /dev/urandom: cryptographic randomness
97
fn device_nodes() -> Result<()> {
1✔
98
    for (path, minor) in [
2✔
99
        ("/dev/null", 3u64),
1✔
100
        ("/dev/zero", 5u64),
1✔
101
        ("/dev/random", 8u64),
1✔
102
        ("/dev/urandom", 9u64),
1✔
103
    ] {
104
        mknod(path, stat::SFlag::S_IFCHR, 1, minor)?; // major 1 = memory devices
2✔
105
    }
106
    Ok(())
1✔
107
}
108

109
/// Set up the minimal filesystem hierarchy required for GPU initialization.
110
/// Creates /proc, /dev, /sys, /run, /tmp mounts and essential device nodes.
111
/// Snapshot-based: reads mount state once to avoid TOCTOU races.
UNCOV
112
pub fn setup() -> Result<()> {
×
113
    // Snapshot mount state once - consistent view, no TOCTOU
114
    let mounts = fs::read_to_string("/proc/mounts").unwrap_or_default();
×
115
    let filesystems = fs::read_to_string("/proc/filesystems").unwrap_or_default();
×
116

117
    let common = MsFlags::MS_NOSUID | MsFlags::MS_NOEXEC | MsFlags::MS_NODEV | MsFlags::MS_RELATIME;
×
118
    mount_cached(&mounts, "proc", "/proc", "proc", common, None)?;
×
119
    let dev_flags = MsFlags::MS_NOSUID | MsFlags::MS_NOEXEC | MsFlags::MS_RELATIME;
×
120
    mount_cached(
121
        &mounts,
×
122
        "dev",
123
        "/dev",
124
        "devtmpfs",
125
        dev_flags,
126
        Some("mode=0755"),
127
    )?;
128
    mount_cached(&mounts, "sysfs", "/sys", "sysfs", common, None)?;
×
129
    mount_cached(&mounts, "run", "/run", "tmpfs", common, Some("mode=0755"))?;
×
130
    let tmp_flags = MsFlags::MS_NOSUID | MsFlags::MS_NODEV | MsFlags::MS_RELATIME;
×
131
    mount_cached(&mounts, "tmpfs", "/tmp", "tmpfs", tmp_flags, None)?;
×
132
    mount_if_cached(
133
        &mounts,
×
134
        &filesystems,
×
135
        "securityfs",
136
        "securityfs",
137
        "/sys/kernel/security",
138
        common,
139
        None,
140
    )?;
141
    mount_if_cached(
142
        &mounts,
×
143
        &filesystems,
×
144
        "efivarfs",
145
        "efivarfs",
146
        "/sys/firmware/efi/efivars",
147
        common,
148
        None,
149
    )?;
150
    proc_symlinks()?;
×
151
    device_nodes()?;
×
152
    Ok(())
×
153
}
154

155
#[cfg(test)]
156
mod tests {
157
    use super::*;
158
    use std::fs;
159

160
    // === Safe parsing function tests ===
161

162
    #[test]
163
    fn test_is_mounted_in() {
164
        let mounts = fs::read_to_string("/proc/mounts").unwrap();
165
        assert!(is_mounted_in(&mounts, "/"));
166
        assert!(!is_mounted_in(&mounts, "/nonexistent"));
167
    }
168

169
    #[test]
170
    fn test_is_mounted_exact_match() {
171
        // /dev/pts mounted should NOT match /dev (substring matching bug fix)
172
        let mounts = "devpts /dev/pts devpts rw 0 0\ntmpfs /tmp tmpfs rw 0 0\n";
173
        assert!(!is_mounted_in(mounts, "/dev"));
174
        assert!(is_mounted_in(mounts, "/dev/pts"));
175
        assert!(is_mounted_in(mounts, "/tmp"));
176
    }
177

178
    #[test]
179
    fn test_is_mounted_empty() {
180
        assert!(!is_mounted_in("", "/"));
181
        assert!(!is_mounted_in("", "/dev"));
182
    }
183

184
    #[test]
185
    fn test_fs_available_in() {
186
        let filesystems = fs::read_to_string("/proc/filesystems").unwrap();
187
        assert!(fs_available_in(&filesystems, "proc"));
188
        assert!(fs_available_in(&filesystems, "sysfs"));
189
        assert!(!fs_available_in(&filesystems, "nonexistent_fs"));
190
    }
191

192
    #[test]
193
    fn test_fs_available_empty() {
194
        assert!(!fs_available_in("", "proc"));
195
    }
196

197
    // === mount_cached tests (safe: no-op when already mounted) ===
198

199
    #[test]
200
    fn test_mount_cached_already_mounted() {
201
        // When target is already in mounts, mount_cached is a no-op
202
        let mounts = "proc /proc proc rw 0 0\n";
203
        let result = mount_cached(mounts, "proc", "/proc", "proc", MsFlags::empty(), None);
204
        assert!(result.is_ok());
205
    }
206

207
    // === mount_if_cached tests (safe: no-op when conditions not met) ===
208

209
    #[test]
210
    fn test_mount_if_cached_fs_not_available() {
211
        // When filesystem is not available, should be no-op
212
        let mounts = "";
213
        let filesystems = "nodev tmpfs\n";
214
        let result = mount_if_cached(
215
            mounts,
216
            filesystems,
217
            "nonexistent_fs",
218
            "src",
219
            "/tmp", // exists but fs not available
220
            MsFlags::empty(),
221
            None,
222
        );
223
        assert!(result.is_ok());
224
    }
225

226
    #[test]
227
    fn test_mount_if_cached_target_not_exists() {
228
        // When target path doesn't exist, should be no-op
229
        let mounts = "";
230
        let filesystems = "nodev tmpfs\n";
231
        let result = mount_if_cached(
232
            mounts,
233
            filesystems,
234
            "tmpfs",
235
            "src",
236
            "/nonexistent/path",
237
            MsFlags::empty(),
238
            None,
239
        );
240
        assert!(result.is_ok());
241
    }
242

243
    #[test]
244
    fn test_mount_if_cached_already_mounted() {
245
        // When already mounted, should be no-op
246
        let mounts = "tmpfs /tmp tmpfs rw 0 0\n";
247
        let filesystems = "nodev tmpfs\n";
248
        let result = mount_if_cached(
249
            mounts,
250
            filesystems,
251
            "tmpfs",
252
            "tmpfs",
253
            "/tmp",
254
            MsFlags::empty(),
255
            None,
256
        );
257
        assert!(result.is_ok());
258
    }
259

260
    // === Error path tests (safe: mount fails, no changes made) ===
261

262
    #[test]
263
    fn test_mount_cached_fails_nonexistent_target() {
264
        // Trying to mount to nonexistent path should fail
265
        let mounts = "";
266
        let result = mount_cached(
267
            mounts,
268
            "tmpfs",
269
            "/nonexistent/mount/point",
270
            "tmpfs",
271
            MsFlags::empty(),
272
            None,
273
        );
274
        assert!(result.is_err());
275
    }
276

277
    #[test]
278
    fn test_readonly_fails_nonexistent() {
279
        // Trying to remount nonexistent path should fail
280
        let result = readonly("/nonexistent/path");
281
        assert!(result.is_err());
282
    }
283

284
    // === Functions that need root but are safe ===
285

286
    fn require_root() {
287
        use nix::unistd::Uid;
288
        use std::env;
289
        use std::process::Command;
290

291
        if Uid::effective().is_root() {
292
            return;
293
        }
294

295
        #[cfg(coverage)]
296
        panic!("coverage tests must run as root - use: sudo cargo llvm-cov");
297

298
        #[cfg(not(coverage))]
299
        {
300
            let args: Vec<String> = env::args().collect();
301
            match Command::new("sudo").args(&args).status() {
302
                Ok(status) => std::process::exit(status.code().unwrap_or(1)),
303
                Err(e) => panic!("failed to run sudo: {}", e),
304
            }
305
        }
306
    }
307

308
    #[test]
309
    fn test_proc_symlinks() {
310
        // These symlinks already exist on any Linux system.
311
        // ln() is idempotent - returns Ok if already correct.
312
        require_root();
313
        assert!(proc_symlinks().is_ok());
314
    }
315

316
    #[test]
317
    fn test_device_nodes() {
318
        // mknod() removes existing nodes first, then recreates.
319
        // Safe: just recreates /dev/null, /dev/zero, etc. with same params.
320
        require_root();
321
        assert!(device_nodes().is_ok());
322
    }
323

324
    // === setup() is dangerous - mounts filesystems ===
325
    // Only test in ephemeral VMs, not on development machines.
326
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc