Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UAF bug occurs during karto::Name::ToString() #696

Closed
GoesM opened this issue May 3, 2024 · 3 comments
Closed

UAF bug occurs during karto::Name::ToString() #696

GoesM opened this issue May 3, 2024 · 3 comments

Comments

@GoesM
Copy link

GoesM commented May 3, 2024

Required Info:

  • Operating System:
    • Ubuntu 22.04
  • Installation type:
    • source
  • ROS Version
    • ROS2-humble
  • Version or commit hash:
    • the latest
  • Laser unit:
    • defaulted

Steps to reproduce issue

I use slam-toolbox (async) by following command :

#!/bin/bash
export ASAN_OPTIONS=halt_on_error=0:new_delete_type_mismatch=0:detect_leaks=0:log_path=asan
source install/setup.bash
ros2 launch slam_toolbox online_async_launch.py

Running Slam-Toolbox within AddressSanitizer , I always faced to such UAF report during shutdown-period

Expected behavior

No UAF occurs

Actual behavior

we could always face to an ASAN-report about UAF bug as following:

=================================================================
==301204==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b00003e360 at pc 0x570803d9332a bp 0x7fa2ba2e8bb0 sp 0x7fa2ba2e8ba8
READ of size 8 at 0x60b00003e360 thread T20
    #0 0x570803d93329 in karto::Name::ToString[abi:cxx11]() const (/home/***/slam_toolbox/install/slam_toolbox/lib/slam_toolbox/async_slam_toolbox_node+0x13e329) (BuildId: 924645fe03080352703e9ddaaf3b488138509ed0)
    #1 0x570803d92c6d in karto::Name::operator<(karto::Name const&) const (/home/***/slam_toolbox/install/slam_toolbox/lib/slam_toolbox/async_slam_toolbox_node+0x13dc6d) (BuildId: 924645fe03080352703e9ddaaf3b488138509ed0)
    #2 0x7fa2cc1e7c3b in karto::SensorManager::GetSensorByName(karto::Name const&) (/home/***/slam_toolbox/install/slam_toolbox/lib/libtoolbox_common.so+0x1e7c3b) (BuildId: e9b06ded44457cd29634e461aae28bcce716a4ce)
    #3 0x7fa2c8004947 in karto::Mapper::Process(karto::LocalizedRangeScan*, karto::Matrix3*) (/home/***/slam_toolbox/install/slam_toolbox/lib/libkartoSlamToolbox.so+0x204947) (BuildId: 2dbb35367cda8afe894c24f7258cd868357940f7)
    #4 0x7fa2cc1cd78e in slam_toolbox::SlamToolbox::addScan(karto::LaserRangeFinder*, std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const> const&, karto::Pose2&) (/home/***/slam_toolbox/install/slam_toolbox/lib/libtoolbox_common.so+0x1cd78e) (BuildId: e9b06ded44457cd29634e461aae28bcce716a4ce)
    #5 0x7fa2cc6f80a8 in slam_toolbox::AsynchronousSlamToolbox::laserCallback(std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const>) (/home/***/slam_toolbox/install/slam_toolbox/lib/libasync_slam_toolbox.so+0x510a8) (BuildId: dfd93fd6d8c439ddd8872d21ec131f9383d9e085)
    #6 0x7fa2cc3b5356 in void std::__invoke_impl<void, void (slam_toolbox::SlamToolbox::*&)(std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const>), slam_toolbox::SlamToolbox*&, std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const> const&>(std::__invoke_memfun_deref, void (slam_toolbox::SlamToolbox::*&)(std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const>), slam_toolbox::SlamToolbox*&, std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const> const&) (/home/***/slam_toolbox/install/slam_toolbox/lib/libtoolbox_common.so+0x3b5356) (BuildId: e9b06ded44457cd29634e461aae28bcce716a4ce)
    #7 0x7fa2cc3b4b38 in message_filters::CallbackHelper1T<std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const> const&, sensor_msgs::msg::LaserScan_<std::allocator<void> > >::call(message_filters::MessageEvent<sensor_msgs::msg::LaserScan_<std::allocator<void> > const> const&, bool) (/home/***/slam_toolbox/install/slam_toolbox/lib/libtoolbox_common.so+0x3b4b38) (BuildId: e9b06ded44457cd29634e461aae28bcce716a4ce)
    #8 0x7fa2cc3ad065 in tf2_ros::MessageFilter<sensor_msgs::msg::LaserScan_<std::allocator<void> >, tf2_ros::Buffer>::transformReadyCallback(tf2_ros::TransformStampedFuture const&, unsigned long) (/home/***/slam_toolbox/install/slam_toolbox/lib/libtoolbox_common.so+0x3ad065) (BuildId: e9b06ded44457cd29634e461aae28bcce716a4ce)
    #9 0x7fa2cc5fde8d  (/opt/ros/humble/lib/libtf2_ros.so+0x4fe8d) (BuildId: dceacb25e05c8a82678784802b23fb16ba98d172)
    #10 0x7fa2ca76565e in tf2::BufferCore::testTransformableRequests() (/opt/ros/humble/lib/libtf2.so+0x1065e) (BuildId: 5677f8e557cfe0980662adcc0a17f03987f8b7f1)
    #11 0x7fa2ca7683fa in tf2::BufferCore::setTransformImpl(tf2::Transform const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) (/opt/ros/humble/lib/libtf2.so+0x133fa) (BuildId: 5677f8e557cfe0980662adcc0a17f03987f8b7f1)
    #12 0x7fa2ca768b29 in tf2::BufferCore::setTransform(geometry_msgs::msg::TransformStamped_<std::allocator<void> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) (/opt/ros/humble/lib/libtf2.so+0x13b29) (BuildId: 5677f8e557cfe0980662adcc0a17f03987f8b7f1)
    #13 0x7fa2cc606bb0 in tf2_ros::TransformListener::subscription_callback(std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const>, bool) (/opt/ros/humble/lib/libtf2_ros.so+0x58bb0) (BuildId: dceacb25e05c8a82678784802b23fb16ba98d172)
    #14 0x7fa2cbd9e7e9 in std::_Function_handler<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const>), std::_Bind<void (tf2_ros::TransformListener::* (tf2_ros::TransformListener*, std::_Placeholder<1>, bool))(std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const>, bool)> >::_M_invoke(std::_Any_data const&, std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const>&&) (/opt/ros/humble/lib/librviz_default_plugins.so+0x79e7e9) (BuildId: b9e8c9e8368837fa41d968409b5b6b05e426765a)
    #15 0x7fa2cbda95b1 in std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<void> (*)(rclcpp::AnySubscriptionCallback<tf2_msgs::msg::TFMessage_<std::allocator<void> >, std::allocator<void> >::dispatch(std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > >, rclcpp::MessageInfo const&)::'lambda'(auto&&)&&, std::variant<std::function<void (tf2_msgs::msg::TFMessage_<std::allocator<void> > const&)>, std::function<void (tf2_msgs::msg::TFMessage_<std::allocator<void> > const&, rclcpp::MessageInfo const&)>, std::function<void (rclcpp::SerializedMessage const&)>, std::function<void (rclcpp::SerializedMessage const&, rclcpp::MessageInfo const&)>, std::function<void (std::unique_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> >, std::default_delete<tf2_msgs::msg::TFMessage_<std::allocator<void> > > >)>, std::function<void (std::unique_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> >, std::default_delete<tf2_msgs::msg::TFMessage_<std::allocator<void> > > >, rclcpp::MessageInfo const&)>, std::function<void (std::unique_ptr<rclcpp::SerializedMessage, std::default_delete<rclcpp::SerializedMessage> >)>, std::function<void (std::unique_ptr<rclcpp::SerializedMessage, std::default_delete<rclcpp::SerializedMessage> >, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const>)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const>, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage const>)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage const>, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const> const&)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const> const&, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage const> const&)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage const> const&, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > >)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > >, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage>)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage>, rclcpp::MessageInfo const&)> >&)>, std::integer_sequence<unsigned long, 8ul> >::__visit_invoke(rclcpp::AnySubscriptionCallback<tf2_msgs::msg::TFMessage_<std::allocator<void> >, std::allocator<void> >::dispatch(std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > >, rclcpp::MessageInfo const&)::'lambda'(auto&&)&&, std::variant<std::function<void (tf2_msgs::msg::TFMessage_<std::allocator<void> > const&)>, std::function<void (tf2_msgs::msg::TFMessage_<std::allocator<void> > const&, rclcpp::MessageInfo const&)>, std::function<void (rclcpp::SerializedMessage const&)>, std::function<void (rclcpp::SerializedMessage const&, rclcpp::MessageInfo const&)>, std::function<void (std::unique_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> >, std::default_delete<tf2_msgs::msg::TFMessage_<std::allocator<void> > > >)>, std::function<void (std::unique_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> >, std::default_delete<tf2_msgs::msg::TFMessage_<std::allocator<void> > > >, rclcpp::MessageInfo const&)>, std::function<void (std::unique_ptr<rclcpp::SerializedMessage, std::default_delete<rclcpp::SerializedMessage> >)>, std::function<void (std::unique_ptr<rclcpp::SerializedMessage, std::default_delete<rclcpp::SerializedMessage> >, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const>)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const>, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage const>)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage const>, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const> const&)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > const> const&, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage const> const&)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage const> const&, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > >)>, std::function<void (std::shared_ptr<tf2_msgs::msg::TFMessage_<std::allocator<void> > >, rclcpp::MessageInfo const&)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage>)>, std::function<void (std::shared_ptr<rclcpp::SerializedMessage>, rclcpp::MessageInfo const&)> >&) (/opt/ros/humble/lib/librviz_default_plugins.so+0x7a95b1) (BuildId: b9e8c9e8368837fa41d968409b5b6b05e426765a)
    #16 0x7fa2cbdaa282  (/opt/ros/humble/lib/librviz_default_plugins.so+0x7aa282) (BuildId: b9e8c9e8368837fa41d968409b5b6b05e426765a)
    #17 0x7fa2c7cf07bb in rclcpp::Executor::execute_subscription(std::shared_ptr<rclcpp::SubscriptionBase>) (/opt/ros/humble/lib/librclcpp.so+0xe77bb) (BuildId: 4cca8a387f3c93d38a0567a8efc7cba9106f5d9a)
    #18 0x7fa2c7cf0fbe in rclcpp::Executor::execute_any_executable(rclcpp::AnyExecutable&) (/opt/ros/humble/lib/librclcpp.so+0xe7fbe) (BuildId: 4cca8a387f3c93d38a0567a8efc7cba9106f5d9a)
    #19 0x7fa2c7cf88af in rclcpp::executors::SingleThreadedExecutor::spin() (/opt/ros/humble/lib/librclcpp.so+0xef8af) (BuildId: 4cca8a387f3c93d38a0567a8efc7cba9106f5d9a)
    #20 0x7fa2c72dc252  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xdc252) (BuildId: e37fe1a879783838de78cbc8c80621fa685d58a2)
    #21 0x7fa2c6e94ac2 in start_thread nptl/./nptl/pthread_create.c:442:8
    #22 0x7fa2c6f2684f  misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

0x60b00003e360 is located 80 bytes inside of 112-byte region [0x60b00003e310,0x60b00003e380)
freed by thread T0 here:
    #0 0x570803d779cd in operator delete(void*) (/home/***/slam_toolbox/install/slam_toolbox/lib/slam_toolbox/async_slam_toolbox_node+0x1229cd) (BuildId: 924645fe03080352703e9ddaaf3b488138509ed0)
    #1 0x570803d84117 in std::_Rb_tree<karto::Name, std::pair<karto::Name const, karto::Sensor*>, std::_Select1st<std::pair<karto::Name const, karto::Sensor*> >, std::less<karto::Name>, std::allocator<std::pair<karto::Name const, karto::Sensor*> > >::_M_erase(std::_Rb_tree_node<std::pair<karto::Name const, karto::Sensor*> >*) (/home/***/slam_toolbox/install/slam_toolbox/lib/slam_toolbox/async_slam_toolbox_node+0x12f117) (BuildId: 924645fe03080352703e9ddaaf3b488138509ed0)

previously allocated by thread T0 here:
    #0 0x570803d7716d in operator new(unsigned long) (/home/***/slam_toolbox/install/slam_toolbox/lib/slam_toolbox/async_slam_toolbox_node+0x12216d) (BuildId: 924645fe03080352703e9ddaaf3b488138509ed0)
    #1 0x7fa2cc1e4559 in std::_Rb_tree_iterator<std::pair<karto::Name const, karto::Sensor*> > std::_Rb_tree<karto::Name, std::pair<karto::Name const, karto::Sensor*>, std::_Select1st<std::pair<karto::Name const, karto::Sensor*> >, std::less<karto::Name>, std::allocator<std::pair<karto::Name const, karto::Sensor*> > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<karto::Name const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<karto::Name const, karto::Sensor*> >, std::piecewise_construct_t const&, std::tuple<karto::Name const&>&&, std::tuple<>&&) (/home/***/slam_toolbox/install/slam_toolbox/lib/libtoolbox_common.so+0x1e4559) (BuildId: e9b06ded44457cd29634e461aae28bcce716a4ce)

Thread T20 created by T0 here:
    #0 0x570803d2581c in __interceptor_pthread_create (/home/***/slam_toolbox/install/slam_toolbox/lib/slam_toolbox/async_slam_toolbox_node+0xd081c) (BuildId: 924645fe03080352703e9ddaaf3b488138509ed0)
    #1 0x7fa2c72dc328 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/lib/x86_64-linux-gnu/libstdc++.so.6+0xdc328) (BuildId: e37fe1a879783838de78cbc8c80621fa685d58a2)
    #2 0x7fa2cc1a8700 in slam_toolbox::SlamToolbox::setROSInterfaces() (/home/***/slam_toolbox/install/slam_toolbox/lib/libtoolbox_common.so+0x1a8700) (BuildId: e9b06ded44457cd29634e461aae28bcce716a4ce)
    #3 0x7fa2cc19e0cc in slam_toolbox::SlamToolbox::configure() (/home/***/slam_toolbox/install/slam_toolbox/lib/libtoolbox_common.so+0x19e0cc) (BuildId: e9b06ded44457cd29634e461aae28bcce716a4ce)
    #4 0x570803d7a79c in main (/home/***/slam_toolbox/install/slam_toolbox/lib/slam_toolbox/async_slam_toolbox_node+0x12579c) (BuildId: 924645fe03080352703e9ddaaf3b488138509ed0)
    #5 0x7fa2c6e29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

SUMMARY: AddressSanitizer: heap-use-after-free (/home/***/slam_toolbox/install/slam_toolbox/lib/slam_toolbox/async_slam_toolbox_node+0x13e329) (BuildId: 924645fe03080352703e9ddaaf3b488138509ed0) in karto::Name::ToString[abi:cxx11]() const
Shadow bytes around the buggy address:
  0x0c167ffffc10: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x0c167ffffc20: 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa
  0x0c167ffffc30: fa fa fa fa fa fa 00 00 00 00 00 00 00 00 00 00
  0x0c167ffffc40: 00 00 00 fa fa fa fa fa fa fa fa fa 00 00 00 00
  0x0c167ffffc50: 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa
=>0x0c167ffffc60: fa fa fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd
  0x0c167ffffc70: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c167ffffc80: 00 00 00 00 00 fa fa fa fa fa fa fa fa fa 00 00
  0x0c167ffffc90: 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa fa
  0x0c167ffffca0: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c167ffffcb0: 00 00 fa fa fa fa fa fa fa fa 00 00 00 00 00 00
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
==301204==ABORTING

Additional information

This bug should be caused because:
During the shutdown-period, the excutor (which the function ``) is not stop before the destruction of the slam-toolbox node.

the function is bind to the callback-excutor here:

scan_filter_sub_ =
std::make_unique<message_filters::Subscriber<sensor_msgs::msg::LaserScan>>(
shared_from_this().get(), scan_topic_, rmw_qos_profile_sensor_data);
scan_filter_ =
std::make_unique<tf2_ros::MessageFilter<sensor_msgs::msg::LaserScan>>(
*scan_filter_sub_, *tf_, odom_frame_, scan_queue_size_, shared_from_this(),
tf2::durationFromSec(transform_timeout_.seconds()));
scan_filter_->registerCallback(
std::bind(&SlamToolbox::laserCallback, this, std::placeholders::_1));

BUT no excutor about freed during on_cleanup() and the destructor

SlamToolbox::~SlamToolbox()
/*****************************************************************************/
{
for (int i = 0; i != threads_.size(); i++) {
threads_[i]->join();
}
smapper_.reset();
dataset_.reset();
closure_assistant_.reset();
map_saver_.reset();
pose_helper_.reset();
laser_assistant_.reset();
scan_holder_.reset();
solver_.reset();
}

So that, the callback-function might be still working after the node is destructed and cause the UAF bug as a result.

@SteveMacenski
Copy link
Owner

Got it - so we just need to add the appropriate reset?

@GoesM
Copy link
Author

GoesM commented Jun 28, 2024

Sure, it's similar to #694, just issue about humble while seems to be fixed in iron and main

@SteveMacenski
Copy link
Owner

Got it, just backport and I'll merge! Continue conversation in #694!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants