0001-Store-a-copy-of-each-serialized-shared_ptr-within-the-archive.patch 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. From f27c12d491955c94583512603bf32c4568f20929 Mon Sep 17 00:00:00 2001
  2. From: Michael Walz <code@serpedon.de>
  3. Date: Tue, 2 Feb 2021 00:50:29 +0100
  4. Subject: [PATCH] Store a copy of each serialized shared_ptr within the archive
  5. to prevent the shared_ptr to be freed to early. (#667)
  6. The archives use the memory address pointed by the shared_ptr as a
  7. unique id which must not be reused during lifetime of the archive.
  8. Therefore, the archives stores a copy of it.
  9. This problem was also reported as CVE-2020-11105.
  10. [Retrieved from:
  11. https://github.com/USCiLab/cereal/commit/f27c12d491955c94583512603bf32c4568f20929]
  12. Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
  13. ---
  14. include/cereal/cereal.hpp | 13 +++++++++++--
  15. include/cereal/types/memory.hpp | 2 +-
  16. 2 files changed, 12 insertions(+), 3 deletions(-)
  17. diff --git a/include/cereal/cereal.hpp b/include/cereal/cereal.hpp
  18. index 99bed9d6..f0d15e8b 100644
  19. --- a/include/cereal/cereal.hpp
  20. +++ b/include/cereal/cereal.hpp
  21. @@ -369,12 +369,17 @@ namespace cereal
  22. point to the same data.
  23. @internal
  24. - @param addr The address (see shared_ptr get()) pointed to by the shared pointer
  25. + @param sharedPointer The shared pointer itself (the adress is taked via get()).
  26. + The archive takes a copy to prevent the memory location to be freed
  27. + as long as the address is used as id. This is needed to prevent CVE-2020-11105.
  28. @return A key that uniquely identifies the pointer */
  29. - inline std::uint32_t registerSharedPointer( void const * addr )
  30. + inline std::uint32_t registerSharedPointer(const std::shared_ptr<const void>& sharedPointer)
  31. {
  32. + void const * addr = sharedPointer.get();
  33. +
  34. // Handle null pointers by just returning 0
  35. if(addr == 0) return 0;
  36. + itsSharedPointerStorage.push_back(sharedPointer);
  37. auto id = itsSharedPointerMap.find( addr );
  38. if( id == itsSharedPointerMap.end() )
  39. @@ -645,6 +650,10 @@ namespace cereal
  40. //! Maps from addresses to pointer ids
  41. std::unordered_map<void const *, std::uint32_t> itsSharedPointerMap;
  42. + //! Copy of shared pointers used in #itsSharedPointerMap to make sure they are kept alive
  43. + // during lifetime of itsSharedPointerMap to prevent CVE-2020-11105.
  44. + std::vector<std::shared_ptr<const void>> itsSharedPointerStorage;
  45. +
  46. //! The id to be given to the next pointer
  47. std::uint32_t itsCurrentPointerId;
  48. diff --git a/include/cereal/types/memory.hpp b/include/cereal/types/memory.hpp
  49. index 59e9da9b..cac1f334 100644
  50. --- a/include/cereal/types/memory.hpp
  51. +++ b/include/cereal/types/memory.hpp
  52. @@ -263,7 +263,7 @@ namespace cereal
  53. {
  54. auto & ptr = wrapper.ptr;
  55. - uint32_t id = ar.registerSharedPointer( ptr.get() );
  56. + uint32_t id = ar.registerSharedPointer( ptr );
  57. ar( CEREAL_NVP_("id", id) );
  58. if( id & detail::msb_32bit )