mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-14 15:09:09 +00:00
Avoid leaking handles across processes
This commit is contained in:
parent
a359de7893
commit
8a0008d985
44 changed files with 232 additions and 266 deletions
|
@ -61,7 +61,7 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
|
|||
handle = g_fds.p[oldfd].handle;
|
||||
proc = GetCurrentProcess();
|
||||
|
||||
if (DuplicateHandle(proc, handle, proc, &g_fds.p[newfd].handle, 0, true,
|
||||
if (DuplicateHandle(proc, handle, proc, &g_fds.p[newfd].handle, 0, false,
|
||||
kNtDuplicateSameAccess)) {
|
||||
g_fds.p[newfd].kind = g_fds.p[oldfd].kind;
|
||||
g_fds.p[newfd].mode = g_fds.p[oldfd].mode;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ntspawn.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/calls/struct/sigaction.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -37,6 +38,7 @@
|
|||
#include "libc/nt/enum/threadaccess.h"
|
||||
#include "libc/nt/enum/wait.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
|
@ -65,6 +67,7 @@
|
|||
|
||||
// clang-format off
|
||||
__msabi extern typeof(CloseHandle) *const __imp_CloseHandle;
|
||||
__msabi extern typeof(DuplicateHandle) *const __imp_DuplicateHandle;
|
||||
__msabi extern typeof(ExitProcess) *const __imp_ExitProcess;
|
||||
__msabi extern typeof(GenerateConsoleCtrlEvent) *const __imp_GenerateConsoleCtrlEvent;
|
||||
__msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
|
||||
|
@ -72,6 +75,7 @@ __msabi extern typeof(GetExitCodeProcess) *const __imp_GetExitCodeProcess;
|
|||
__msabi extern typeof(GetLastError) *const __imp_GetLastError;
|
||||
__msabi extern typeof(OpenThread) *const __imp_OpenThread;
|
||||
__msabi extern typeof(SetConsoleCtrlHandler) *const __imp_SetConsoleCtrlHandler;
|
||||
__msabi extern typeof(SetHandleInformation) *const __imp_SetHandleInformation;
|
||||
__msabi extern typeof(TerminateThread) *const __imp_TerminateThread;
|
||||
__msabi extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile;
|
||||
__msabi extern typeof(WaitForSingleObject) *const __imp_WaitForSingleObject;
|
||||
|
@ -171,23 +175,6 @@ keywords int sys_execve_nt(const char *program, char *const argv[],
|
|||
PurgeThread(*_weaken(__sigchld_thread));
|
||||
PurgeThread(*_weaken(__sigwinch_thread));
|
||||
|
||||
// close win32 handles for memory mappings
|
||||
// unlike fork calling execve destroys all memory
|
||||
// closing a map handle won't impact the mapping itself
|
||||
for (i = 0; i < _mmi.i; ++i) {
|
||||
PurgeHandle(_mmi.p[i].h);
|
||||
}
|
||||
|
||||
// close o_cloexec fds and anything that isn't stdio
|
||||
for (i = 0; i < g_fds.n; ++i) {
|
||||
if (g_fds.p[i].kind == kFdEmpty) {
|
||||
g_fds.p[i].handle = -1;
|
||||
} else if (i > 2 || (g_fds.p[i].flags & O_CLOEXEC)) {
|
||||
PurgeHandle(g_fds.p[i].handle);
|
||||
g_fds.p[i].handle = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// pass bitmask telling child which fds are sockets
|
||||
int bits;
|
||||
char buf[32], *v = 0;
|
||||
|
@ -205,10 +192,16 @@ keywords int sys_execve_nt(const char *program, char *const argv[],
|
|||
struct NtStartupInfo si = {
|
||||
.cb = sizeof(struct NtStartupInfo),
|
||||
.dwFlags = kNtStartfUsestdhandles,
|
||||
.hStdInput = g_fds.p[0].handle,
|
||||
.hStdOutput = g_fds.p[1].handle,
|
||||
.hStdError = g_fds.p[2].handle,
|
||||
};
|
||||
for (i = 0; i <= 2; ++i) {
|
||||
if (g_fds.p[i].kind != kFdEmpty && //
|
||||
!(g_fds.p[i].flags & O_CLOEXEC)) {
|
||||
__imp_SetHandleInformation(g_fds.p[i].handle, kNtHandleFlagInherit, true);
|
||||
si.stdiofds[i] = g_fds.p[i].handle;
|
||||
} else {
|
||||
si.stdiofds[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// launch the process
|
||||
struct NtProcessInformation pi;
|
||||
|
@ -223,6 +216,11 @@ keywords int sys_execve_nt(const char *program, char *const argv[],
|
|||
}
|
||||
PurgeHandle(pi.hThread);
|
||||
|
||||
// remove duplicate handles
|
||||
for (i = 0; i <= 2; ++i) {
|
||||
PurgeHandle(si.stdiofds[i]);
|
||||
}
|
||||
|
||||
// retreat to original win32-provided stack memory
|
||||
__switch_stacks(pi.hProcess, 0, 0, 0, sys_execve_nt_relay, __oldstack);
|
||||
}
|
||||
|
@ -240,19 +238,25 @@ static keywords void sys_execve_nt_relay(intptr_t h, long b, long c, long d) {
|
|||
|
||||
// close more handles
|
||||
__imp_SetConsoleCtrlHandler((void *)sys_execve_nt_event, 1);
|
||||
PurgeThread(g_fds.stdin.thread); // wasn't inherited by ntspawn
|
||||
PurgeHandle(g_fds.stdin.reader); // wasn't inherited by ntspawn
|
||||
PurgeHandle(g_fds.stdin.writer); // wasn't inherited by ntspawn
|
||||
PurgeHandle(g_fds.p[0].handle); // was inherited via startinfo
|
||||
PurgeHandle(g_fds.p[1].handle); // was inherited via startinfo
|
||||
PurgeHandle(g_fds.p[2].handle); // was inherited via startinfo
|
||||
PurgeThread(g_fds.stdin.thread);
|
||||
PurgeHandle(g_fds.stdin.reader);
|
||||
PurgeHandle(g_fds.stdin.writer);
|
||||
for (i = 0; i < g_fds.n; ++i) {
|
||||
if (g_fds.p[i].kind != kFdEmpty) {
|
||||
PurgeHandle(g_fds.p[i].handle);
|
||||
if (g_fds.p[i].kind == kFdConsole) {
|
||||
PurgeHandle(g_fds.p[i].extra);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_weaken(__klog_handle)) {
|
||||
PurgeHandle(*_weaken(__klog_handle)); // wasn't inherited by ntspawn
|
||||
PurgeHandle(*_weaken(__klog_handle));
|
||||
}
|
||||
|
||||
// free all the memory mmap created
|
||||
for (i = 0; i < _mmi.i; ++i) {
|
||||
__imp_UnmapViewOfFile((void *)((uintptr_t)_mmi.p[i].x << 16));
|
||||
PurgeHandle(_mmi.p[i].h);
|
||||
}
|
||||
|
||||
// wait for process to terminate
|
||||
|
|
|
@ -130,12 +130,11 @@ static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path,
|
|||
|
||||
// open the file, following symlinks
|
||||
int e = errno;
|
||||
int64_t hand = CreateFile(path16, perm | extra_perm, share, &kNtIsInheritable,
|
||||
disp, attr | extra_attr, 0);
|
||||
int64_t hand = CreateFile(path16, perm | extra_perm, share, 0, disp,
|
||||
attr | extra_attr, 0);
|
||||
if (hand == -1 && errno == EACCES && (flags & O_ACCMODE) == O_RDONLY) {
|
||||
errno = e;
|
||||
hand = CreateFile(path16, perm, share, &kNtIsInheritable, disp,
|
||||
attr | extra_attr, 0);
|
||||
hand = CreateFile(path16, perm, share, 0, disp, attr | extra_attr, 0);
|
||||
}
|
||||
|
||||
return __fix_enotdir(hand, path16);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/handlock.internal.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
|
@ -52,11 +53,11 @@ textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) {
|
|||
}
|
||||
__fds_unlock();
|
||||
hin = CreateNamedPipe(pipename, kNtPipeAccessInbound | kNtFileFlagOverlapped,
|
||||
mode, 1, PIPE_BUF, PIPE_BUF, 0, &kNtIsInheritable);
|
||||
mode, 1, PIPE_BUF, PIPE_BUF, 0, 0);
|
||||
__fds_lock();
|
||||
if (hin != -1) {
|
||||
if ((hout = CreateFile(pipename, kNtGenericWrite, 0, &kNtIsInheritable,
|
||||
kNtOpenExisting, kNtFileFlagOverlapped, 0)) != -1) {
|
||||
if ((hout = CreateFile(pipename, kNtGenericWrite, 0, 0, kNtOpenExisting,
|
||||
kNtFileFlagOverlapped, 0)) != -1) {
|
||||
g_fds.p[reader].kind = kFdFile;
|
||||
g_fds.p[reader].flags = O_RDONLY | flags;
|
||||
g_fds.p[reader].mode = 0010444;
|
||||
|
|
|
@ -33,8 +33,8 @@ textwindows int sys_statfs_nt(const char *path, struct statfs *sf) {
|
|||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
h = __fix_enotdir(
|
||||
CreateFile(path16, kNtFileGenericRead,
|
||||
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete,
|
||||
&kNtIsInheritable, kNtOpenExisting,
|
||||
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, 0,
|
||||
kNtOpenExisting,
|
||||
kNtFileAttributeNormal | kNtFileFlagBackupSemantics, 0),
|
||||
path16);
|
||||
if (h == -1) return -1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue