diff --git a/src/action_executor.zig b/src/action_executor.zig index 29a208f..9cf93e1 100644 --- a/src/action_executor.zig +++ b/src/action_executor.zig @@ -2110,6 +2110,8 @@ fn createOutputParent(io: std.Io, work_root: std.Io.Dir, path: []const u8) !void fn prepareChrootBaseDirs(io: std.Io, chroot_root: std.Io.Dir) !void { try chroot_root.createDirPath(io, "dev"); + try chroot_root.createDirPath(io, "dev/pts"); + try chroot_root.symLink(io, "pts/ptmx", "dev/ptmx", .{}); try chroot_root.createDirPath(io, "proc"); try chroot_root.createDirPath(io, "tmp"); try chroot_root.createDirPath(io, "var/tmp"); @@ -3641,6 +3643,10 @@ test "prepareChrootBaseDirs creates temporary directories" { defer work_dir.close(std.testing.io); try prepareChrootBaseDirs(std.testing.io, work_dir); + try work_dir.access(std.testing.io, "dev/pts", .{}); + var pseudo_terminal_target: [64]u8 = undefined; + const pseudo_terminal_target_len = try work_dir.readLink(std.testing.io, "dev/ptmx", &pseudo_terminal_target); + try std.testing.expectEqualStrings("pts/ptmx", pseudo_terminal_target[0..pseudo_terminal_target_len]); try work_dir.access(std.testing.io, "tmp", .{}); try work_dir.access(std.testing.io, "var/tmp", .{}); } diff --git a/src/action_runner.zig b/src/action_runner.zig index 0ecbb14..ba74608 100644 --- a/src/action_runner.zig +++ b/src/action_runner.zig @@ -648,6 +648,14 @@ fn forkAction(action: ForkAction) !std.os.linux.pid_t { childSyscallName(linux.chroot(action.chroot_dir.ptr), "chroot"); childSyscallName(linux.chdir("/"), "chdir_root"); childSyscallName(linux.mount("proc", "/proc", "proc", linux.MS.NOSUID | linux.MS.NODEV | linux.MS.NOEXEC, 0), "mount_proc"); + const pseudo_terminal_mount_data: [:0]const u8 = "newinstance,ptmxmode=0666,mode=0620"; + childSyscallName(linux.mount( + "devpts", + "/dev/pts", + "devpts", + linux.MS.NOSUID | linux.MS.NOEXEC, + @intFromPtr(pseudo_terminal_mount_data.ptr), + ), "mount_devpts"); childDropPrivileges(action.sandbox_uid, action.sandbox_gid); childSyscallName(linux.chdir(action.cwd.ptr), "chdir"); childInstallSocketFilter(); diff --git a/vm/linux.config b/vm/linux.config index 69abcd9..44e105b 100644 --- a/vm/linux.config +++ b/vm/linux.config @@ -79,6 +79,7 @@ CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_VSOCKETS=y CONFIG_VSOCKETS=y CONFIG_TTY=y +CONFIG_UNIX98_PTYS=y # CONFIG_BT is not set # CONFIG_EFI_PARTITION is not set # CONFIG_MODULES is not set diff --git a/vm/linux_x86_64.config b/vm/linux_x86_64.config index 278a71f..49413e7 100644 --- a/vm/linux_x86_64.config +++ b/vm/linux_x86_64.config @@ -70,6 +70,7 @@ CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_VSOCKETS=y CONFIG_VSOCKETS=y CONFIG_TTY=y +CONFIG_UNIX98_PTYS=y # CONFIG_BT is not set # CONFIG_EFI_PARTITION is not set # CONFIG_MODULES is not set