mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 16:28:30 +00:00
Spoof PID across execve() on Windows
It's now possible with cosmo and redbean, to deliver a signal to a child process after it has called execve(). However the executed program needs to be compiled using cosmocc. The cosmo runtime WinMain() implementation now intercepts a _COSMO_PID environment variable that's set by execve(). It ensures the child process will use the same C:\ProgramData\cosmo\sigs file, which is where kill() will place the delivered signal. We are able to do this on Windows even better than NetBSD, which has a bug with this Fixes #1334
This commit is contained in:
parent
9cc1bd04b2
commit
26c051c297
8 changed files with 187 additions and 21 deletions
|
@ -300,6 +300,37 @@ static abi wontreturn void WinInit(const char16_t *cmdline) {
|
|||
(uintptr_t)(stackaddr + (stacksize - sizeof(struct WinArgs))));
|
||||
}
|
||||
|
||||
static int Atoi(const char16_t *str) {
|
||||
int c;
|
||||
unsigned x = 0;
|
||||
while ((c = *str++)) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
x *= 10;
|
||||
x += c - '0';
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
static abi int WinGetPid(const char16_t *var, bool *out_is_inherited) {
|
||||
uint32_t len;
|
||||
char16_t val[12];
|
||||
if ((len = __imp_GetEnvironmentVariableW(var, val, ARRAYLEN(val)))) {
|
||||
int pid = -1;
|
||||
if (len < ARRAYLEN(val))
|
||||
pid = Atoi(val);
|
||||
__imp_SetEnvironmentVariableW(var, NULL);
|
||||
if (pid > 0) {
|
||||
*out_is_inherited = true;
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
*out_is_inherited = false;
|
||||
return __imp_GetCurrentProcessId();
|
||||
}
|
||||
|
||||
abi int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
|
||||
const char *lpCmdLine, int64_t nCmdShow) {
|
||||
static atomic_ulong fake_process_signals;
|
||||
|
@ -316,10 +347,12 @@ abi int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
|
|||
__imp_GetSystemInfo(&si);
|
||||
__pagesize = si.dwPageSize;
|
||||
__gransize = si.dwAllocationGranularity;
|
||||
__pid = __imp_GetCurrentProcessId();
|
||||
bool pid_is_inherited;
|
||||
__pid = WinGetPid(u"_COSMO_PID", &pid_is_inherited);
|
||||
if (!(__sig.process = __sig_map_process(__pid, kNtOpenAlways)))
|
||||
__sig.process = &fake_process_signals;
|
||||
atomic_store_explicit(__sig.process, 0, memory_order_release);
|
||||
if (!pid_is_inherited)
|
||||
atomic_store_explicit(__sig.process, 0, memory_order_release);
|
||||
cmdline = __imp_GetCommandLineW();
|
||||
#if SYSDEBUG
|
||||
// sloppy flag-only check for early initialization
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue