Skip to content

Commit

Permalink
Enable memory protection on DataSharing readers (#2405)
Browse files Browse the repository at this point in the history
* Refs 13457. DataSharing reader map memory as read only.

Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>

* Refs 13457. Allow disabling non-const accessor on LoanableSequence.

Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>

* Refs 13457. New macro FASTDDS_CONST_SEQUENCE.

Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>

* Refs 13457. Use FASTDDS_CONST_SEQUENCE on zero copy example.

Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>

* Refs 13457. Linters.

Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>
(cherry picked from commit 6505a51)

# Conflicts:
#	src/cpp/rtps/DataSharing/ReaderPool.hpp
#	src/cpp/utils/shared_memory/SharedMemSegment.hpp
  • Loading branch information
MiguelCompany authored and mergify-bot committed Feb 9, 2022
1 parent dc95ea1 commit 7fcba1b
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ void LoanableHelloWorldSubscriber::SubListener::on_subscription_matched(
void LoanableHelloWorldSubscriber::SubListener::on_data_available(
DataReader* reader)
{
FASTDDS_SEQUENCE(DataSeq, LoanableHelloWorld);
FASTDDS_CONST_SEQUENCE(DataSeq, LoanableHelloWorld);

DataSeq data;
SampleInfoSeq infos;
Expand Down
7 changes: 5 additions & 2 deletions include/fastdds/dds/core/LoanableSequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <cassert>
#include <cstdint>
#include <vector>
#include <type_traits>

#include <fastdds/dds/core/LoanableTypedCollection.hpp>
#include <fastdds/dds/log/Log.hpp>
Expand Down Expand Up @@ -57,8 +58,8 @@ namespace dds {
* the sequence is loaning the buffer. The sequence should not be destroyed until the loan is returned.
* @li A sequence with a zero maximum always has has_ownership == true
*/
template<typename T>
class LoanableSequence : public LoanableTypedCollection<T>
template<typename T, typename _NonConstEnabler = std::true_type>
class LoanableSequence : public LoanableTypedCollection<T, _NonConstEnabler>
{
public:

Expand Down Expand Up @@ -226,5 +227,7 @@ class LoanableSequence : public LoanableTypedCollection<T>

// Macro to easily declare a LoanableSequence for a data type
#define FASTDDS_SEQUENCE(FooSeq, Foo) using FooSeq = eprosima::fastdds::dds::LoanableSequence<Foo>
#define FASTDDS_CONST_SEQUENCE(FooSeq, Foo) using FooSeq = eprosima::fastdds::dds::LoanableSequence<Foo, \
std::false_type>

#endif // _FASTDDS_DDS_CORE_LOANABLESEQUENCE_HPP_
6 changes: 4 additions & 2 deletions include/fastdds/dds/core/LoanableTypedCollection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <cassert>
#include <cstdint>
#include <stdexcept>
#include <type_traits>

#include <fastdds/dds/core/LoanableCollection.hpp>

Expand All @@ -34,7 +35,7 @@ namespace dds {
*
* This is an abstract class. See @ref LoanableSequence for details.
*/
template<typename T>
template<typename T, typename _NonConstEnabler = std::true_type>
class LoanableTypedCollection : public LoanableCollection
{
public:
Expand All @@ -54,7 +55,8 @@ class LoanableTypedCollection : public LoanableCollection
*
* @return a reference to the element at position @c n
*/
T& operator [](
template <typename Enabler = _NonConstEnabler>
typename std::enable_if<Enabler::value, T>::type& operator [](
size_type n)
{
if (n >= length_)
Expand Down
5 changes: 5 additions & 0 deletions src/cpp/rtps/DataSharing/ReaderPool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,13 @@ class ReaderPool : public DataSharingPayloadPool
// Open the segment
try
{
<<<<<<< HEAD
segment_ = std::unique_ptr<fastdds::rtps::SharedMemSegment>(
new fastdds::rtps::SharedMemSegment(boost::interprocess::open_only,
=======
local_segment = std::unique_ptr<T>(
new T(boost::interprocess::open_read_only,
>>>>>>> 6505a51ff (Enable memory protection on DataSharing readers (#2405))
segment_name_.c_str()));
}
catch (const std::exception& e)
Expand Down
169 changes: 169 additions & 0 deletions src/cpp/utils/shared_memory/SharedMemSegment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,175 @@ class SharedMemSegment
std::string name_;
};

<<<<<<< HEAD
=======
template<typename T, typename U>
class SharedSegment : public SharedSegmentBase
{
public:

typedef T managed_shared_memory_type;
typedef U managed_shared_object_type;

SharedSegment(
boost::interprocess::create_only_t,
const std::string& name,
size_t size)
: SharedSegmentBase(name)
{
segment_ = std::unique_ptr<managed_shared_memory_type>(
new managed_shared_memory_type(boost::interprocess::create_only, name.c_str(),
static_cast<Offset>(size + EXTRA_SEGMENT_SIZE)));
}

SharedSegment(
boost::interprocess::open_only_t,
const std::string& name)
: SharedSegmentBase(name)
{
segment_ = std::unique_ptr<managed_shared_memory_type>(
new managed_shared_memory_type(boost::interprocess::open_only, name.c_str()));
}

SharedSegment(
boost::interprocess::open_read_only_t,
const std::string& name)
: SharedSegmentBase(name)
{
segment_ = std::unique_ptr<managed_shared_memory_type>(
new managed_shared_memory_type(boost::interprocess::open_read_only, name.c_str()));
}

SharedSegment(
boost::interprocess::open_or_create_t,
const std::string& name,
size_t size)
: SharedSegmentBase(name)
{
segment_ = std::unique_ptr<managed_shared_memory_type>(
new managed_shared_memory_type(boost::interprocess::create_only, name.c_str(), static_cast<Offset>(size)));
}

~SharedSegment()
{
// no need of exception handling cause never throws
segment_.reset();
}

static void remove(
const std::string& name)
{
managed_shared_object_type::remove(name.c_str());
}

void remove() override
{
managed_shared_object_type::remove(name().c_str());
}

void* get_address_from_offset(
SharedSegment::Offset offset) const override
{
return segment_->get_address_from_handle(offset);
}

SharedSegment::Offset get_offset_from_address(
void* address) const override
{
return segment_->get_handle_from_address(address);
}

managed_shared_memory_type& get()
{
return *segment_;
}

/**
* Estimates the extra segment space required for an allocation
*/
static uint32_t compute_per_allocation_extra_size(
size_t allocation_alignment,
const std::string& domain_name)
{
Id uuid;

try
{
static uint32_t extra_size = 0;

if (extra_size == 0)
{
uuid.generate();

auto name = domain_name + "_" + uuid.to_string();

SharedMemEnvironment::get().init();

{
managed_shared_memory_type
test_segment(boost::interprocess::create_only, name.c_str(),
(std::max)((uint32_t)1024, static_cast<uint32_t>(allocation_alignment * 4)));

auto m1 = test_segment.get_free_memory();
test_segment.allocate_aligned(1, static_cast<uint32_t>(allocation_alignment));
auto m2 = test_segment.get_free_memory();
extra_size = static_cast<uint32_t>(m1 - m2);
}

managed_shared_object_type::remove(name.c_str());
}

return extra_size;

}
catch (const std::exception& e)
{
logError(RTPS_TRANSPORT_SHM, "Failed to create segment " << uuid.to_string()
<< ": " << e.what());

throw;
}
}

/**
* Check the allocator internal structures
* @return true if structures are ok, false otherwise
*/
bool check_sanity()
{
return segment_->check_sanity();
}

/**
* @return The segment's size in bytes, including internal structures overhead.
*/
Offset mem_size() const
{
return segment_->get_size();
}

private:

std::unique_ptr<managed_shared_memory_type> segment_;
};

using SharedMemSegment = SharedSegment<
boost::interprocess::basic_managed_shared_memory<
char,
boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
boost::interprocess::offset_ptr<void, SharedSegmentBase::Offset, std::uint64_t>>,
boost::interprocess::iset_index>,
boost::interprocess::shared_memory_object>;

using SharedFileSegment = SharedSegment<
boost::interprocess::basic_managed_mapped_file<
char,
boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
boost::interprocess::offset_ptr<void, SharedSegmentBase::Offset, std::uint64_t>>,
boost::interprocess::iset_index>,
boost::interprocess::file_mapping>;

>>>>>>> 6505a51ff (Enable memory protection on DataSharing readers (#2405))
} // namespace rtps
} // namespace fastdds
} // namespace eprosima
Expand Down

0 comments on commit 7fcba1b

Please sign in to comment.