From f096185f3a2369f19971ccc6e5b2fb6030904648 Mon Sep 17 00:00:00 2001 From: zm-oai Date: Wed, 11 Nov 2026 22:12:35 +0000 Subject: [PATCH] Fix Windows atomic writes and refresh build maintenance (#60872) ## What changed - Use `std::fs::rename` for atomic file replacement to support overlapping readers on Windows, retaining temporary-file cleanup if publication fails. - Replace PowerShell fixtures in legacy sandbox capture and ConPTY lifecycle tests with native subprocesses. Keep child markers and output in writable workspaces, prevent inherited capture handles, and use asynchronous waits in ConPTY tests. - Update the Bazel `rules_rs` Linux zlib package pins and mirrors. - Temporarily exempt four `hickory-proto` advisories in `cargo-audit` and `cargo-deny`, with removal tied to upgrading Rust to 1.96+ and Rama to use `hickory-proto` 0.26.2 or later. GitOrigin-RevId: 23d10a023014cc16c100480d1e8bfc2ec87085e3 --- MODULE.bazel | 1 + codex-rs/.cargo/audit.toml | 6 + codex-rs/deny.toml | 6 + codex-rs/ext/history-notes/src/tools_tests.rs | 3 +- codex-rs/utils/path-utils/src/lib.rs | 8 +- .../src/unified_exec/tests.rs | 206 +++++++++++------- patches/BUILD.bazel | 1 + patches/rules_rs_zlib_snapshot_urls.patch | 33 +++ 8 files changed, 184 insertions(+), 80 deletions(-) create mode 100644 patches/rules_rs_zlib_snapshot_urls.patch diff --git a/MODULE.bazel b/MODULE.bazel index 06405ca6fb..8b2726b8dd 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -217,6 +217,7 @@ archive_override( "//patches:rules_rs_build_script_deps_annotation.patch", "//patches:rules_rs_rust_debug_modes.patch", "//patches:rules_rs_workspace_package_version.patch", + "//patches:rules_rs_zlib_snapshot_urls.patch", ], strip_prefix = "rules_rs-7a05511772a8a85db5382ff7536bf2f1e6a8dde3", urls = ["https://github.com/hermeticbuild/rules_rs/archive/7a05511772a8a85db5382ff7536bf2f1e6a8dde3.tar.gz"], diff --git a/codex-rs/.cargo/audit.toml b/codex-rs/.cargo/audit.toml index 04183859b4..5a0ebedb48 100644 --- a/codex-rs/.cargo/audit.toml +++ b/codex-rs/.cargo/audit.toml @@ -10,6 +10,12 @@ ignore = [ "RUSTSEC-2025-0141", # bincode via syntect; remove when syntect drops or updates it "RUSTSEC-2026-0118", # hickory-proto via rama-dns/rama-tcp; remove when rama updates to hickory 0.26.1 or hickory-net "RUSTSEC-2026-0119", # hickory-proto via rama-dns/rama-tcp; remove when rama updates to hickory 0.26.1 or hickory-net + # TODO(ioanbudea): after upgrading Rust to 1.96+, upgrade Rama to use + # hickory-proto >=0.26.2 and remove these temporary exceptions. + "RUSTSEC-2026-0487", # hickory-proto 0.25.2 via rama-dns/rama-tcp; remove after the Rust/Rama upgrade to hickory-proto >=0.26.2 + "RUSTSEC-2026-0489", # hickory-proto 0.25.2 via rama-dns/rama-tcp; remove after the Rust/Rama upgrade to hickory-proto >=0.26.2 + "RUSTSEC-2026-0490", # hickory-proto 0.25.2 via rama-dns/rama-tcp; remove after the Rust/Rama upgrade to hickory-proto >=0.26.2 + "RUSTSEC-2026-0491", # hickory-proto 0.25.2 via rama-dns/rama-tcp; remove after the Rust/Rama upgrade to hickory-proto >=0.26.2 "RUSTSEC-2026-0194", # quick-xml via plist/syntect and wayland-scanner; trusted inputs only; remove when rust-plist#191 and wayland-rs#938 are released "RUSTSEC-2026-0195", # quick-xml via plist/syntect and wayland-scanner; trusted inputs only; remove when rust-plist#191 and wayland-rs#938 are released "RUSTSEC-2026-0370", # zvariant 4.2.0 via zbus 4.4.0 in Linux TUI and keyring/secret-service; remove when those paths migrate off the retired standalone crates diff --git a/codex-rs/deny.toml b/codex-rs/deny.toml index a2f5825c24..ac92c62c0f 100644 --- a/codex-rs/deny.toml +++ b/codex-rs/deny.toml @@ -81,6 +81,12 @@ ignore = [ { id = "RUSTSEC-2025-0141", reason = "bincode is unmaintained; pulled in via syntect v5.3.0 used by codex-tui for syntax highlighting; no fixed release yet" }, { id = "RUSTSEC-2026-0118", reason = "hickory-proto v0.25.2 is pulled in via rama-dns/rama-tcp used by codex-network-proxy; DNSSEC features are not enabled; remove when rama updates to hickory 0.26.1 or hickory-net" }, { id = "RUSTSEC-2026-0119", reason = "hickory-proto v0.25.2 is pulled in via rama-dns/rama-tcp used by codex-network-proxy; no fixed rama release is available yet; remove when rama updates to hickory 0.26.1 or hickory-net" }, + # TODO(ioanbudea): after upgrading Rust to 1.96+, upgrade Rama to use + # hickory-proto >=0.26.2 and remove these temporary exceptions. + { id = "RUSTSEC-2026-0487", reason = "hickory-proto 0.25.2 via rama-dns/rama-tcp in codex-network-proxy; temporarily accepted until the Rust toolchain and Rama upgrade brings hickory-proto >=0.26.2" }, + { id = "RUSTSEC-2026-0489", reason = "hickory-proto 0.25.2 via rama-dns/rama-tcp in codex-network-proxy; temporarily accepted until the Rust toolchain and Rama upgrade brings hickory-proto >=0.26.2" }, + { id = "RUSTSEC-2026-0490", reason = "hickory-proto 0.25.2 via rama-dns/rama-tcp in codex-network-proxy; temporarily accepted until the Rust toolchain and Rama upgrade brings hickory-proto >=0.26.2" }, + { id = "RUSTSEC-2026-0491", reason = "hickory-proto 0.25.2 via rama-dns/rama-tcp in codex-network-proxy; temporarily accepted until the Rust toolchain and Rama upgrade brings hickory-proto >=0.26.2" }, { id = "RUSTSEC-2026-0194", reason = "quick-xml v0.39.4 remains via plist/syntect and wayland-scanner; plist does not exercise the affected APIs and wayland-scanner parses trusted build-time XML; remove when rust-plist#191 and wayland-rs#938 are released" }, { id = "RUSTSEC-2026-0195", reason = "quick-xml v0.39.4 remains via plist/syntect and wayland-scanner; plist does not exercise the affected APIs and wayland-scanner parses trusted build-time XML; remove when rust-plist#191 and wayland-rs#938 are released" }, { id = "RUSTSEC-2026-0370", reason = "zvariant 4.2.0 is unmaintained; pulled in via zbus 4.4.0 by Linux TUI accessibility integration and keyring/secret-service; remove when those paths migrate off the retired standalone crates" }, diff --git a/codex-rs/ext/history-notes/src/tools_tests.rs b/codex-rs/ext/history-notes/src/tools_tests.rs index ea5429770e..67d3ee5d62 100644 --- a/codex-rs/ext/history-notes/src/tools_tests.rs +++ b/codex-rs/ext/history-notes/src/tools_tests.rs @@ -182,6 +182,7 @@ fn sparse_catalog_messages_preserve_defaults_and_explicit_empty_descriptions() { #[test] fn bundled_tool_contracts() { - let specs = super::HistoryNotesAction::ALL.map(|action| action.spec(None, None)); + let specs = super::HistoryNotesAction::ALL + .map(|action| action.spec(/*history_messages*/ None, /*notes_messages*/ None)); insta::assert_snapshot!(serde_json::to_string_pretty(&specs).unwrap()); } diff --git a/codex-rs/utils/path-utils/src/lib.rs b/codex-rs/utils/path-utils/src/lib.rs index 028e4dea76..118876d183 100644 --- a/codex-rs/utils/path-utils/src/lib.rs +++ b/codex-rs/utils/path-utils/src/lib.rs @@ -161,7 +161,13 @@ pub fn write_atomically(write_path: &Path, contents: &str) -> io::Result<()> { std::fs::create_dir_all(parent)?; let mut tmp = NamedTempFile::new_in(parent)?; tmp.write_all(contents.as_bytes())?; - tmp.persist(write_path)?; + // Match credential-file replacement: std::fs::rename supports overlapping + // readers on Windows, while tempfile::persist's MoveFileExW does not. + // Clear the temporary attribute and retain cleanup if publication fails. + let (_file, path) = tmp.keep().map_err(|error| error.error)?; + let mut path = tempfile::TempPath::try_from_path(path)?; + std::fs::rename(&path, write_path)?; + path.disable_cleanup(/*disable_cleanup*/ true); Ok(()) } diff --git a/codex-rs/windows-sandbox-rs/src/unified_exec/tests.rs b/codex-rs/windows-sandbox-rs/src/unified_exec/tests.rs index f3c43cee8d..d69aa0f632 100644 --- a/codex-rs/windows-sandbox-rs/src/unified_exec/tests.rs +++ b/codex-rs/windows-sandbox-rs/src/unified_exec/tests.rs @@ -28,6 +28,7 @@ use std::os::windows::io::FromRawHandle; use std::os::windows::io::OwnedHandle; use std::path::Path; use std::path::PathBuf; +use std::process::Stdio; use std::sync::Arc; use std::sync::Mutex; use std::sync::MutexGuard; @@ -41,9 +42,17 @@ use tokio::sync::broadcast; use tokio::sync::mpsc; use tokio::sync::oneshot; use tokio::time::timeout; +use windows_sys::Win32::Foundation::HANDLE_FLAG_INHERIT; +use windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE; +use windows_sys::Win32::Foundation::SetHandleInformation; use windows_sys::Win32::Foundation::WAIT_FAILED; use windows_sys::Win32::Foundation::WAIT_OBJECT_0; use windows_sys::Win32::Foundation::WAIT_TIMEOUT; +use windows_sys::Win32::System::Console::GetConsoleWindow; +use windows_sys::Win32::System::Console::GetStdHandle; +use windows_sys::Win32::System::Console::STD_ERROR_HANDLE; +use windows_sys::Win32::System::Console::STD_INPUT_HANDLE; +use windows_sys::Win32::System::Console::STD_OUTPUT_HANDLE; use windows_sys::Win32::System::Threading::OpenProcess; use windows_sys::Win32::System::Threading::PROCESS_SYNCHRONIZE; use windows_sys::Win32::System::Threading::WaitForSingleObject; @@ -51,6 +60,10 @@ use windows_sys::Win32::System::Threading::WaitForSingleObject; static TEST_HOME_COUNTER: AtomicU64 = AtomicU64::new(0); static LEGACY_PROCESS_TEST_LOCK: Mutex<()> = Mutex::new(()); +const LEGACY_FIXTURE_ROLE: &str = "CODEX_TEST_LEGACY_PROCESS_ROLE"; +const LEGACY_FIXTURE_TEST: &str = + "unified_exec::tests::legacy_capture_emits_output_and_preserves_descendant_after_normal_exit"; + const ASSERT_NO_CONSOLE: &str = r#"Add-Type -ErrorAction Stop 'using System; using System.Runtime.InteropServices; public class ConsoleProbe { [DllImport("kernel32.dll")] public static extern IntPtr GetConsoleWindow(); }'; if ([ConsoleProbe]::GetConsoleWindow() -ne [IntPtr]::Zero) { throw 'piped sandbox process unexpectedly has a console' };"#; fn legacy_process_test_guard() -> MutexGuard<'static, ()> { @@ -135,6 +148,17 @@ fn wait_for_path(path: &Path, timeout: Duration) -> bool { path.exists() } +async fn wait_for_path_async(path: &Path, wait: Duration) -> bool { + // Let the single-threaded runtime continue driving the process session. + timeout(wait, async { + while !path.exists() { + tokio::time::sleep(Duration::from_millis(25)).await; + } + }) + .await + .is_ok() +} + fn open_process_for_wait(pid: u32) -> std::io::Result { let handle = unsafe { OpenProcess(PROCESS_SYNCHRONIZE, 0, pid) }; if handle.is_null() { @@ -662,49 +686,91 @@ fn runner_resizer_sends_resize_frame() { }); } +fn run_legacy_process_fixture(role: &str) { + let cwd = std::env::current_dir().expect("fixture cwd"); + let ready = cwd.join("descendant-started"); + if role == "child" { + assert!(unsafe { GetConsoleWindow() }.is_null()); + let temporary = cwd.join("descendant-started.tmp"); + fs::write(&temporary, std::process::id().to_string()).expect("write child PID"); + fs::rename(temporary, ready).expect("publish child PID"); + assert!(wait_for_path( + &cwd.join("release-descendant"), + Duration::from_secs(30) + )); + fs::write(cwd.join("descendant-survived"), "survived").expect("write survival marker"); + return; + } + assert!(matches!(role, "capture" | "preserve" | "terminate")); + if role == "capture" { + assert!(unsafe { GetConsoleWindow() }.is_null()); + } + // This is an isolated fixture process. Do not let the child retain the + // root's capture pipes or ConPTY handles alongside its explicit file stdio. + // Otherwise EOF cannot arrive until the child that our caller releases exits. + for id in [STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE] { + let handle = unsafe { GetStdHandle(id) }; + if !handle.is_null() && handle != INVALID_HANDLE_VALUE { + assert_ne!( + unsafe { SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0) }, + 0 + ); + } + } + let child = codex_utils_process::background_command( + std::env::current_exe().expect("fixture executable"), + ) + .args(["--exact", LEGACY_FIXTURE_TEST, "--nocapture"]) + .env(LEGACY_FIXTURE_ROLE, "child") + .stdin(Stdio::null()) + .stdout(fs::File::create(cwd.join("descendant.stdout")).expect("child stdout")) + .stderr(fs::File::create(cwd.join("descendant.stderr")).expect("child stderr")) + .spawn() + .expect("spawn fixture descendant"); + drop(child); // Closing a process handle must not terminate the descendant. + assert!(wait_for_path(&ready, Duration::from_secs(10))); + println!("LEGACY-CAPTURE-DIRECT"); + if role == "terminate" { + std::thread::sleep(Duration::from_secs(30)); + } +} + #[test] fn legacy_capture_emits_output_and_preserves_descendant_after_normal_exit() { - let Some(pwsh) = pwsh_path() else { + if let Ok(role) = std::env::var(LEGACY_FIXTURE_ROLE) { + run_legacy_process_fixture(&role); return; - }; + } let _guard = legacy_process_test_guard(); - let cwd = sandbox_cwd(); - let codex_home = sandbox_home("legacy-capture-pwsh"); - println!("capture pwsh codex_home={}", codex_home.path().display()); - let ready_marker = codex_home.path().join("descendant-started"); - let release_marker = codex_home.path().join("release-descendant"); - let survival_marker = codex_home.path().join("descendant-survived"); - let descendant_command = format!( - "$deadline=(Get-Date).AddSeconds(30); Set-Content -LiteralPath '{}' -Value $PID; while (-not (Test-Path -LiteralPath '{}')) {{ if ((Get-Date) -ge $deadline) {{ exit 3 }}; Start-Sleep -Milliseconds 25 }}; Set-Content -LiteralPath '{}' -Value survived", - powershell_literal(&ready_marker), - powershell_literal(&release_marker), - powershell_literal(&survival_marker), - ); - let parent_tail = format!( - "while (-not (Test-Path -LiteralPath '{}')) {{ Start-Sleep -Milliseconds 25 }}", - powershell_literal(&ready_marker), - ); - let parent_command = format!( - "{ASSERT_NO_CONSOLE} Write-Output LEGACY-CAPTURE-DIRECT; {}", - start_powershell_child(&pwsh, codex_home.path(), &descendant_command, &parent_tail,), - ); + // Child-owned markers and redirected output belong in the writable workspace, + // not the protected Codex home used for sandbox control state. + let workspace = tempfile::tempdir().expect("create sandbox workspace"); + let cwd = workspace.path().to_path_buf(); + let codex_home = sandbox_home("legacy-capture-native"); + println!("capture native codex_home={}", codex_home.path().display()); + let ready_marker = cwd.join("descendant-started"); + let release_marker = cwd.join("release-descendant"); + let survival_marker = cwd.join("descendant-survived"); let permission_profile = PermissionProfile::workspace_write(); let result = run_windows_sandbox_capture( &permission_profile, workspace_roots_for(cwd.as_path()).as_slice(), codex_home.path(), vec![ - pwsh.display().to_string(), - "-NoProfile".to_string(), - "-Command".to_string(), - parent_command, + std::env::current_exe() + .expect("fixture executable") + .display() + .to_string(), + "--exact".to_string(), + LEGACY_FIXTURE_TEST.to_string(), + "--nocapture".to_string(), ], cwd.as_path(), - HashMap::new(), + HashMap::from([(LEGACY_FIXTURE_ROLE.to_string(), "capture".to_string())]), Some(10_000), /*cancellation*/ None, ) - .expect("run legacy capture powershell"); + .expect("run legacy capture fixture"); let descendant_pid = fs::read_to_string(&ready_marker) .expect("read descendant pid") .trim() @@ -714,11 +780,11 @@ fn legacy_capture_emits_output_and_preserves_descendant_after_normal_exit() { fs::write(&release_marker, "release").expect("release descendant after root exit"); let descendant_process = descendant_process.expect("open descendant after normal capture exit"); - println!("capture pwsh exit_code={}", result.exit_code); - println!("capture pwsh timed_out={}", result.timed_out); + println!("capture native exit_code={}", result.exit_code); + println!("capture native timed_out={}", result.timed_out); let stdout = String::from_utf8_lossy(&result.stdout); let stderr = String::from_utf8_lossy(&result.stderr); - println!("capture pwsh stderr={stderr:?}"); + println!("capture native stderr={stderr:?}"); assert_eq!(result.exit_code, 0, "stdout={stdout:?} stderr={stderr:?}"); assert!( stdout.contains("LEGACY-CAPTURE-DIRECT"), @@ -852,10 +918,13 @@ fn legacy_capture_cancellation_terminates_descendants_without_timeout() { return; }; let _guard = legacy_process_test_guard(); - let cwd = sandbox_cwd(); + // Child-owned markers and redirected output belong in the writable workspace, + // not the protected Codex home used for sandbox control state. + let workspace = tempfile::tempdir().expect("create sandbox workspace"); + let cwd = workspace.path().to_path_buf(); let codex_home = sandbox_home("legacy-capture-cancel"); - let descendant_marker = codex_home.path().join("descendant-survived"); - let ready_marker = codex_home.path().join("descendant-started"); + let descendant_marker = cwd.join("descendant-survived"); + let ready_marker = cwd.join("descendant-started"); let descendant_command = format!( "Set-Content -LiteralPath '{}' -Value $PID; Start-Sleep -Seconds 1; Set-Content -LiteralPath '{}' -Value survived", powershell_literal(&ready_marker), @@ -863,7 +932,7 @@ fn legacy_capture_cancellation_terminates_descendants_without_timeout() { ); let parent_command = start_powershell_child( &pwsh, - codex_home.path(), + cwd.as_path(), &descendant_command, "Start-Sleep -Seconds 30", ); @@ -933,62 +1002,48 @@ enum LegacyTtyDescendantLifecycle { Preserve, } -async fn assert_legacy_tty_descendant_lifecycle( - pwsh: &Path, - lifecycle: LegacyTtyDescendantLifecycle, -) { - let cwd = sandbox_cwd(); +async fn assert_legacy_tty_descendant_lifecycle(lifecycle: LegacyTtyDescendantLifecycle) { + // Child-owned markers and redirected output belong in the writable workspace, + // not the protected Codex home used for sandbox control state. + let workspace = tempfile::tempdir().expect("create sandbox workspace"); + let cwd = workspace.path().to_path_buf(); let codex_home = sandbox_home(match lifecycle { LegacyTtyDescendantLifecycle::Terminate => "legacy-tty-descendant-terminate", LegacyTtyDescendantLifecycle::Preserve => "legacy-tty-descendant-preserve", }); - let ready_marker = codex_home.path().join("descendant-started"); - let release_marker = codex_home.path().join("release-descendant"); - let survival_marker = codex_home.path().join("descendant-survived"); - let child_tail = match lifecycle { - LegacyTtyDescendantLifecycle::Terminate => "Start-Sleep -Seconds 30".to_string(), - LegacyTtyDescendantLifecycle::Preserve => format!( - "$deadline=(Get-Date).AddSeconds(30); while (-not (Test-Path -LiteralPath '{}')) {{ if ((Get-Date) -ge $deadline) {{ exit 3 }}; Start-Sleep -Milliseconds 25 }}; Set-Content -LiteralPath '{}' -Value survived", - powershell_literal(&release_marker), - powershell_literal(&survival_marker), - ), + let ready_marker = cwd.join("descendant-started"); + let release_marker = cwd.join("release-descendant"); + let survival_marker = cwd.join("descendant-survived"); + let role = match lifecycle { + LegacyTtyDescendantLifecycle::Terminate => "terminate", + LegacyTtyDescendantLifecycle::Preserve => "preserve", }; - let child_command = format!( - "Set-Content -LiteralPath '{}' -Value $PID; {child_tail}", - powershell_literal(&ready_marker), - ); - let parent_tail = match lifecycle { - LegacyTtyDescendantLifecycle::Terminate => "Start-Sleep -Seconds 30".to_string(), - LegacyTtyDescendantLifecycle::Preserve => format!( - "while (-not (Test-Path -LiteralPath '{}')) {{ Start-Sleep -Milliseconds 25 }}", - powershell_literal(&ready_marker), - ), - }; - let parent_command = - start_powershell_child(pwsh, codex_home.path(), &child_command, &parent_tail); let permission_profile = PermissionProfile::workspace_write(); let spawned = spawn_windows_sandbox_session_legacy( &permission_profile, workspace_roots_for(cwd.as_path()).as_slice(), codex_home.path(), vec![ - pwsh.display().to_string(), - "-NoProfile".to_string(), - "-Command".to_string(), - parent_command, + std::env::current_exe() + .expect("fixture executable") + .display() + .to_string(), + "--exact".to_string(), + LEGACY_FIXTURE_TEST.to_string(), + "--nocapture".to_string(), ], cwd.as_path(), - HashMap::new(), + HashMap::from([(LEGACY_FIXTURE_ROLE.to_string(), role.to_string())]), Some(30_000), &[], &[], /*tty*/ true, - /*stdin_open*/ false, + /*stdin_open*/ true, ) .await .expect("spawn legacy sandbox ConPTY lifecycle test"); assert!( - wait_for_path(&ready_marker, Duration::from_secs(10)), + wait_for_path_async(&ready_marker, Duration::from_secs(10)).await, "{lifecycle:?} descendant did not start" ); let descendant_pid = fs::read_to_string(&ready_marker) @@ -1013,7 +1068,7 @@ async fn assert_legacy_tty_descendant_lifecycle( LegacyTtyDescendantLifecycle::Preserve => { assert_eq!(exit_code, 0); assert!( - wait_for_path(&survival_marker, Duration::from_secs(10)), + wait_for_path_async(&survival_marker, Duration::from_secs(10)).await, "sandbox ConPTY descendant did not survive normal exit" ); } @@ -1024,15 +1079,10 @@ async fn assert_legacy_tty_descendant_lifecycle( #[test] fn legacy_tty_job_terminates_and_preserves_descendants() { - let Some(pwsh) = pwsh_path() else { - eprintln!("skipping sandbox ConPTY lifecycle test: PowerShell 7 is not installed"); - return; - }; let _guard = legacy_process_test_guard(); current_thread_runtime().block_on(async move { - assert_legacy_tty_descendant_lifecycle(&pwsh, LegacyTtyDescendantLifecycle::Terminate) - .await; - assert_legacy_tty_descendant_lifecycle(&pwsh, LegacyTtyDescendantLifecycle::Preserve).await; + assert_legacy_tty_descendant_lifecycle(LegacyTtyDescendantLifecycle::Terminate).await; + assert_legacy_tty_descendant_lifecycle(LegacyTtyDescendantLifecycle::Preserve).await; }); } diff --git a/patches/BUILD.bazel b/patches/BUILD.bazel index 6fad1f052b..bbd272c4b2 100644 --- a/patches/BUILD.bazel +++ b/patches/BUILD.bazel @@ -18,6 +18,7 @@ exports_files([ "rules_rs_build_script_deps_annotation.patch", "rules_rs_rust_debug_modes.patch", "rules_rs_workspace_package_version.patch", + "rules_rs_zlib_snapshot_urls.patch", "rusty_v8_prebuilt_out_dir.patch", "ring_windows_msvc_include_dirs.patch", "tikv-jemalloc-sys_make_env.patch", diff --git a/patches/rules_rs_zlib_snapshot_urls.patch b/patches/rules_rs_zlib_snapshot_urls.patch new file mode 100644 index 0000000000..a7f0a2d609 --- /dev/null +++ b/patches/rules_rs_zlib_snapshot_urls.patch @@ -0,0 +1,33 @@ +# Backport the Linux zlib package pins and mirrors from rules_rs v0.2.2. +# https://github.com/hermeticbuild/rules_rs/commit/4c3d6ecc8fe94d373b818366ac3c52a31fffa277 + +diff --git a/rs/private/rustc_repository.bzl b/rs/private/rustc_repository.bzl +--- a/rs/private/rustc_repository.bzl ++++ b/rs/private/rustc_repository.bzl +@@ -56,18 +56,20 @@ filegroup( + _LINUX_ZLIB = { + "aarch64": struct( + libdir = "usr/lib/aarch64-linux-gnu", +- sha256 = "e55ab3b4fb7b6edc4a628e28ec13f8780b08abe427d33ae148f030d8586d0e9a", ++ sha256 = "84536bcf440cf0f988899b24b6c7df32cb9ff9f0dfa97d5e7efcc2dc088d15dc", + urls = [ +- "https://launchpad.net/ubuntu/+archive/primary/+files/zlib1g_1.3.dfsg-3.1ubuntu2.2_arm64.deb", +- "https://snapshot.ubuntu.com/ubuntu/20260901T000000Z/pool/main/z/zlib/zlib1g_1.3.dfsg-3.1ubuntu2.2_arm64.deb", ++ "https://ports.ubuntu.com/ubuntu-ports/pool/main/z/zlib/zlib1g_1.3.dfsg-3.1ubuntu2.3_arm64.deb", ++ "https://launchpad.net/ubuntu/+archive/primary/+files/zlib1g_1.3.dfsg-3.1ubuntu2.3_arm64.deb", ++ "https://snapshot.ubuntu.com/ubuntu/20261110T000000Z/pool/main/z/zlib/zlib1g_1.3.dfsg-3.1ubuntu2.3_arm64.deb", + ], + ), + "x86_64": struct( + libdir = "usr/lib/x86_64-linux-gnu", +- sha256 = "84b9cf5752b29c9f92c27cd4c4ba9bbcc70b5ccf9b1b515421a28ae23212e273", ++ sha256 = "376249c8de139568221dbb242318cc8cb8f02299e3a62b7432948e1754fbddf9", + urls = [ +- "https://launchpad.net/ubuntu/+archive/primary/+files/zlib1g_1.3.dfsg-3.1ubuntu2.2_amd64.deb", +- "https://snapshot.ubuntu.com/ubuntu/20260901T000000Z/pool/main/z/zlib/zlib1g_1.3.dfsg-3.1ubuntu2.2_amd64.deb", ++ "https://archive.ubuntu.com/ubuntu/pool/main/z/zlib/zlib1g_1.3.dfsg-3.1ubuntu2.3_amd64.deb", ++ "https://launchpad.net/ubuntu/+archive/primary/+files/zlib1g_1.3.dfsg-3.1ubuntu2.3_amd64.deb", ++ "https://snapshot.ubuntu.com/ubuntu/20261110T000000Z/pool/main/z/zlib/zlib1g_1.3.dfsg-3.1ubuntu2.3_amd64.deb", + ], + ), + }