Skip to content

Commit e9ee2f6

Browse files
Mario-DLMiguelCompany
authored andcommitted
Fix data race in PDPListener and SecurityManager (#4188)
* Refs #20166: Regression Test Signed-off-by: Mario Dominguez <[email protected]> * Refs #20166: Use the participant proxy data stored the collection in SecurityManager::discovered_participant() Signed-off-by: Mario Dominguez <[email protected]> * Refs #20166: Rev suggestion Signed-off-by: Mario Dominguez <[email protected]> * Refs #20166: Test Rev suggestion Signed-off-by: Mario Dominguez <[email protected]> --------- Signed-off-by: Mario Dominguez <[email protected]> (cherry picked from commit 84334da)
1 parent d2ac489 commit e9ee2f6

File tree

3 files changed

+68
-14
lines changed

3 files changed

+68
-14
lines changed

src/cpp/rtps/builtin/discovery/participant/DS/PDPSecurityInitiatorListener.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,16 @@ void PDPSecurityInitiatorListener::process_alive_data(
7171

7272
if (old_data == nullptr)
7373
{
74+
auto callback_data = new_data;
7475
reader->getMutex().unlock();
7576
lock.unlock();
7677

7778
//! notify security manager in order to start handshake
78-
bool ret = parent_pdp_->getRTPSParticipant()->security_manager().discovered_participant(new_data);
79+
bool ret = parent_pdp_->getRTPSParticipant()->security_manager().discovered_participant(callback_data);
7980
//! Reply to the remote participant
8081
if (ret)
8182
{
82-
response_cb_(temp_participant_data_);
83+
response_cb_(callback_data);
8384
}
8485

8586
// Take again the reader lock

src/cpp/rtps/security/SecurityManager.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,8 @@ bool SecurityManager::discovered_participant(
601601
// Create or find information
602602
bool undiscovered = false;
603603
DiscoveredParticipantInfo::AuthUniquePtr remote_participant_info;
604+
// Use the information from the collection
605+
const ParticipantProxyData* remote_participant_data = nullptr;
604606
{
605607
std::lock_guard<shared_mutex> _(mutex_);
606608

@@ -614,13 +616,14 @@ bool SecurityManager::discovered_participant(
614616

615617
undiscovered = map_ret.second;
616618
remote_participant_info = map_ret.first->second->get_auth();
619+
remote_participant_data = &map_ret.first->second->participant_data();
617620
}
618621

619622
bool notify_part_authorized = false;
620-
if (undiscovered && remote_participant_info)
623+
if (undiscovered && remote_participant_info && remote_participant_data != nullptr)
621624
{
622625
// Configure the timed event but do not start it
623-
const GUID_t guid = participant_data.m_guid;
626+
const GUID_t guid = remote_participant_data->m_guid;
624627
remote_participant_info->event_.reset(new TimedEvent(participant_->getEventResource(),
625628
[&, guid]() -> bool
626629
{
@@ -634,8 +637,8 @@ bool SecurityManager::discovered_participant(
634637
// Validate remote participant.
635638
ValidationResult_t validation_ret = authentication_plugin_->validate_remote_identity(&remote_identity_handle,
636639
*local_identity_handle_,
637-
participant_data.identity_token_,
638-
participant_data.m_guid, exception);
640+
remote_participant_data->identity_token_,
641+
remote_participant_data->m_guid, exception);
639642

640643
switch (validation_ret)
641644
{
@@ -655,21 +658,21 @@ bool SecurityManager::discovered_participant(
655658
// TODO(Ricardo) Send event.
656659
default:
657660

658-
on_validation_failed(participant_data, exception);
661+
on_validation_failed(*remote_participant_data, exception);
659662

660663
std::lock_guard<shared_mutex> _(mutex_);
661664

662665
// Remove created element, because authentication failed.
663-
discovered_participants_.erase(participant_data.m_guid);
666+
discovered_participants_.erase(remote_participant_data->m_guid);
664667

665668
//TODO(Ricardo) cryptograhy registration in AUTHENTICAITON_OK
666669
return false;
667670
}
668671

669-
EPROSIMA_LOG_INFO(SECURITY, "Discovered participant " << participant_data.m_guid);
672+
EPROSIMA_LOG_INFO(SECURITY, "Discovered participant " << remote_participant_data->m_guid);
670673

671674
// Match entities
672-
match_builtin_endpoints(participant_data);
675+
match_builtin_endpoints(*remote_participant_data);
673676

674677
// Store new remote handle.
675678
remote_participant_info->auth_status_ = auth_status;
@@ -681,7 +684,7 @@ bool SecurityManager::discovered_participant(
681684
{
682685
//TODO(Ricardo) Shared secret on this case?
683686
std::shared_ptr<SecretHandle> ss;
684-
notify_part_authorized = participant_authorized(participant_data, remote_participant_info, ss);
687+
notify_part_authorized = participant_authorized(*remote_participant_data, remote_participant_info, ss);
685688
}
686689
}
687690
else
@@ -704,15 +707,15 @@ bool SecurityManager::discovered_participant(
704707
if (remote_participant_info->auth_status_ == AUTHENTICATION_REQUEST_NOT_SEND)
705708
{
706709
// Maybe send request.
707-
returnedValue = on_process_handshake(participant_data, remote_participant_info,
710+
returnedValue = on_process_handshake(*remote_participant_data, remote_participant_info,
708711
MessageIdentity(), HandshakeMessageToken(), notify_part_authorized);
709712
}
710713

711-
restore_discovered_participant_info(participant_data.m_guid, remote_participant_info);
714+
restore_discovered_participant_info(remote_participant_data->m_guid, remote_participant_info);
712715

713716
if (notify_part_authorized)
714717
{
715-
notify_participant_authorized(participant_data);
718+
notify_participant_authorized(*remote_participant_data);
716719
}
717720

718721
return returnedValue;

test/blackbox/common/BlackboxTestsSecurity.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3848,6 +3848,56 @@ TEST(Security, AllowUnauthenticatedParticipants_TwoParticipantsDifferentCertific
38483848
ASSERT_FALSE(writer.is_matched());
38493849
}
38503850

3851+
// Regresion test for redmine issue 20166
3852+
TEST(Security, InANonSecureParticipantWithTwoSecureParticipantScenario_TheTwoSecureParticipantsCorrectlyCommunicate)
3853+
{
3854+
// Create
3855+
PubSubReader<HelloWorldPubSubType> non_secure_reader("HelloWorldTopic");
3856+
PubSubReader<HelloWorldPubSubType> secure_reader("HelloWorldTopic");
3857+
PubSubWriter<HelloWorldPubSubType> secure_writer("HelloWorldTopic");
3858+
3859+
// Configure security
3860+
const std::string governance_file("governance_helloworld_all_enable.smime");
3861+
const std::string permissions_file("permissions_helloworld.smime");
3862+
CommonPermissionsConfigure(secure_reader, secure_writer, governance_file, permissions_file);
3863+
3864+
secure_writer.history_depth(10).
3865+
reliability(eprosima::fastrtps::RELIABLE_RELIABILITY_QOS).init();
3866+
3867+
ASSERT_TRUE(secure_writer.isInitialized());
3868+
3869+
non_secure_reader.history_depth(10).
3870+
reliability(eprosima::fastrtps::RELIABLE_RELIABILITY_QOS).init();
3871+
3872+
ASSERT_TRUE(non_secure_reader.isInitialized());
3873+
3874+
secure_reader.history_depth(10).
3875+
reliability(eprosima::fastrtps::RELIABLE_RELIABILITY_QOS).init();
3876+
3877+
ASSERT_TRUE(secure_reader.isInitialized());
3878+
3879+
// Wait for the authorization
3880+
secure_reader.waitAuthorized();
3881+
secure_writer.waitAuthorized();
3882+
3883+
// Wait for discovery
3884+
secure_writer.wait_discovery(std::chrono::seconds(5));
3885+
secure_reader.wait_discovery(std::chrono::seconds(5));
3886+
3887+
// Data is correctly sent and received
3888+
auto data = default_helloworld_data_generator();
3889+
3890+
secure_reader.startReception(data);
3891+
3892+
secure_writer.send(data);
3893+
3894+
// In this test all data should be sent.
3895+
ASSERT_TRUE(data.empty());
3896+
3897+
secure_reader.block_for_all();
3898+
EXPECT_EQ(non_secure_reader.getReceivedCount(), 0u);
3899+
}
3900+
38513901
// *INDENT-OFF*
38523902
TEST_P(Security, BuiltinAuthenticationAndAccessAndCryptoPlugin_PermissionsDisableDiscoveryDisableAccessEncrypt_validation_ok_enable_discovery_enable_access_encrypt)
38533903
// *INDENT-ON*

0 commit comments

Comments
 (0)