Skip to content

Malformed serialized data in a data submessage leads to unhandled exception

High
MiguelCompany published GHSA-2rq6-8j7x-frr9 Aug 11, 2023

Package

Fast-DDS

Affected versions

2.9.1

Patched versions

2.11.0 / 2.10.2 / 2.9.2 / 2.6.5

Description

Summary

A data submessage sent to PDP port raises unhandled BadParamException in fastcdr, which in turn crashes fastdds.

Details

Please note that this is related to issue #3422, but a different code path is taken in CDR (hence a different strerror).
Found and tested on Fast-DDS 2.9.1, Ubuntu 20.04.

Stderr:

terminate called after throwing an instance of 'eprosima::fastcdr::exception::BadParamException'
  what():  Unexpected non-zero initial byte received in Cdr::read_encapsulation

Submessage that triggers the vuln:

submessageId: DATA (0x15)
    Flags: 0x05, Data present, Endianness bit
    octetsToNextHeader: 28
    0000 0000 0000 0000 = Extra flags: 0x0000
    Octets to inline QoS: 16
    readerEntityId: ENTITYID_UNKNOWN (0x00000000)
    writerEntityId: ENTITYID_UNKNOWN (0x00000000)
    writerSeqNumber: 7457626082161378294
    serializedData
        encapsulation kind: Unknown (0x0100)
        Encapsulation options (0x900)
            Compression class Id: NONE (0)
            Padding bytes: 0
        serializedData: 00010000

Hexdump of the submessage (last 8 bytes cause the issue):

0000   15 05 1c 00 00 00 10 00 00 00 00 00 00 00 00 00
0010   68 cf 7e 67 f6 c3 ea d6 01 00 09 00 00 01 00 00

GDB backtrace:

pwndbg> bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff4369859 in __GI_abort () at abort.c:79
#2  0x00007ffff4743911 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff474f38c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff474f3f7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff474f6a9 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff4c9eeaa in eprosima::fastcdr::exception::BadParamException::raise (this=0x60d0000068c0) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastcdr/src/cpp/exceptions/BadParamException.cpp:75
#7  0x00007ffff4c60694 in eprosima::fastcdr::Cdr::read_encapsulation (this=0x7fffef1d2540) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastcdr/src/cpp/Cdr.cpp:118
#8  0x0000000000510288 in Messenger::HelloWorldPubSubType::deserialize(eprosima::fastrtps::rtps::SerializedPayload_t*, void*) ()
#9  0x00007ffff646a4fd in eprosima::fastdds::dds::detail::ReadTakeCommand::deserialize_sample (this=0x7fffef1d30c0, change=0x611000015800) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/fastdds/subscriber/DataReaderImpl/ReadTakeCommand.hpp:366
#10 0x00007ffff6469382 in eprosima::fastdds::dds::detail::ReadTakeCommand::add_sample (this=0x7fffef1d30c0, item=@0x618000001080: 0x611000015800, deserialization_error=@0x7fffef1d2b30: false) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/fastdds/subscriber/DataReaderImpl/ReadTakeCommand.hp
p:337
#11 0x00007ffff6433c23 in eprosima::fastdds::dds::detail::ReadTakeCommand::add_instance (this=0x7fffef1d30c0, take_samples=true) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/fastdds/subscriber/DataReaderImpl/ReadTakeCommand.hpp:149
#12 0x00007ffff643922d in eprosima::fastdds::dds::DataReaderImpl::read_or_take_next_sample (this=0x61e00000a880, data=0x7fffef1d3580, info=0x7fffef1d35d0, should_take=true) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/fastdds/subscriber/DataReaderImpl.cpp:726
#13 0x00007ffff6439f9a in eprosima::fastdds::dds::DataReaderImpl::take_next_sample (this=0x61e00000a880, data=0x7fffef1d3580, info=0x7fffef1d35d0) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/fastdds/subscriber/DataReaderImpl.cpp:751
#14 0x00007ffff641c24e in eprosima::fastdds::dds::DataReader::take_next_sample (this=0x607000000a30, data=0x7fffef1d3580, info=0x7fffef1d35d0) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/fastdds/subscriber/DataReader.cpp:272
#15 0x0000000000559cab in HelloWorldSubscriber::SubListener::on_data_available(eprosima::fastdds::dds::DataReader*) ()
#16 0x00007ffff64433fd in eprosima::fastdds::dds::DataReaderImpl::InnerDataReaderListener::on_data_available (this=0x61e00000b178, writer_guid=..., first_sequence=..., last_sequence=..., should_notify_individual_changes=@0x7fffef1d3b80: false) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/
fastdds/subscriber/DataReaderImpl.cpp:904
#17 0x00007ffff60be0e0 in eprosima::fastrtps::rtps::StatelessReader::change_received (this=0x617000001900, change=0x611000015800) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/reader/StatelessReader.cpp:326
#18 0x00007ffff60c3f4e in eprosima::fastrtps::rtps::StatelessReader::processDataMsg (this=0x617000001900, change=0x7fffef1d6060) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/reader/StatelessReader.cpp:557
#19 0x00007ffff61636fe in eprosima::fastrtps::rtps::MessageReceiver::process_data_message_without_security(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)::$_0::operator()(eprosima::fastrtps::rtps::RTPSReader*) const (this=0x7fffef1d5660, reader=0x617000001900) at /home/seulba
e/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/messages/MessageReceiver.cpp:202
#20 0x00007ffff6127c8c in eprosima::fastrtps::rtps::MessageReceiver::findAllReaders<eprosima::fastrtps::rtps::MessageReceiver::process_data_message_without_security(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)::$_0>(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fas
trtps::rtps::MessageReceiver::process_data_message_without_security(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)::$_0 const&) const (this=0x614000007440, readerID=..., callback=...) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/messages/Messag
eReceiver.cpp:680
#21 0x00007ffff6125d9e in eprosima::fastrtps::rtps::MessageReceiver::process_data_message_without_security (this=0x614000007440, reader_id=..., change=...) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/messages/MessageReceiver.cpp:205
#22 0x00007ffff615e4f7 in std::__invoke_impl<void, void (eprosima::fastrtps::rtps::MessageReceiver::*&)(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&), eprosima::fastrtps::rtps::MessageReceiver*&, eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheCha
nge_t&> (__f=@0x603000004030: (void (eprosima::fastrtps::rtps::MessageReceiver::*)(class eprosima::fastrtps::rtps::MessageReceiver * const, const struct eprosima::fastrtps::rtps::EntityId_t &, struct eprosima::fastrtps::rtps::CacheChange_t &)) 0x7ffff6125c40 <eprosima::fastrtps::rtps::MessageReceiver::process_data_
message_without_security(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)>, __t=@0x603000004040: 0x614000007440, __args=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/invoke.h:73
#23 0x00007ffff615e131 in std::__invoke<void (eprosima::fastrtps::rtps::MessageReceiver::*&)(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&), eprosima::fastrtps::rtps::MessageReceiver*&, eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&> (_$
fn=@0x603000004030: (void (eprosima::fastrtps::rtps::MessageReceiver::*)(class eprosima::fastrtps::rtps::MessageReceiver * const, const struct eprosima::fastrtps::rtps::EntityId_t &, struct eprosima::fastrtps::rtps::CacheChange_t &)) 0x7ffff6125c40 <eprosima::fastrtps::rtps::MessageReceiver::process_data_message_wi
thout_security(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)>, __args=..., __args=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/invoke.h:95
#24 0x00007ffff615df25 in std::_Bind<void (eprosima::fastrtps::rtps::MessageReceiver::*(eprosima::fastrtps::rtps::MessageReceiver*, std::_Placeholder<1>, std::_Placeholder<2>))(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)>::__call<void, eprosima::fastrtps::rtps::EntityId_t
const&, eprosima::fastrtps::rtps::CacheChange_t&, 0ul, 1ul, 2ul>(std::tuple<eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&>&&, std::_Index_tuple<0ul, 1ul, 2ul>) (this=0x603000004030, __args=...) at /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/functional:400
#25 0x00007ffff615dc1c in std::_Bind<void (eprosima::fastrtps::rtps::MessageReceiver::*(eprosima::fastrtps::rtps::MessageReceiver*, std::_Placeholder<1>, std::_Placeholder<2>))(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)>::operator()<eprosima::fastrtps::rtps::EntityId_t co
nst&, eprosima::fastrtps::rtps::CacheChange_t&, void>(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&) (this=0x603000004030, __args=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/functional:482
#26 0x00007ffff615d6bb in std::_Function_handler<void (eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&), std::_Bind<void (eprosima::fastrtps::rtps::MessageReceiver::*(eprosima::fastrtps::rtps::MessageReceiver*, std::_Placeholder<1>, std::_Placeholder<2>))(eprosima::fastrtps::rt
ps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)> >::_M_invoke(std::_Any_data const&, eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&) (__functor=..., __args=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/std_function.h:300
#27 0x00007ffff6155b00 in std::function<void (eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&)>::operator()(eprosima::fastrtps::rtps::EntityId_t const&, eprosima::fastrtps::rtps::CacheChange_t&) const (this=0x614000007590, __args=..., __args=...) at /usr/lib/gcc/x86_64-linux-gn
u/9/../../../../include/c++/9/bits/std_function.h:688
#28 0x00007ffff6140f59 in eprosima::fastrtps::rtps::MessageReceiver::proc_Submsg_Data (this=0x614000007440, msg=0x7fffef1db5a0, smh=0x7fffef1d8070) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/messages/MessageReceiver.cpp:841
#29 0x00007ffff612fe07 in eprosima::fastrtps::rtps::MessageReceiver::processCDRMsg (this=0x614000007440, source_locator=..., reception_locator=..., msg=0x7fffef1db5a0) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/messages/MessageReceiver.cpp:418
#30 0x00007ffff61a62f7 in eprosima::fastrtps::rtps::ReceiverResource::OnDataReceived (this=0x610000000a40, data=0x63100003c800 "RTPS\002\002\377\377\001\017Eҳ\365X\271\001", size=64, localLocator=..., remoteLocator=...) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/network/ReceiverRes
ource.cpp:132
#31 0x00007ffff65dd754 in eprosima::fastdds::rtps::UDPChannelResource::perform_listen_operation (this=0x60d0000002b0, input_locator=...) at /home/seulbae/ddssecurity/targets/fastdds-2.9.1/src/fastrtps/src/cpp/rtps/transport/UDPChannelResource.cpp:70
#32 0x00007ffff65e82be in std::__invoke_impl<void, void (eprosima::fastdds::rtps::UDPChannelResource::*)(eprosima::fastrtps::rtps::Locator_t), eprosima::fastdds::rtps::UDPChannelResource*, eprosima::fastrtps::rtps::Locator_t> (__f=@0x606000000d68: (void (eprosima::fastdds::rtps::UDPChannelResource::*)(class eprosim
a::fastdds::rtps::UDPChannelResource * const, class eprosima::fastrtps::rtps::Locator_t)) 0x7ffff65dd2c0 <eprosima::fastdds::rtps::UDPChannelResource::perform_listen_operation(eprosima::fastrtps::rtps::Locator_t)>, __t=@0x606000000d60: 0x60d0000002b0, __args=...) at /usr/lib/gcc/x86_64-linux-gnu/9/../../../../inclu
de/c++/9/bits/invoke.h:73
#33 0x00007ffff65e7eab in std::__invoke<void (eprosima::fastdds::rtps::UDPChannelResource::*)(eprosima::fastrtps::rtps::Locator_t), eprosima::fastdds::rtps::UDPChannelResource*, eprosima::fastrtps::rtps::Locator_t> (__fn=@0x606000000d68: (void (eprosima::fastdds::rtps::UDPChannelResource::*)(class eprosima::fastdds
::rtps::UDPChannelResource * const, class eprosima::fastrtps::rtps::Locator_t)) 0x7ffff65dd2c0 <eprosima::fastdds::rtps::UDPChannelResource::perform_listen_operation(eprosima::fastrtps::rtps::Locator_t)>, __args=..., __args=...) at /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/invoke.h:95
#34 0x00007ffff65e7e1b in std::thread::_Invoker<std::tuple<void (eprosima::fastdds::rtps::UDPChannelResource::*)(eprosima::fastrtps::rtps::Locator_t), eprosima::fastdds::rtps::UDPChannelResource*, eprosima::fastrtps::rtps::Locator_t> >::_M_invoke<0ul, 1ul, 2ul> (this=0x606000000d48) at /usr/lib/gcc/x86_64-linux-gnu
/9/../../../../include/c++/9/thread:244
#35 0x00007ffff65e7d85 in std::thread::_Invoker<std::tuple<void (eprosima::fastdds::rtps::UDPChannelResource::*)(eprosima::fastrtps::rtps::Locator_t), eprosima::fastdds::rtps::UDPChannelResource*, eprosima::fastrtps::rtps::Locator_t> >::operator() (this=0x606000000d48) at /usr/lib/gcc/x86_64-linux-gnu/9/../../../..
/include/c++/9/thread:251
#36 0x00007ffff65e7699 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (eprosima::fastdds::rtps::UDPChannelResource::*)(eprosima::fastrtps::rtps::Locator_t), eprosima::fastdds::rtps::UDPChannelResource*, eprosima::fastrtps::rtps::Locator_t> > >::_M_run (this=0x606000000d40) at /usr/lib/gcc/x86_64-
linux-gnu/9/../../../../include/c++/9/thread:195
#37 0x00007ffff477bde4 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#38 0x00007ffff4c22609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#39 0x00007ffff4466133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Source: fastcdr/src/cpp/Cdr.cpp:77

        if (m_cdrType == DDS_CDR)
        {
            (*this) >> dummy;
            if (0 != dummy)
            {
                throw BadParamException("Unexpected non-zero initial byte received in Cdr::read_encapsulation");
            }
        }

(*this) >> dummy; invokes cdr's deserialize, which returns the following object:

$8 = {
  static DEFAULT_ENDIAN = eprosima::fastcdr::Cdr::LITTLE_ENDIANNESS,
  m_cdrBuffer = @0x7fffef1d26d0,
  m_cdrType = (unknown: 5309064),
  m_plFlag = eprosima::fastcdr::Cdr::DDS_CDR_WITHOUT_PL,
  m_options = 0,
  m_endianness = 179 '\263',
  m_swapBytes = 138,
  m_lastDataSize = 5764450,
  m_currentPosition = {
    m_buffer = 0x50ffc0 <Messenger::HelloWorldPubSubType::deserialize(eprosima::fastrtps::rtps::SerializedPayload_t*, void*)> "UH\211\345SH\203\344\340H\201", <incomplete sequence \354>,
    m_currentPosition = 0x6600 <error: Cannot access memory at address 0x6600>
  },
  m_alignPosition = {
    m_buffer = 0x7ffff4ca86f0 <vtable for eprosima::fastcdr::FastBuffer+16> "\360\331\311\364\377\177",
    m_currentPosition = 0x61200000a0cc "\001"
  },
  m_lastPosition = {
    m_buffer = 0x8 <error: Cannot access memory at address 0x8>,
    m_currentPosition = 0x7fffef1d3000 "fs\201\v"
  }
}

This assigns 0x1 to dummy, raising the exception.

Thank you.

PoC

Send the data submessage above to the PID_DEFAULT_UNICAST_LOCATOR at any moment (in this case, during PDP). Please refer to this pcap for details (Packet no. 183).

Impact

CWE-248 (uncaught exception)

Severity

High
8.2
/ 10

CVSS base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
None
Availability
High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H

CVE ID

CVE-2023-39945

Weaknesses

Credits