about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-04 17:30:11 +0000
committerbors <bors@rust-lang.org>2024-09-04 17:30:11 +0000
commit4ac7bcbaad8d6fd7a51bdf1b696cbc3ba4c796cf (patch)
tree21afa0f343996010318c87881ef991be57e29349
parent842d6fc32e3d0d26bb11fbe6a2f6ae2afccc06cb (diff)
parentc811d3126f87930b3de3c9e5e7b8d37e9d9d0cae (diff)
downloadrust-4ac7bcbaad8d6fd7a51bdf1b696cbc3ba4c796cf.tar.gz
rust-4ac7bcbaad8d6fd7a51bdf1b696cbc3ba4c796cf.zip
Auto merge of #129962 - pietroalbini:pa-cve-2024-43402-nightly, r=Amanieu
[nightly] Fix CVE-2024-43402

Include the for CVE-2024-43402 in nightly. See [GHSA-2xg3-7mm6-98jj](https://github.com/rust-lang/rust/security/advisories/GHSA-2xg3-7mm6-98jj) for more information about it.

r? `@ghost`
-rw-r--r--library/std/src/sys/pal/windows/mod.rs2
-rw-r--r--library/std/src/sys/pal/windows/process.rs23
-rw-r--r--library/std/src/sys/path/windows.rs5
-rw-r--r--tests/ui/std/windows-bat-args.rs4
4 files changed, 27 insertions, 7 deletions
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 272fadd9150..1cc9a2b7ffa 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -13,7 +13,7 @@ use crate::time::Duration;
 #[macro_use]
 pub mod compat;
 
-mod api;
+pub mod api;
 
 pub mod args;
 pub mod c;
diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs
index 06eae5a07b0..d40a537e359 100644
--- a/library/std/src/sys/pal/windows/process.rs
+++ b/library/std/src/sys/pal/windows/process.rs
@@ -272,11 +272,24 @@ impl Command {
             None
         };
         let program = resolve_exe(&self.program, || env::var_os("PATH"), child_paths)?;
-        // Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
-        let is_batch_file = matches!(
-            program.len().checked_sub(5).and_then(|i| program.get(i..)),
-            Some([46, 98 | 66, 97 | 65, 116 | 84, 0] | [46, 99 | 67, 109 | 77, 100 | 68, 0])
-        );
+        let has_bat_extension = |program: &[u16]| {
+            matches!(
+                // Case insensitive "ends_with" of UTF-16 encoded ".bat" or ".cmd"
+                program.len().checked_sub(4).and_then(|i| program.get(i..)),
+                Some([46, 98 | 66, 97 | 65, 116 | 84] | [46, 99 | 67, 109 | 77, 100 | 68])
+            )
+        };
+        let is_batch_file = if path::is_verbatim(&program) {
+            has_bat_extension(&program[..program.len() - 1])
+        } else {
+            super::fill_utf16_buf(
+                |buffer, size| unsafe {
+                    // resolve the path so we can test the final file name.
+                    c::GetFullPathNameW(program.as_ptr(), size, buffer, ptr::null_mut())
+                },
+                |program| has_bat_extension(program),
+            )?
+        };
         let (program, mut cmd_str) = if is_batch_file {
             (
                 command_prompt()?,
diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs
index 21841eb18cc..2ae9a0a9199 100644
--- a/library/std/src/sys/path/windows.rs
+++ b/library/std/src/sys/path/windows.rs
@@ -1,5 +1,6 @@
 use crate::ffi::{OsStr, OsString};
 use crate::path::{Path, PathBuf, Prefix};
+use crate::sys::api::utf16;
 use crate::sys::pal::{c, fill_utf16_buf, os2path, to_u16s};
 use crate::{io, ptr};
 
@@ -19,6 +20,10 @@ pub fn is_verbatim_sep(b: u8) -> bool {
     b == b'\\'
 }
 
+pub fn is_verbatim(path: &[u16]) -> bool {
+    path.starts_with(utf16!(r"\\?\")) || path.starts_with(utf16!(r"\??\"))
+}
+
 /// Returns true if `path` looks like a lone filename.
 pub(crate) fn is_file_name(path: &OsStr) -> bool {
     !path.as_encoded_bytes().iter().copied().any(is_sep_byte)
diff --git a/tests/ui/std/windows-bat-args.rs b/tests/ui/std/windows-bat-args.rs
index a9b6252b78c..cc4a43692ab 100644
--- a/tests/ui/std/windows-bat-args.rs
+++ b/tests/ui/std/windows-bat-args.rs
@@ -32,7 +32,9 @@ fn parent() {
     let bat2 = String::from(bat.to_str().unwrap());
     bat.set_file_name("windows-bat-args3.bat");
     let bat3 = String::from(bat.to_str().unwrap());
-    let bat = [bat1.as_str(), bat2.as_str(), bat3.as_str()];
+    bat.set_file_name("windows-bat-args1.bat .. ");
+    let bat4 = String::from(bat.to_str().unwrap());
+    let bat = [bat1.as_str(), bat2.as_str(), bat3.as_str(), bat4.as_str()];
 
     check_args(&bat, &["a", "b"]).unwrap();
     check_args(&bat, &["c is for cat", "d is for dog"]).unwrap();