[BUG]: Heap Out-of-Bounds Write in E2E Profile-07 Protector
- Dominant language
- C++
- Stars
- 1.4k
- Forks
- 826
- PR merge metrics
- No merged PRs in 30d
Description
### vSomeip Version
7bcc1e06f16a774e70931ed641f475fbba9c8c64
### Boost Version
1.9.0
### Environment
Ubuntu 24.04
### Describe the bug
## Summary
A single, unmodified local IPC `REQUEST`, sent through vsomeip's public API, reliably triggers a heap out-of-bounds write in the vsomeip routing-manager daemon due to missing bounds checking on an operator-configured offset, resulting in a crash.
## Root Cause
`implementation/e2e_protection/src/e2e/profile/profile07/protector.cpp:24-36`
```cpp
bool protector::verify_inputs(e2e_buffer& _buffer) {
return (_buffer.size() >= config_.min_data_length_
&& _buffer.size() <= config_.max_data_length_); // never checks offset_
}
```
`protect()` writes 20 bytes (CRC, size, counter, and data ID) to the message buffer at `config_.offset_`. The value of `offset_` is taken from the operator-configured `crc_offset`, while the buffer size is determined directly by the attacker-controlled `REQUEST` payload length. No check ensures that `offset_ + 20 <= buffer.size()`, allowing a sufficiently short `REQUEST` to cause the write to extend beyond the heap allocation.
### Reproduction Steps
e2e_provider.json:
```
{
"unicast": "127.0.0.1",
"logging": { "level": "info", "console": "true", "dlt": "false",
"version": { "enable": "false" }, "statistics": { "interval": "0" } },
"applications": [
{ "name": "routingmanagerd", "id": "0x1343" },
{ "name": "request-sample", "id": "0x1533" }
],
"services": [
{ "service": "0x1234", "instance": "0x5678", "unicast": "127.0.0.2", "unreliable": "$REMOTE_PORT" }
],
"e2e": {
"e2e_enabled": "true",
"protected": [
{ "service_id": "0x1234", "event_id": "0x0421", "variant": "protector", "profile": "P07",
"data_id": "0x1", "crc_offset": "144", "min_data_length": "0", "max_data_length": "4194304",
"max_delta_counter": "4294967295" }
]
},
"routing": "routingmanagerd",
"service-discovery": { "enable": "false" }
}
```
```
export VSOMEIP_CONFIGURATION=$PWD/../e2e_provider.json
export VSOMEIP_APPLICATION_NAME=routingmanagerd
export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
./examples/routingmanagerd/routingmanagerd
```
```
export VSOMEIP_APPLICATION_NAME=request-sample
./examples/request-sample
```
### Expected behaviour
_No response_
### Logs and Screenshots
```
=================================================================
==6195==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50300000d9aa at pc 0x7ef658e6f68a bp 0x7ffe818a9440 sp 0x7ffe818a9430
WRITE of size 4 at 0x50300000d9aa thread T0
#0 0x7ef658e6f689 in memcpy /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
#1 0x7ef658e6f689 in vsomeip_v3::bithelper::write_uint32_be(unsigned int, unsigned char*) /root/vsomeip-src/implementation/e2e_protection/src/e2e/profile/profile07/../../../../../utility/include/bithelper.hpp:41
#2 0x7ef658e6f689 in vsomeip_v3::e2e::profile07::protector::protect(std::vector >&, unsigned short) /root/vsomeip-src/implementation/e2e_protection/src/e2e/profile/profile07/protector.cpp:24
#3 0x7ef658e3b89e in vsomeip_v3::e2e::e2e_provider_impl::protect(std::pair, std::vector >&, unsigned short) /root/vsomeip-src/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp:117
#4 0x7ef659ef951e in vsomeip_v3::routing_manager_impl::send(unsigned short, unsigned char const*, unsigned int, unsigned short, bool, unsigned short, vsomeip_sec_client_t const*, unsigned char, bool, bool) /root/vsomeip-src/implementation/routing/src/routing_manager_impl.cpp:712
#5 0x7ef659f5c23c in vsomeip_v3::routing_manager_impl::on_message(unsigned short, unsigned short, unsigned char const*, unsigned int, bool, unsigned short, vsomeip_sec_client_t const*, unsigned char, bool) /root/vsomeip-src/implementation/routing/src/routing_manager_impl.cpp:1213
#6 0x7ef659ffcc7d in vsomeip_v3::routing_manager_stub::on_message(unsigned char const*, unsigned int, vsomeip_v3::local_client_data const&) /root/vsomeip-src/implementation/routing/src/routing_manager_stub.cpp:394
#7 0x7ef659b18b62 in vsomeip_v3::local_endpoint::process(unsigned long, std::unique_lock&) /root/vsomeip-src/implementation/endpoints/src/local_endpoint.cpp:480
#8 0x7ef659b1bc03 in vsomeip_v3::local_endpoint::receive_cbk(boost::system::error_code const&, unsigned long) /root/vsomeip-src/implementation/endpoints/src/local_endpoint.cpp:510
#9 0x7ef659b1c1b5 in operator() /root/vsomeip-src/implementation/endpoints/src/local_endpoint.cpp:315
#10 0x7ef659b1c1b5 in __invoke_impl&, const boost::system::error_code&, long unsigned int> /usr/include/c++/13/bits/invoke.h:61
#11 0x7ef659b1c1b5 in __invoke_r&, const boost::system::error_code&, long unsigned int> /usr/include/c++/13/bits/invoke.h:111
#12 0x7ef659b1c1b5 in _M_invoke /usr/include/c++/13/bits/std_function.h:290
#13 0x7ef65999dbb1 in std::function::operator()(boost::system::error_code const&, unsigned long) const /usr/include/c++/13/bits/std_function.h:591
#14 0x7ef65999dbb1 in boost::asio::detail::binder2, boost::system::error_code, unsigned long>::operator()() /usr/include/boost/asio/detail/bind_handler.hpp:289
#15 0x7ef65999dbb1 in void boost::asio::asio_handler_invoke, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2, boost::system::error_code, unsigned long>&, ...) /usr/include/boost/asio/handler_invoke_hook.hpp:88
#16 0x7ef65999dbb1 in void boost_asio_handler_invoke_helpers::invoke, boost::system::error_code, unsigned long>, std::function >(boost::asio::detail::binder2, boost::system::error_code, unsigned long>&, std::function&) /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:54
#17 0x7ef65999dbb1 in void boost::asio::detail::handler_work, boost::asio::any_io_executor, void>::complete, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2, boost::system::error_code, unsigned long>&, std::function&) /usr/include/boost/asio/detail/handler_work.hpp:524
#18 0x7ef65999dbb1 in void boost::asio::detail::handler_work, boost::asio::any_io_executor, void>::complete, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2, boost::system::error_code, unsigned long>&, std::function&) /usr/include/boost/asio/detail/handler_work.hpp:517
#19 0x7ef65999dbb1 in boost::asio::detail::reactive_socket_recv_op, boost::asio::any_io_executor>::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:152
#20 0x7ef65995e475 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40
#21 0x7ef65995e475 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) /usr/include/boost/asio/detail/impl/scheduler.ipp:493
#22 0x7ef65a03d26c in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:210
#23 0x7ef65a08f06a in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:64
#24 0x7ef65a08f06a in vsomeip_v3::application_impl::start() /root/vsomeip-src/implementation/runtime/src/application_impl.cpp:438
#25 0x64272e373e2e in routingmanagerd_process(bool) /root/vsomeip-src/examples/routingmanagerd/routingmanagerd.cpp:84
#26 0x64272e372ed1 in main /root/vsomeip-src/examples/routingmanagerd/routingmanagerd.cpp:165
#27 0x7ef6592951c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb)
#28 0x7ef65929528a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb)
#29 0x64272e3732e4 in _start (/root/examples/routingmanagerd/routingmanagerd+0x32e4) (BuildId: e8230ce52791428ee3a618a4c58cdf6db802cf63)
0x50300000d9aa is located 8 bytes after 18-byte region [0x50300000d990,0x50300000d9a2)
allocated by thread T0 here:
#0 0x7ef65a4a9548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
#1 0x7ef659eaa168 in void std::vector >::_M_assign_aux(unsigned char const*, unsigned char const*, std::forward_iterator_tag) /usr/include/c++/13/bits/new_allocator.h:151
#2 0x7ef659ef9419 in void std::vector >::assign(unsigned char const*, unsigned char const*) /usr/include/c++/13/bits/stl_vector.h:829
#3 0x7ef659ef9419 in vsomeip_v3::routing_manager_impl::send(unsigned short, unsigned char const*, unsigned int, unsigned short, bool, unsigned short, vsomeip_sec_client_t const*, unsigned char, bool, bool) /root/vsomeip-src/implementation/routing/src/routing_manager_impl.cpp:710
#4 0x7ef659f5c23c in vsomeip_v3::routing_manager_impl::on_message(unsigned short, unsigned short, unsigned char const*, unsigned int, bool, unsigned short, vsomeip_sec_client_t const*, unsigned char, bool) /root/vsomeip-src/implementation/routing/src/routing_manager_impl.cpp:1213
#5 0x7ef659ffcc7d in vsomeip_v3::routing_manager_stub::on_message(unsigned char const*, unsigned int, vsomeip_v3::local_client_data const&) /root/vsomeip-src/implementation/routing/src/routing_manager_stub.cpp:394
#6 0x7ef659b18b62 in vsomeip_v3::local_endpoint::process(unsigned long, std::unique_lock&) /root/vsomeip-src/implementation/endpoints/src/local_endpoint.cpp:480
#7 0x7ef659b1bc03 in vsomeip_v3::local_endpoint::receive_cbk(boost::system::error_code const&, unsigned long) /root/vsomeip-src/implementation/endpoints/src/local_endpoint.cpp:510
#8 0x7ef659b1c1b5 in operator() /root/vsomeip-src/implementation/endpoints/src/local_endpoint.cpp:315
#9 0x7ef659b1c1b5 in __invoke_impl&, const boost::system::error_code&, long unsigned int> /usr/include/c++/13/bits/invoke.h:61
#10 0x7ef659b1c1b5 in __invoke_r&, const boost::system::error_code&, long unsigned int> /usr/include/c++/13/bits/invoke.h:111
#11 0x7ef659b1c1b5 in _M_invoke /usr/include/c++/13/bits/std_function.h:290
#12 0x7ef65999dbb1 in std::function::operator()(boost::system::error_code const&, unsigned long) const /usr/include/c++/13/bits/std_function.h:591
#13 0x7ef65999dbb1 in boost::asio::detail::binder2, boost::system::error_code, unsigned long>::operator()() /usr/include/boost/asio/detail/bind_handler.hpp:289
#14 0x7ef65999dbb1 in void boost::asio::asio_handler_invoke, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2, boost::system::error_code, unsigned long>&, ...) /usr/include/boost/asio/handler_invoke_hook.hpp:88
#15 0x7ef65999dbb1 in void boost_asio_handler_invoke_helpers::invoke, boost::system::error_code, unsigned long>, std::function >(boost::asio::detail::binder2, boost::system::error_code, unsigned long>&, std::function&) /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:54
#16 0x7ef65999dbb1 in void boost::asio::detail::handler_work, boost::asio::any_io_executor, void>::complete, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2, boost::system::error_code, unsigned long>&, std::function&) /usr/include/boost/asio/detail/handler_work.hpp:524
#17 0x7ef65999dbb1 in void boost::asio::detail::handler_work, boost::asio::any_io_executor, void>::complete, boost::system::error_code, unsigned long> >(boost::asio::detail::binder2, boost::system::error_code, unsigned long>&, std::function&) /usr/include/boost/asio/detail/handler_work.hpp:517
#18 0x7ef65999dbb1 in boost::asio::detail::reactive_socket_recv_op, boost::asio::any_io_executor>::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:152
#19 0x7ef65995e475 in boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) /usr/include/boost/asio/detail/scheduler_operation.hpp:40
#20 0x7ef65995e475 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) /usr/include/boost/asio/detail/impl/scheduler.ipp:493
#21 0x7ef65a03d26c in boost::asio::detail::scheduler::run(boost::system::error_code&) /usr/include/boost/asio/detail/impl/scheduler.ipp:210
#22 0x7ef65a08f06a in boost::asio::io_context::run() /usr/include/boost/asio/impl/io_context.ipp:64
#23 0x7ef65a08f06a in vsomeip_v3::application_impl::start() /root/vsomeip-src/implementation/runtime/src/application_impl.cpp:438
#24 0x64272e373e2e in routingmanagerd_process(bool) /root/vsomeip-src/examples/routingmanagerd/routingmanagerd.cpp:84
#25 0x64272e372ed1 in main /root/vsomeip-src/examples/routingmanagerd/routingmanagerd.cpp:165
#26 0x7ef6592951c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb)
#27 0x7ef65929528a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 8e9fd827446c24067541ac5390e6f527fb5947bb)
#28 0x64272e3732e4 in _start (/root/examples/routingmanagerd/routingmanagerd+0x32e4) (BuildId: e8230ce52791428ee3a618a4c58cdf6db802cf63)
SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29 in memcpy
Shadow bytes around the buggy address:
0x50300000d700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300000d780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300000d800: fa fa 00 00 00 fa fa fa 00 00 00 fa fa fa fd fd
0x50300000d880: fd fd fa fa fd fd fd fa fa fa 00 00 00 00 fa fa
0x50300000d900: 00 00 00 00 fa fa 00 00 00 02 fa fa 00 00 00 02
=>0x50300000d980: fa fa 00 00 02[fa]fa fa fa fa fa fa fa fa fa fa
0x50300000da00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300000da80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300000db00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300000db80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x50300000dc00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==6195==ABORTING
```
Contributor guide
Research direction
Start with implementation/e2e_protection/src/e2e/profile/profile07/protector.cpp:24-36 and trace the protect call from e2e_provider_impl.cpp:117. Run the provided routingmanagerd and request-sample reproduction with AddressSanitizer. Done means the configured offset cannot cause a write beyond the message buffer and the reproduction no longer reports a heap-buffer-overflow.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 70/100