You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jp...@apache.org on 2017/09/20 00:07:32 UTC
mesos git commit: Fixed invalid handle bug in `os::process()`.
Repository: mesos
Updated Branches:
refs/heads/master 01b7041fa -> 11de04c1b
Fixed invalid handle bug in `os::process()`.
This patch fixes a bug found by running `mesos-tests` under Application
Verifier on Windows. Mesos was inadvertently attempting to get a process
handle for the System Idle Process with PID `0`, which is not permitted
by the OS. To remedy this, we now check if `os::process` receives `0`
for its argument, and return an error if so. Furthermore, we remove the
PID `0` from the `os::pids` API, as it is not useful to the programmer,
and only serves to cause errors later. Finally, the return value for
`OpenProcess` was being incorrectly checked, as the API returns a
`nullptr` on failure, not `INVALID_HANDLE_VALUE`.
Review: https://reviews.apache.org/r/62391/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/11de04c1
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/11de04c1
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/11de04c1
Branch: refs/heads/master
Commit: 11de04c1bbf65d0a90576642f8ea9574e05a317a
Parents: 01b7041
Author: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Authored: Tue Sep 19 17:19:59 2017 -0700
Committer: James Peach <jp...@apache.org>
Committed: Tue Sep 19 17:19:59 2017 -0700
----------------------------------------------------------------------
3rdparty/stout/include/stout/windows/os.hpp | 21 +++++++++++++++++++--
3rdparty/stout/tests/os/process_tests.cpp | 13 +++++++++++--
2 files changed, 30 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/11de04c1/3rdparty/stout/include/stout/windows/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/windows/os.hpp b/3rdparty/stout/include/stout/windows/os.hpp
index f35bf31..a70a61c 100644
--- a/3rdparty/stout/include/stout/windows/os.hpp
+++ b/3rdparty/stout/include/stout/windows/os.hpp
@@ -179,7 +179,16 @@ inline Try<std::set<pid_t>> pids(Option<pid_t> group, Option<pid_t> session)
max_items *= 2;
} while (bytes_returned >= size_in_bytes);
- return std::set<pid_t>(processes.begin(), processes.end());
+ std::set<pid_t> pids_set(processes.begin(), processes.end());
+
+ // NOTE: The PID `0` will always be returned by `EnumProcesses`; however, it
+ // is the PID of Windows' System Idle Process. While the PID is valid, using
+ // it for anything is almost always invalid. For instance, `OpenProcess` will
+ // fail with an invalid parameter error if the user tries to get a handle for
+ // PID `0`. In the interest of safety, we prevent the `pids` API from ever
+ // including the PID `0`.
+ pids_set.erase(0);
+ return pids_set;
}
@@ -534,6 +543,13 @@ inline Result<PROCESSENTRY32W> process_entry(pid_t pid)
// something went wrong.
inline Result<Process> process(pid_t pid)
{
+ if (pid == 0) {
+ // The 0th PID is that of the System Idle Process on Windows. However, it is
+ // invalid to attempt to get a proces handle or else perform any operation
+ // on this pseudo-process.
+ return Error("os::process: Invalid parameter: pid == 0");
+ }
+
// Find process with pid.
Result<PROCESSENTRY32W> entry = process_entry(pid);
@@ -548,7 +564,8 @@ inline Result<Process> process(pid_t pid)
false,
pid);
- if (process_handle == INVALID_HANDLE_VALUE) {
+ // ::OpenProcess returns `NULL`, not `INVALID_HANDLE_VALUE` on failure.
+ if (process_handle == nullptr) {
return WindowsError("os::process: Call to `OpenProcess` failed");
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/11de04c1/3rdparty/stout/tests/os/process_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/tests/os/process_tests.cpp b/3rdparty/stout/tests/os/process_tests.cpp
index 963eb4e..cbae66c 100644
--- a/3rdparty/stout/tests/os/process_tests.cpp
+++ b/3rdparty/stout/tests/os/process_tests.cpp
@@ -44,6 +44,7 @@ using std::string;
const unsigned int init_pid =
#ifdef __WINDOWS__
+ // NOTE: This is also known as the System Idle Process.
0;
#else
1;
@@ -105,8 +106,9 @@ TEST_F(ProcessTest, Process)
// Assert init.
Result<Process> init_process = os::process(init_pid);
#ifdef __WINDOWS__
- // NOTE: On Windows, inspecting other processes usually requires privileges.
- // So we expect it to error out instead of succeed, unlike the POSIX version.
+ // NOTE: On Windows, the init process is a pseudo-process, and it is not
+ // possible to get a handle to it. So we expect it to error out instead of
+ // succeed, unlike the POSIX version.
EXPECT_ERROR(init_process);
#elif __FreeBSD__
// In a FreeBSD jail, we wont find an init process.
@@ -173,7 +175,14 @@ TEST_F(ProcessTest, Pids)
#ifdef __FreeBSD__
if (!isJailed()) {
#endif
+#ifdef __WINDOWS__
+ // On Windows, we explicitly do not return the PID of the System Idle
+ // Process, because doing so can cause unexpected bugs.
+ EXPECT_EQ(0u, pids.get().count(init_pid));
+#else
+ // Elsewhere we always expect exactly 1 init PID.
EXPECT_EQ(1u, pids.get().count(init_pid));
+#endif
#ifdef __FreeBSD__
}
#endif