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

NVIDIA / nvrc / 20940321460

13 Jan 2026 12:45AM UTC coverage: 89.229% (-0.8%) from 90.078%
20940321460

push

github

web-flow
Merge pull request #121 from zvonkok/execute-hardened

hardened_std: Implement execute hardened

156 of 171 new or added lines in 6 files covered. (91.23%)

58 existing lines in 6 files now uncovered.

1806 of 2024 relevant lines covered (89.23%)

16.79 hits per line

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

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

4
use anyhow::{anyhow, Result};
5
use hardened_std::fs::{self, File, OpenOptions};
6
use std::sync::Once;
7

8
static KERNLOG_INIT: Once = Once::new();
9

10
/// Socket buffer size (16MB = 16 * 1024 * 1024 = 16777216 bytes).
11
/// Large buffers prevent message loss during high-throughput GPU operations
12
/// where NVIDIA drivers may emit bursts of diagnostic data.
13
const SOCKET_BUFFER_SIZE: &str = "16777216";
14

15
/// Initialize kernel logging and tune socket buffer sizes.
16
/// Large buffers (16MB) prevent message loss during high-throughput GPU operations
17
/// where drivers may emit bursts of diagnostic data.
18
pub fn kernlog_setup() -> Result<()> {
2✔
19
    KERNLOG_INIT.call_once(|| {
2✔
20
        let _ = kernlog::init();
2✔
21
    });
2✔
22
    log::set_max_level(log::LevelFilter::Off);
2✔
23
    for path in [
8✔
24
        "/proc/sys/net/core/rmem_default",
25
        "/proc/sys/net/core/wmem_default",
2✔
26
        "/proc/sys/net/core/rmem_max",
2✔
27
        "/proc/sys/net/core/wmem_max",
2✔
28
    ] {
29
        fs::write(path, SOCKET_BUFFER_SIZE.as_bytes())
8✔
30
            .map_err(|e| anyhow!("write {}: {}", path, e))?;
8✔
31
    }
32
    Ok(())
2✔
33
}
2✔
34

35
/// Get a file handle for kernel message output.
36
/// Routes to /dev/kmsg when debug logging is enabled for visibility in dmesg,
37
/// otherwise /dev/null to suppress noise in production.
38
pub fn kmsg() -> Result<File> {
122✔
39
    kmsg_at(if log_enabled!(log::Level::Debug) {
122✔
40
        "/dev/kmsg"
2✔
41
    } else {
42
        "/dev/null"
120✔
43
    })
44
}
122✔
45

46
/// Internal: open the given path for writing. Extracted for testability.
47
fn kmsg_at(path: &str) -> Result<File> {
128✔
48
    OpenOptions::new()
128✔
49
        .write(true)
128✔
50
        .open(path)
128✔
51
        .map_err(|e| anyhow!("open {}: {}", path, e))
128✔
52
}
128✔
53

54
#[cfg(test)]
55
mod tests {
56
    use super::*;
57
    use crate::test_utils::require_root;
58
    use serial_test::serial;
59
    use tempfile::NamedTempFile;
60

61
    #[test]
62
    fn test_kmsg_at_dev_null() {
2✔
63
        // /dev/null is always writable, no root needed
64
        let file = kmsg_at("/dev/null");
2✔
65
        assert!(file.is_ok());
2✔
66
    }
2✔
67

68
    #[test]
69
    fn test_kmsg_at_nonexistent() {
2✔
70
        let err = kmsg_at("/nonexistent/path").unwrap_err();
2✔
71
        // Should contain the path in the error context
72
        assert!(
2✔
73
            err.to_string().contains("/nonexistent/path"),
2✔
74
            "error should mention the path: {}",
×
75
            err
76
        );
77
    }
2✔
78

79
    #[test]
80
    fn test_kmsg_at_temp_file() {
2✔
81
        // Create a temp file to verify we can actually write to it
82
        let temp = NamedTempFile::new().unwrap();
2✔
83
        let path = temp.path().to_str().unwrap();
2✔
84

85
        // Open via kmsg_at
86
        let file = kmsg_at(path).expect("kmsg_at should succeed for temp file");
2✔
87

88
        // Verify we can write to the returned File
89
        // This catches issues where the file handle is invalid or closed
90
        //
91
        // Note: We use unsafe libc::write() instead of std::io::Write because:
92
        // 1. hardened_std::fs::File doesn't implement Write trait (minimalist design)
93
        // 2. This test specifically validates the raw fd is usable, not high-level APIs
94
        // 3. Direct syscall testing ensures fd validity at lowest level
95
        // 4. Catching fd issues that might be hidden by higher-level wrappers
96
        let test_data = b"test write\n";
2✔
97
        let fd = file.as_raw_fd();
2✔
98
        assert!(fd >= 0, "File descriptor should be valid");
2✔
99

100
        // SAFETY: Direct fd write is safe here because:
101
        // 1. fd is valid (came from successful kmsg_at)
102
        // 2. test_data pointer and length are valid
103
        // 3. We don't use fd after this (file owns it)
104
        let write_result = unsafe {
2✔
105
            libc::write(
2✔
106
                fd,
2✔
107
                test_data.as_ptr() as *const libc::c_void,
2✔
108
                test_data.len(),
2✔
109
            )
110
        };
111
        assert_eq!(
2✔
112
            write_result,
113
            test_data.len() as isize,
2✔
UNCOV
114
            "Should write full test data"
×
115
        );
116
    }
2✔
117

118
    #[test]
119
    #[serial]
120
    fn test_kmsg_routes_to_dev_null_when_log_off() {
2✔
121
        // Default log level is Off, so kmsg() should open /dev/null
122
        log::set_max_level(log::LevelFilter::Off);
2✔
123
        let file = kmsg();
2✔
124
        assert!(file.is_ok());
2✔
125
    }
126

127
    #[test]
128
    #[serial]
129
    fn test_kmsg_routes_to_kmsg_when_debug() {
2✔
130
        require_root();
2✔
131
        // When debug is enabled, kmsg() should open /dev/kmsg
132
        log::set_max_level(log::LevelFilter::Debug);
2✔
133
        let file = kmsg();
2✔
134
        assert!(file.is_ok());
2✔
135
        log::set_max_level(log::LevelFilter::Off);
2✔
136
    }
137

138
    #[test]
139
    #[serial]
140
    fn test_kernlog_setup() {
2✔
141
        require_root();
2✔
142

143
        const PATHS: [&str; 4] = [
144
            "/proc/sys/net/core/rmem_default",
145
            "/proc/sys/net/core/wmem_default",
146
            "/proc/sys/net/core/rmem_max",
147
            "/proc/sys/net/core/wmem_max",
148
        ];
149

150
        // RAII guard to restore original values after test
151
        struct Restore(Vec<(&'static str, String)>);
152
        impl Drop for Restore {
153
            fn drop(&mut self) {
2✔
154
                for (path, value) in &self.0 {
10✔
155
                    let _ = std::fs::write(path, value.as_bytes());
8✔
156
                }
8✔
157
            }
2✔
158
        }
159

160
        let saved: Vec<_> = PATHS
2✔
161
            .iter()
2✔
162
            .filter_map(|&p| std::fs::read_to_string(p).ok().map(|v| (p, v)))
8✔
163
            .collect();
2✔
164
        let _restore = Restore(saved);
2✔
165

166
        assert!(kernlog_setup().is_ok());
2✔
167

168
        for &path in &PATHS {
10✔
169
            let v = std::fs::read_to_string(path).expect("should read sysctl");
8✔
170
            assert_eq!(
8✔
171
                v.trim(),
8✔
172
                SOCKET_BUFFER_SIZE,
UNCOV
173
                "sysctl {} should be {}",
×
174
                path,
175
                SOCKET_BUFFER_SIZE
176
            );
177
        }
178
    }
179
}
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