-
Notifications
You must be signed in to change notification settings - Fork 138
Description
I've noticed while using boost::process::limit_handles
that the code seems to be attempting to dereference std::vector::end which ultimately ends up with undefined behavior. We can see here
auto all_handles = get_handles();
foreach_used_handle(exec,
[&](::boost::winapi::HANDLE_ handle)
{
auto itr = std::find(all_handles.begin(), all_handles .end(), handle);
::boost::winapi::DWORD_ flags = 0u;
if (itr != all_handles.end())
*itr = ::boost::winapi::INVALID_HANDLE_VALUE_;
else if ((::boost::winapi::GetHandleInformation(*itr, &flags) != 0)
&&((flags & ::boost::winapi::HANDLE_FLAG_INHERIT_) == 0)) //it is NOT inherited anyhow, so ignore too
*itr = ::boost::winapi::INVALID_HANDLE_VALUE_;
});
auto part_itr = std::partition(all_handles.begin(), all_handles.end(),
[](::boost::winapi::HANDLE_ handle) {return handle != ::boost::winapi::INVALID_HANDLE_VALUE_;});
all_handles.erase(part_itr, all_handles.end()); //remove invalid handles
handles_with_inherit_flag = std::move(all_handles);
for (auto handle : handles_with_inherit_flag)
::boost::winapi::SetHandleInformation(handle, ::boost::winapi::HANDLE_FLAG_INHERIT_, 0);
If the iterator != all_handles.end()
then it was found and set the value to ::boost::winapi::INVALID_HANDLE_VALUE_
. Otherwise dereference the iterator into GetHandleInformation, however the iterator will equal all_handles.end(). It also seems that if this is the case there's no point in setting itr
to ::boost::winapi::INVALID_HANDLE_VALUE_
as it already is not present in all_handles list and therefore ::boost::winapi::SetHandleInformation
won't be called on it anyway. It seems the additional else if
is redundant?
Ordinarily if this code is being called you would expect at least 1 handle to be present (for the pipe) in the calling process and therefore wouldn't normally run into this error but I am also seeing it's possible for get_handles() to return nothing and this then seems to cause an access violation.