Skip to content

Commit

Permalink
Store a copy of each serialized shared_ptr within the archive to prev…
Browse files Browse the repository at this point in the history
…ent the shared_ptr to be freed to early. (USCiLab#667)

The archives use the memory address pointed by the shared_ptr as a
unique id which must not be reused during lifetime of the archive.
Therefore, the archives stores a copy of it.
This problem was also reported as CVE-2020-11105.
  • Loading branch information
serpedon authored and AzothAmmo committed Nov 28, 2021
1 parent 6e6fd8d commit 51bee0f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
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

0 comments on commit 51bee0f

Please sign in to comment.