Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

secure_allocator_t is nonconforming #4460

Open
tiagomacarios opened this issue Nov 17, 2022 · 2 comments
Open

secure_allocator_t is nonconforming #4460

tiagomacarios opened this issue Nov 17, 2022 · 2 comments

Comments

@tiagomacarios
Copy link

(Most of this is copy and paste from an email thread with @BillyONeal)

secure_allocator_t is nonconforming - it doesn't rebind back to the same type.

That is, secure_allocator_t::template rebind::template rebind isn't secure_allocator_t, it is std::allocator.

Example code:

#include <memory>
#include <vector>

template <typename T>
struct secure_allocator_t : std::allocator<T> {};

std::vector<uint8_t, secure_allocator_t<uint8_t> > vec(42);

Failure (observe the _DEBUG):

clang-cl -c -std:c++20 -D_DEBUG a.cpp
In file included from a.cpp:2:
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\vector(2125,27): error: no matching conversion for static_cast from
      'std::vector<unsigned char, secure_allocator_t<unsigned char>>::_Alty' (aka 'secure_allocator_t<unsigned char>') to '_Rebind_alloc_t<std::vector<unsigned char,
      secure_allocator_t<unsigned char>>::_Alty, std::_Container_proxy>' (aka 'secure_allocator_t<std::_Container_proxy>')
        auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Al);
                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\xmemory(1353,42): note: expanded from macro '_GET_PROXY_ALLOCATOR'
#define _GET_PROXY_ALLOCATOR(_Alty, _Al) static_cast<_Rebind_alloc_t<_Alty, _Container_proxy>>(_Al)
                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\vector(683,9): note: in instantiation of function template specialization
      'std::vector<unsigned char, secure_allocator_t<unsigned char>>::_Construct_n<>' requested here
        _Construct_n(_Count);
        ^
a.cpp(7,52): note: in instantiation of member function 'std::vector<unsigned char, secure_allocator_t<unsigned char>>::vector' requested here
std::vector<uint8_t, secure_allocator_t<uint8_t> > vec(42);
                                                   ^
a.cpp(5,8): note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'secure_allocator_t<unsigned char>' to
      'const secure_allocator_t<std::_Container_proxy>' for 1st argument
struct secure_allocator_t : std::allocator<T> {};
       ^
a.cpp(5,8): note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'secure_allocator_t<unsigned char>' to
      'secure_allocator_t<std::_Container_proxy>' for 1st argument
a.cpp(5,8): note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
In file included from a.cpp:2:
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\vector(832,27): error: no matching conversion for static_cast from
      'std::vector<unsigned char, secure_allocator_t<unsigned char>>::_Alty' (aka 'secure_allocator_t<unsigned char>') to '_Rebind_alloc_t<std::vector<unsigned char,
      secure_allocator_t<unsigned char>>::_Alty, std::_Container_proxy>' (aka 'secure_allocator_t<std::_Container_proxy>')
        auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.34.31933\include\xmemory(1353,42): note: expanded from macro '_GET_PROXY_ALLOCATOR'
#define _GET_PROXY_ALLOCATOR(_Alty, _Al) static_cast<_Rebind_alloc_t<_Alty, _Container_proxy>>(_Al)
                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cpp(7,52): note: in instantiation of member function 'std::vector<unsigned char, secure_allocator_t<unsigned char>>::~vector' requested here
std::vector<uint8_t, secure_allocator_t<uint8_t> > vec(42);
                                                   ^
a.cpp(5,8): note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'secure_allocator_t<unsigned char>' to
      'const secure_allocator_t<std::_Container_proxy>' for 1st argument
struct secure_allocator_t : std::allocator<T> {};
       ^
a.cpp(5,8): note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'secure_allocator_t<unsigned char>' to
      'secure_allocator_t<std::_Container_proxy>' for 1st argument
a.cpp(5,8): note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
2 errors generated.

Rebinding back to the same type results in a compatible allocator is a runtime requirement.

Consider std::list<T, std::allocator>. List doesn't allocate Ts, it allocates list_nodes. Rebind is the mechanism the library uses to get from an allocator for T to an allocator for something other than T.

The library is going to secure_allocator_t and saying "give me the allocator for _Container_proxy", and secure_allocator_t is saying "std::allocator<_Container_proxy>". But secure_allocator_t isn't convertible to std::allocator<_Container_proxy>, hence the error.

The right fix for libmzq is to either change:

template <typename T> struct secure_allocator_t : std::allocator<T>
{
};

into

template <typename T> using secure_allocator_t = std::allocator<T>;,

or change the behavior of ZMQ_USE_LIBSODIUM to apply inside the body of allocate and deallocate instead of changing the definition of the type entirely.

@rotu
Copy link

rotu commented Jun 12, 2024

Fixed in #4480?

@ljluestc

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants