Cygwin: kill(1): disallow killing process using raw Windows PID
This may end up killing the wrong process. Only allow Cygwin PID. Slightly clean up code: Remove outdated W95 considerations. Fix a bug in commandline argument processing. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
448cf5aa4b
commit
8de660271f
|
@ -152,29 +152,31 @@ get_debug_priv (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __stdcall
|
static void __stdcall
|
||||||
forcekill (int pid, int sig, int wait)
|
forcekill (pid_t pid, int sig, int wait)
|
||||||
{
|
{
|
||||||
// try to acquire SeDebugPrivilege
|
/* try to acquire SeDebugPrivilege */
|
||||||
get_debug_priv();
|
get_debug_priv();
|
||||||
|
|
||||||
external_pinfo *p = NULL;
|
external_pinfo *p = NULL;
|
||||||
/* cygwin_internal misinterprets negative pids (Win9x pids) */
|
|
||||||
if (pid > 0)
|
|
||||||
p = (external_pinfo *) cygwin_internal (CW_GETPINFO_FULL, pid);
|
p = (external_pinfo *) cygwin_internal (CW_GETPINFO_FULL, pid);
|
||||||
DWORD dwpid = p ? p->dwProcessId : (DWORD) pid;
|
if (!p)
|
||||||
HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, (DWORD) dwpid);
|
{
|
||||||
|
fprintf (stderr, "%s: %d: No such process\n", prog_name, pid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DWORD dwpid = p->dwProcessId;
|
||||||
|
HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, dwpid);
|
||||||
if (!h)
|
if (!h)
|
||||||
{
|
{
|
||||||
if (!wait || GetLastError () != ERROR_INVALID_PARAMETER)
|
if (!wait || GetLastError () != ERROR_INVALID_PARAMETER)
|
||||||
fprintf (stderr, "%s: couldn't open pid %u\n",
|
fprintf (stderr, "%s: couldn't open pid %u\n", prog_name, dwpid);
|
||||||
prog_name, (unsigned) dwpid);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!wait || WaitForSingleObject (h, 200) != WAIT_OBJECT_0)
|
if (!wait || WaitForSingleObject (h, 200) != WAIT_OBJECT_0)
|
||||||
if (sig && !TerminateProcess (h, sig << 8)
|
if (sig && !TerminateProcess (h, sig << 8)
|
||||||
&& WaitForSingleObject (h, 200) != WAIT_OBJECT_0)
|
&& WaitForSingleObject (h, 200) != WAIT_OBJECT_0)
|
||||||
fprintf (stderr, "%s: couldn't kill pid %u, %u\n",
|
fprintf (stderr, "%s: couldn't kill pid %u, %u\n",
|
||||||
prog_name, (unsigned) dwpid, (unsigned int) GetLastError ());
|
prog_name, dwpid, GetLastError ());
|
||||||
CloseHandle (h);
|
CloseHandle (h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,11 +234,8 @@ main (int argc, char **argv)
|
||||||
print_version ();
|
print_version ();
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
if (gotasig)
|
if (gotasig) /* this is a negative pid, go ahead */
|
||||||
{
|
|
||||||
--optind;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
optreset = 1;
|
optreset = 1;
|
||||||
optind = 1 + av - argv;
|
optind = 1 + av - argv;
|
||||||
gotasig = *av + 1;
|
gotasig = *av + 1;
|
||||||
|
@ -252,18 +251,22 @@ out:
|
||||||
test_for_unknown_sig (sig, gotasig);
|
test_for_unknown_sig (sig, gotasig);
|
||||||
|
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
if (*argv == 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: not enough arguments\n", prog_name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
while (*argv != NULL)
|
while (*argv != NULL)
|
||||||
{
|
{
|
||||||
if (!pid)
|
if (!pid)
|
||||||
pid = strtoll (*argv, &p, 10);
|
pid = strtoll (*argv, &p, 10);
|
||||||
if (*p != '\0'
|
/* INT_MIN <= pid <= INT_MAX. -f only takes positive pids. */
|
||||||
|| (!force && (pid < INT_MIN || pid > INT_MAX))
|
if (*p != '\0' || pid < (force ? 1 : INT_MIN) || pid > INT_MAX)
|
||||||
|| (force && (pid <= 0 || pid > UINT_MAX)))
|
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: illegal pid: %s\n", prog_name, *argv);
|
fprintf (stderr, "%s: illegal pid: %s\n", prog_name, *argv);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
else if (pid <= INT_MAX && kill ((pid_t) pid, sig) == 0)
|
else if (kill ((pid_t) pid, sig) == 0)
|
||||||
{
|
{
|
||||||
if (force)
|
if (force)
|
||||||
forcekill ((pid_t) pid, sig, 1);
|
forcekill ((pid_t) pid, sig, 1);
|
||||||
|
|
Loading…
Reference in New Issue