mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Add test to ensure the BatBadBut mitigation handles trailing . and space safely
Context: - https://blog.rust-lang.org/2024/09/04/cve-2024-43402.html - https://github.com/rust-lang/rust/pull/129962 Note that the Rust test case for this checks that it executes the batch file successfully with the proper mitigation in place, while the Zig test case expects a FileNotFound error. This is because of a PATHEXT optimization that Zig does, and that Rust doesn't do because Rust doesn't do PATHEXT appending (it only appends .exe specifically). See the added comment for more details.
This commit is contained in:
parent
2210c4c360
commit
63014d3819
1 changed files with 25 additions and 0 deletions
|
|
@ -73,6 +73,31 @@ pub fn main() anyerror!void {
|
|||
try testExec(allocator, &.{ "\"hello^\"world\"", "hello &echo oh no >file.txt" }, null);
|
||||
try testExec(allocator, &.{"&whoami.exe"}, null);
|
||||
|
||||
// Ensure that trailing space and . characters can't lead to unexpected bat/cmd script execution.
|
||||
// In many Windows APIs (including CreateProcess), trailing space and . characters are stripped
|
||||
// from paths, so if a path with trailing . and space character(s) is passed directly to
|
||||
// CreateProcess, then it could end up executing a batch/cmd script that naive extension detection
|
||||
// would not flag as .bat/.cmd.
|
||||
//
|
||||
// Note that we expect an error here, though, which *is* a valid mitigation, but also an implementation detail.
|
||||
// This error is caused by the use of a wildcard with NtQueryDirectoryFile to optimize PATHEXT searching. That is,
|
||||
// the trailing characters in the app name will lead to a FileNotFound error as the wildcard-appended path will not
|
||||
// match any real paths on the filesystem (e.g. `foo.bat .. *` will not match `foo.bat`; only `foo.bat*` will).
|
||||
//
|
||||
// This being an error matches the behavior of running a command via the command line of cmd.exe, too:
|
||||
//
|
||||
// > "args1.bat .. "
|
||||
// '"args1.bat .. "' is not recognized as an internal or external command,
|
||||
// operable program or batch file.
|
||||
try std.testing.expectError(error.FileNotFound, testExecBat(allocator, "args1.bat .. ", &.{"abc"}, null));
|
||||
const absolute_with_trailing = blk: {
|
||||
const absolute_path = try std.fs.realpathAlloc(allocator, "args1.bat");
|
||||
defer allocator.free(absolute_path);
|
||||
break :blk try std.mem.concat(allocator, u8, &.{ absolute_path, " .. " });
|
||||
};
|
||||
defer allocator.free(absolute_with_trailing);
|
||||
try std.testing.expectError(error.FileNotFound, testExecBat(allocator, absolute_with_trailing, &.{"abc"}, null));
|
||||
|
||||
var env = env: {
|
||||
var env = try std.process.getEnvMap(allocator);
|
||||
errdefer env.deinit();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue