Skip to content

CVE-2020-11105: Store a copy of each serialized shared_ptr within the archive to prevent the shared_ptr to be freed to early. #667

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

Merged
merged 1 commit into from
Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions include/cereal/cereal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,17 @@ namespace cereal
point to the same data.

@internal
@param addr The address (see shared_ptr get()) pointed to by the shared pointer
@param sharedPointer The shared pointer itself (the adress is taked via get()).
The archive takes a copy to prevent the memory location to be freed
as long as the address is used as id. This is needed to prevent CVE-2020-11105.
@return A key that uniquely identifies the pointer */
inline std::uint32_t registerSharedPointer( void const * addr )
inline std::uint32_t registerSharedPointer(const std::shared_ptr<const void>& sharedPointer)
{
void const * addr = sharedPointer.get();

// Handle null pointers by just returning 0
if(addr == 0) return 0;
itsSharedPointerStorage.push_back(sharedPointer);

auto id = itsSharedPointerMap.find( addr );
if( id == itsSharedPointerMap.end() )
Expand Down Expand Up @@ -645,6 +650,10 @@ namespace cereal
//! Maps from addresses to pointer ids
std::unordered_map<void const *, std::uint32_t> itsSharedPointerMap;

//! Copy of shared pointers used in #itsSharedPointerMap to make sure they are kept alive
// during lifetime of itsSharedPointerMap to prevent CVE-2020-11105.
std::vector<std::shared_ptr<const void>> itsSharedPointerStorage;

//! The id to be given to the next pointer
std::uint32_t itsCurrentPointerId;

Expand Down
2 changes: 1 addition & 1 deletion include/cereal/types/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ namespace cereal
{
auto & ptr = wrapper.ptr;

uint32_t id = ar.registerSharedPointer( ptr.get() );
uint32_t id = ar.registerSharedPointer( ptr );
ar( CEREAL_NVP_("id", id) );

if( id & detail::msb_32bit )
Expand Down