Zero-fill padding in detach_abi(com_array) (#1165)

A code analysis warning recently fired for a customer on detach_abi(com_array<T>). This function returns a std::pair<uint32_t, some_pointer_type>, which will have, on 64-bit builds, 4 bytes of padding between the uint32 size and the pointer members. Currently, that padding is uninitialized.

The idea behind the code analysis warning is that information may be leaked via those unitialized bytes.

In practice, that's almost never going to be an issue for this function, because the std::pair is not an interesting object to pass around, and only exists as a convenience to return both the size and buffer of the com_array at the same time.

However, the fix removes a pain point for a customer, is simple, risk-free, and actually gets optimized away in the 99% use case (return value stored in a local variable, access only the first/second members, not the padding bytes).  Demo showing optimization: https://godbolt.org/z/T4vPhMKxn
This commit is contained in:
Ryan Shepherd 2022-07-06 14:05:20 -07:00 коммит произвёл GitHub
Родитель 53ee6de064
Коммит f65801e69f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 4 добавлений и 1 удалений

Просмотреть файл

@ -420,7 +420,10 @@ WINRT_EXPORT namespace winrt
template <typename T> template <typename T>
auto detach_abi(com_array<T>& object) noexcept auto detach_abi(com_array<T>& object) noexcept
{ {
std::pair<uint32_t, impl::arg_out<T>> result(object.size(), *reinterpret_cast<impl::arg_out<T>*>(&object)); std::pair<uint32_t, impl::arg_out<T>> result;
memset(&result, 0, sizeof(result));
result.first = object.size();
result.second = *reinterpret_cast<impl::arg_out<T>*>(&object);
memset(&object, 0, sizeof(com_array<T>)); memset(&object, 0, sizeof(com_array<T>));
return result; return result;
} }