Skip to content

Commit 73feb91

Browse files
serpedonarximboldi
authored andcommitted
Store a copy of each serialized shared_ptr within the archive to prevent 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.
1 parent 51662e4 commit 73feb91

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

include/cereal/cereal.hpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,17 @@ namespace cereal
369369
point to the same data.
370370
371371
@internal
372-
@param addr The address (see shared_ptr get()) pointed to by the shared pointer
372+
@param sharedPointer The shared pointer itself (the adress is taked via get()).
373+
The archive takes a copy to prevent the memory location to be freed
374+
as long as the address is used as id. This is needed to prevent CVE-2020-11105.
373375
@return A key that uniquely identifies the pointer */
374-
inline std::uint32_t registerSharedPointer( void const * addr )
376+
inline std::uint32_t registerSharedPointer(const std::shared_ptr<const void>& sharedPointer)
375377
{
378+
void const * addr = sharedPointer.get();
379+
376380
// Handle null pointers by just returning 0
377381
if(addr == 0) return 0;
382+
itsSharedPointerStorage.push_back(sharedPointer);
378383

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

653+
//! Copy of shared pointers used in #itsSharedPointerMap to make sure they are kept alive
654+
// during lifetime of itsSharedPointerMap to prevent CVE-2020-11105.
655+
std::vector<std::shared_ptr<const void>> itsSharedPointerStorage;
656+
648657
//! The id to be given to the next pointer
649658
std::uint32_t itsCurrentPointerId;
650659

include/cereal/types/memory.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ namespace cereal
263263
{
264264
auto & ptr = wrapper.ptr;
265265

266-
uint32_t id = ar.registerSharedPointer( ptr.get() );
266+
uint32_t id = ar.registerSharedPointer( ptr );
267267
ar( CEREAL_NVP_("id", id) );
268268

269269
if( id & detail::msb_32bit )

0 commit comments

Comments
 (0)