Skip to content

Commit b3d3204

Browse files
have world_writable_warning_details accept cwd as a param (#6913)
this enables app-server to pass in the correct workspace cwd for the current conversation
1 parent 91a1d20 commit b3d3204

File tree

4 files changed

+48
-38
lines changed

4 files changed

+48
-38
lines changed

codex-rs/app-server/src/message_processor.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,15 @@ impl MessageProcessor {
191191
}
192192

193193
// This function is stubbed out to return None on non-Windows platforms
194+
let cwd = match std::env::current_dir() {
195+
Ok(cwd) => cwd,
196+
Err(_) => return,
197+
};
194198
if let Some((sample_paths, extra_count, failed_scan)) =
195-
codex_windows_sandbox::world_writable_warning_details(self.config.codex_home.as_path())
199+
codex_windows_sandbox::world_writable_warning_details(
200+
self.config.codex_home.as_path(),
201+
cwd,
202+
)
196203
{
197204
self.outgoing
198205
.send_server_notification(ServerNotification::WindowsWorldWritableWarning(

codex-rs/tui/src/chatwidget.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2300,7 +2300,11 @@ impl ChatWidget {
23002300
{
23012301
return None;
23022302
}
2303-
codex_windows_sandbox::world_writable_warning_details(self.config.codex_home.as_path())
2303+
let cwd = match std::env::current_dir() {
2304+
Ok(cwd) => cwd,
2305+
Err(_) => return Some((Vec::new(), 0, true)),
2306+
};
2307+
codex_windows_sandbox::world_writable_warning_details(self.config.codex_home.as_path(), cwd)
23042308
}
23052309

23062310
#[cfg(not(target_os = "windows"))]

codex-rs/windows-sandbox-rs/src/audit.rs

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,35 @@ use std::path::Path;
88
use std::path::PathBuf;
99
use std::time::Duration;
1010
use std::time::Instant;
11+
use windows_sys::Win32::Foundation::CloseHandle;
1112
use windows_sys::Win32::Foundation::LocalFree;
1213
use windows_sys::Win32::Foundation::ERROR_SUCCESS;
1314
use windows_sys::Win32::Foundation::HLOCAL;
15+
use windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE;
1416
use windows_sys::Win32::Security::Authorization::GetNamedSecurityInfoW;
1517
use windows_sys::Win32::Security::Authorization::GetSecurityInfo;
16-
use windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE;
17-
use windows_sys::Win32::Foundation::CloseHandle;
1818
use windows_sys::Win32::Storage::FileSystem::CreateFileW;
19+
use windows_sys::Win32::Storage::FileSystem::FILE_APPEND_DATA;
1920
use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_BACKUP_SEMANTICS;
21+
use windows_sys::Win32::Storage::FileSystem::FILE_GENERIC_WRITE;
2022
use windows_sys::Win32::Storage::FileSystem::FILE_SHARE_DELETE;
2123
use windows_sys::Win32::Storage::FileSystem::FILE_SHARE_READ;
2224
use windows_sys::Win32::Storage::FileSystem::FILE_SHARE_WRITE;
23-
use windows_sys::Win32::Storage::FileSystem::OPEN_EXISTING;
24-
use windows_sys::Win32::Storage::FileSystem::FILE_GENERIC_WRITE;
25+
use windows_sys::Win32::Storage::FileSystem::FILE_WRITE_ATTRIBUTES;
2526
use windows_sys::Win32::Storage::FileSystem::FILE_WRITE_DATA;
26-
use windows_sys::Win32::Storage::FileSystem::FILE_APPEND_DATA;
2727
use windows_sys::Win32::Storage::FileSystem::FILE_WRITE_EA;
28-
use windows_sys::Win32::Storage::FileSystem::FILE_WRITE_ATTRIBUTES;
28+
use windows_sys::Win32::Storage::FileSystem::OPEN_EXISTING;
2929
const GENERIC_ALL_MASK: u32 = 0x1000_0000;
3030
const GENERIC_WRITE_MASK: u32 = 0x4000_0000;
31-
use windows_sys::Win32::Security::ACL;
32-
use windows_sys::Win32::Security::DACL_SECURITY_INFORMATION;
33-
use windows_sys::Win32::Security::ACL_SIZE_INFORMATION;
3431
use windows_sys::Win32::Security::AclSizeInformation;
35-
use windows_sys::Win32::Security::GetAclInformation;
32+
use windows_sys::Win32::Security::EqualSid;
3633
use windows_sys::Win32::Security::GetAce;
34+
use windows_sys::Win32::Security::GetAclInformation;
3735
use windows_sys::Win32::Security::ACCESS_ALLOWED_ACE;
3836
use windows_sys::Win32::Security::ACE_HEADER;
39-
use windows_sys::Win32::Security::EqualSid;
37+
use windows_sys::Win32::Security::ACL;
38+
use windows_sys::Win32::Security::ACL_SIZE_INFORMATION;
39+
use windows_sys::Win32::Security::DACL_SECURITY_INFORMATION;
4040

4141
// Preflight scan limits
4242
const MAX_ITEMS_PER_DIR: i32 = 1000;
@@ -162,7 +162,9 @@ unsafe fn path_has_world_write_allow(path: &Path) -> Result<bool> {
162162
let psid_world = world.as_mut_ptr() as *mut c_void;
163163
// Very fast mask-based check for world-writable grants (includes GENERIC_*).
164164
if !dacl_quick_world_write_mask_allows(p_dacl, psid_world) {
165-
if !p_sd.is_null() { LocalFree(p_sd as HLOCAL); }
165+
if !p_sd.is_null() {
166+
LocalFree(p_sd as HLOCAL);
167+
}
166168
return Ok(false);
167169
}
168170
// Quick detector flagged a write grant for Everyone: treat as writable.
@@ -202,7 +204,9 @@ pub fn audit_everyone_writable(
202204
let has = unsafe { path_has_world_write_allow(&p)? };
203205
if has {
204206
let key = normalize_path_key(&p);
205-
if seen.insert(key) { flagged.push(p); }
207+
if seen.insert(key) {
208+
flagged.push(p);
209+
}
206210
}
207211
}
208212
}
@@ -218,7 +222,9 @@ pub fn audit_everyone_writable(
218222
let has_root = unsafe { path_has_world_write_allow(&root)? };
219223
if has_root {
220224
let key = normalize_path_key(&root);
221-
if seen.insert(key) { flagged.push(root.clone()); }
225+
if seen.insert(key) {
226+
flagged.push(root.clone());
227+
}
222228
}
223229
// one level down best-effort
224230
if let Ok(read) = std::fs::read_dir(&root) {
@@ -240,13 +246,17 @@ pub fn audit_everyone_writable(
240246
// Skip noisy/irrelevant Windows system subdirectories
241247
let pl = p.to_string_lossy().to_ascii_lowercase();
242248
let norm = pl.replace('\\', "/");
243-
if SKIP_DIR_SUFFIXES.iter().any(|s| norm.ends_with(s)) { continue; }
249+
if SKIP_DIR_SUFFIXES.iter().any(|s| norm.ends_with(s)) {
250+
continue;
251+
}
244252
if ft.is_dir() {
245253
checked += 1;
246254
let has_child = unsafe { path_has_world_write_allow(&p)? };
247255
if has_child {
248256
let key = normalize_path_key(&p);
249-
if seen.insert(key) { flagged.push(p); }
257+
if seen.insert(key) {
258+
flagged.push(p);
259+
}
250260
}
251261
}
252262
}
@@ -258,20 +268,12 @@ pub fn audit_everyone_writable(
258268
for p in &flagged {
259269
list.push_str(&format!("\n - {}", p.display()));
260270
}
261-
crate::logging::log_note(
262-
&format!(
263-
"AUDIT: world-writable scan FAILED; checked={checked}; duration_ms={elapsed_ms}; flagged:{}",
264-
list
265-
),
266-
logs_base_dir,
267-
);
271+
268272
return Ok(flagged);
269273
}
270274
// Log success once if nothing flagged
271275
crate::logging::log_note(
272-
&format!(
273-
"AUDIT: world-writable scan OK; checked={checked}; duration_ms={elapsed_ms}"
274-
),
276+
&format!("AUDIT: world-writable scan OK; checked={checked}; duration_ms={elapsed_ms}"),
275277
logs_base_dir,
276278
);
277279
Ok(Vec::new())
@@ -284,14 +286,10 @@ fn normalize_windows_path_for_display(p: impl AsRef<Path>) -> String {
284286

285287
pub fn world_writable_warning_details(
286288
codex_home: impl AsRef<Path>,
289+
cwd: impl AsRef<Path>,
287290
) -> Option<(Vec<String>, usize, bool)> {
288-
let cwd = match std::env::current_dir() {
289-
Ok(cwd) => cwd,
290-
Err(_) => return Some((Vec::new(), 0, true)),
291-
};
292-
293291
let env_map: HashMap<String, String> = std::env::vars().collect();
294-
match audit_everyone_writable(&cwd, &env_map, Some(codex_home.as_ref())) {
292+
match audit_everyone_writable(cwd.as_ref(), &env_map, Some(codex_home.as_ref())) {
295293
Ok(paths) if paths.is_empty() => None,
296294
Ok(paths) => {
297295
let as_strings: Vec<String> = paths
@@ -329,16 +327,16 @@ unsafe fn dacl_quick_world_write_mask_allows(p_dacl: *mut ACL, psid_world: *mut
329327
continue;
330328
}
331329
let hdr = &*(p_ace as *const ACE_HEADER);
332-
if hdr.AceType != 0 { // ACCESS_ALLOWED_ACE_TYPE
330+
if hdr.AceType != 0 {
331+
// ACCESS_ALLOWED_ACE_TYPE
333332
continue;
334333
}
335334
if (hdr.AceFlags & INHERIT_ONLY_ACE) != 0 {
336335
continue;
337336
}
338337
let base = p_ace as usize;
339-
let sid_ptr = (base
340-
+ std::mem::size_of::<ACE_HEADER>()
341-
+ std::mem::size_of::<u32>()) as *mut c_void; // skip header + mask
338+
let sid_ptr =
339+
(base + std::mem::size_of::<ACE_HEADER>() + std::mem::size_of::<u32>()) as *mut c_void; // skip header + mask
342340
if EqualSid(sid_ptr, psid_world) != 0 {
343341
let ace = &*(p_ace as *const ACCESS_ALLOWED_ACE);
344342
let mask = ace.Mask;

codex-rs/windows-sandbox-rs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ mod stub {
467467

468468
pub fn world_writable_warning_details(
469469
_codex_home: impl AsRef<Path>,
470+
_cwd: impl AsRef<Path>,
470471
) -> Option<(Vec<String>, usize, bool)> {
471472
None
472473
}

0 commit comments

Comments
 (0)