terminal: fix use-after-free in exec (#8358)
This was only an issue on Linux, as MacOS' command is reallocated and rewritten. We hit this using embedded Ghostty w/o a login shell :ppull/8368/head
commit
062d596c0a
|
|
@ -1513,7 +1513,8 @@ fn execCommand(
|
|||
}
|
||||
|
||||
return switch (command) {
|
||||
.direct => |v| v,
|
||||
// We need to clone the command since there's no guarantee the config remains valid.
|
||||
.direct => |_| (try command.clone(alloc)).direct,
|
||||
|
||||
.shell => |v| shell: {
|
||||
var args: std.ArrayList([:0]const u8) = try .initCapacity(alloc, 4);
|
||||
|
|
@ -1688,3 +1689,35 @@ test "execCommand: direct command, error passwd" {
|
|||
try testing.expectEqualStrings(result[0], "foo");
|
||||
try testing.expectEqualStrings(result[1], "bar baz");
|
||||
}
|
||||
|
||||
test "execCommand: direct command, config freed" {
|
||||
if (comptime builtin.os.tag == .windows) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
var arena = ArenaAllocator.init(testing.allocator);
|
||||
defer arena.deinit();
|
||||
const alloc = arena.allocator();
|
||||
|
||||
var command_arena = ArenaAllocator.init(alloc);
|
||||
const command_alloc = command_arena.allocator();
|
||||
const command = try (configpkg.Command{
|
||||
.direct = &.{
|
||||
"foo",
|
||||
"bar baz",
|
||||
},
|
||||
}).clone(command_alloc);
|
||||
|
||||
const result = try execCommand(alloc, command, struct {
|
||||
fn get(_: Allocator) !PasswdEntry {
|
||||
// Failed passwd entry means we can't construct a macOS
|
||||
// login command and falls back to POSIX behavior.
|
||||
return error.Fail;
|
||||
}
|
||||
});
|
||||
|
||||
command_arena.deinit();
|
||||
|
||||
try testing.expectEqual(2, result.len);
|
||||
try testing.expectEqualStrings(result[0], "foo");
|
||||
try testing.expectEqualStrings(result[1], "bar baz");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue