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

user-misconfiguration may cause a heap-buffer-overflow bug in nav2_amcl #4157

Closed
GoesM opened this issue Feb 29, 2024 · 8 comments
Closed

user-misconfiguration may cause a heap-buffer-overflow bug in nav2_amcl #4157

GoesM opened this issue Feb 29, 2024 · 8 comments

Comments

@GoesM
Copy link
Contributor

GoesM commented Feb 29, 2024

Bug report

Required Info:

  • Operating System:
    • Ubuntu 22.04
  • ROS2 Version:
    • humble
  • Version or commit hash:
    • the latest
  • DDS implementation:
    • default

Steps to reproduce issue

launch the navigation2 within defaulted tb3_simulation_launch.py as following commands

source install/setup.bash
source /opt/ros/humble/setup.bash
export TURTLEBOT3_MODEL=waffle
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/opt/ros/humble/share/turtlebot3_gazebo/models
ros2 launch nav2_bringup tb3_simulation_launch.py params_file:=my_nav2_params.yaml

there's only one difference between my_nav2_params.yaml and defaulted nav2_params.yaml,(we wrongly set amcl->ros_parameters->z_rand as a very large value ), as following:

amcl:
  ros__parameters:
    ...
    ...
    z_rand: 54861240687936886832559362511872092700743926359323919340246415125412623597951915939539289081689902927585003914562122604.0  # (such value is derived from our fuzzy testing.)
    ...
    ...

then, just wait for the navigation2 launching.

Expected behavior

Processes should not crash, or at least processes should not result in heap buffer overflow, thereby providing the possibility for hackers to inject malicious code.

Actual behavior

  • we would find a asan report after (steps to reproduce issue) done:
#asan报告
=================================================================
==10254==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x63000000fe00 at pc 0x556909308687 bp 0x7f2f3d49c4b0 sp 0x7f2f3d49bc80
READ of size 24 at 0x63000000fe00 thread T11
    #0 0x7f2f45b7ca7c in pf_update_resample (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libpf_lib.so+0x8a7c) (BuildId: 73e413561c1948e30ca366fe29aeef8e601b70f9)
    #1 0x7f2f4617704b in nav2_amcl::AmclNode::laserReceived(std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const>) (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x37704b) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #2 0x7f2f463406a9 in void std::__invoke_impl<void, void (nav2_amcl::AmclNode::*&)(std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const>), nav2_amcl::AmclNode*&, std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const> const&>(std::__invoke_memfun_deref, void (nav2_amcl::AmclNode::*&)(std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const>), nav2_amcl::AmclNode*&, std::shared_ptr<sensor_msgs::msg::LaserScan_<std::allocator<void> > const> const&) (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x5406a9) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #3 0x7f2f4633fe35 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/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x53fe35) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #4 0x7f2f462f342b in message_filters::Signal1<sensor_msgs::msg::LaserScan_<std::allocator<void> > >::call(message_filters::MessageEvent<sensor_msgs::msg::LaserScan_<std::allocator<void> > const> const&) (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x4f342b) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #5 0x7f2f46338790 in tf2_ros::MessageFilter<sensor_msgs::msg::LaserScan_<std::allocator<void> >, tf2_ros::Buffer>::transformReadyCallback(tf2_ros::TransformStampedFuture const&, unsigned long) (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x538790) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #6 0x7f2f4633cc6e in std::_Function_handler<void (tf2_ros::TransformStampedFuture const&), std::_Bind<void (tf2_ros::MessageFilter<sensor_msgs::msg::LaserScan_<std::allocator<void> >, tf2_ros::Buffer>::* (tf2_ros::MessageFilter<sensor_msgs::msg::LaserScan_<std::allocator<void> >, tf2_ros::Buffer>*, std::_Placeholder<1>, unsigned long))(tf2_ros::TransformStampedFuture const&, unsigned long)> >::_M_invoke(std::_Any_data const&, tf2_ros::TransformStampedFuture const&) (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x53cc6e) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #7 0x7f2f47620e8d  (/opt/ros/humble/lib/libtf2_ros.so+0x4fe8d) (BuildId: 5fe744f3037178d67abb96013375a405993407b9)
    #8 0x7f2f4759c5fe in tf2::BufferCore::testTransformableRequests() (/opt/ros/humble/lib/libtf2.so+0x105fe) (BuildId: 3fd150ee62f6512f752884e3ecc762fe9ad1e1e6)
    #9 0x7f2f4759f321 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+0x13321) (BuildId: 3fd150ee62f6512f752884e3ecc762fe9ad1e1e6)
    #100x7f2f4759fb69 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+0x13b69) (BuildId: 3fd150ee62f6512f752884e3ecc762fe9ad1e1e6)
    #11 0x7f2f47629bb0 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: 5fe744f3037178d67abb96013375a405993407b9)
    #12 0x7f2f47629a89 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/libtf2_ros.so+0x58a89) (BuildId: 5fe744f3037178d67abb96013375a405993407b9)
    #13 0x7f2f4763e601 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/libtf2_ros.so+0x6d601) (BuildId: 5fe744f3037178d67abb96013375a405993407b9)
    #14 0x7f2f4763d93e  (/opt/ros/humble/lib/libtf2_ros.so+0x6c93e) (BuildId: 5fe744f3037178d67abb96013375a405993407b9)
    #15 0x7f2f471db7bb in rclcpp::Executor::execute_subscription(std::shared_ptr<rclcpp::SubscriptionBase>) (/opt/ros/humble/lib/librclcpp.so+0xe77bb) (BuildId: 92476726abf0a3ea3241f920cd3eedb4c1b1b3ac)
    #16 0x7f2f471dbfbe in rclcpp::Executor::execute_any_executable(rclcpp::AnyExecutable&) (/opt/ros/humble/lib/librclcpp.so+0xe7fbe) (BuildId: 92476726abf0a3ea3241f920cd3eedb4c1b1b3ac)
    #17 0x7f2f471e38af in rclcpp::executors::SingleThreadedExecutor::spin() (/opt/ros/humble/lib/librclcpp.so+0xef8af) (BuildId: 92476726abf0a3ea3241f920cd3eedb4c1b1b3ac)
    #18 0x7f2f458dc252  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xdc252) (BuildId: e37fe1a879783838de78cbc8c80621fa685d58a2)
    #19 0x7f2f45494ac2 in start_thread nptl/./nptl/pthread_create.c:442:8
    #20 0x7f2f4552684f  misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

0x63000000fe00 is located 0 bytes to the right of 64000-byte region [0x630000000400,0x63000000fe00)
allocated by thread T0 here:
    #0 0x556909309548 in __interceptor_calloc (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/nav2_amcl/amcl+0xae548) (BuildId: 9cab2dfb4fd0f7edff9ad0c4896458037daa0009)
    #1 0x7f2f45b78afa in pf_alloc (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libpf_lib.so+0x4afa) (BuildId: 73e413561c1948e30ca366fe29aeef8e601b70f9)
    #2 0x7f2f46159b4b in nav2_amcl::AmclNode::on_configure(rclcpp_lifecycle::State const&) (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x359b4b) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #3 0x7f2f470d7b8c  (/opt/ros/humble/lib/librclcpp_lifecycle.so+0x28b8c) (BuildId: 012115a5136d65f945feb1fe7a699e9903b4add1)

Thread T11 created by T0 here:
    #0 0x5569092f27dc in __interceptor_pthread_create (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/nav2_amcl/amcl+0x977dc) (BuildId: 9cab2dfb4fd0f7edff9ad0c4896458037daa0009)
    #1 0x7f2f458dc328 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 0x7f2f462d3359 in std::_Sp_counted_ptr_inplace<tf2_ros::TransformListener, std::allocator<tf2_ros::TransformListener>, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace<tf2_ros::Buffer&>(std::allocator<tf2_ros::TransformListener>, tf2_ros::Buffer&) (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x4d3359) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #3 0x7f2f46160ad2 in nav2_amcl::AmclNode::initTransforms() (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x360ad2) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #4 0x7f2f46159aa9 in nav2_amcl::AmclNode::on_configure(rclcpp_lifecycle::State const&) (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/libamcl_core.so+0x359aa9) (BuildId: fcf524e51612a7063856b255b0200fa30f1c8a67)
    #5 0x7f2f470d7b8c  (/opt/ros/humble/lib/librclcpp_lifecycle.so+0x28b8c) (BuildId: 012115a5136d65f945feb1fe7a699e9903b4add1)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/****/ROS_ws/nav2/install/nav2_amcl/lib/nav2_amcl/amcl+0xad686) (BuildId: 9cab2dfb4fd0f7edff9ad0c4896458037daa0009) in __asan_memcpy
Shadow bytes around the buggy address:
  0x0c607fff9f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c607fff9f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c607fff9f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c607fff9fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c607fff9fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c607fff9fc0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c607fff9fd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c607fff9fe0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c607fff9ff0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c607fffa000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c607fffa010: 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
==10254==ABORTING

Additional information


It's understood that "It is more a matter of time / inclination to set bounds on all N params in the stack (and make sure the dynamic parameter callbacks are respecting them too). " by us. Therefore, some bugs in navigation2 resulting from user-misconfiguration that lead to Denial of Service (DoS) behavior can actually be resolved by users themselves.

However, bugs like heap-buffer-overflow may pose security issues within system software. Attackers can exploit heap buffer overflow to overwrite function pointers or program counters, thereby injecting malicious code into the program for execution, escalating to more serious security concerns.

a suggestion that may be helpful:

  • necessary parameter checks, which may pose security risks, should be implemented. shall we add a param value check for z_rand in nav2_amcl to avoid such heap-buffer-overflow bug?
@SteveMacenski
Copy link
Member

That's an insane number, I wouldn't expect anything else to happen.

Added to the #4005 - I think we discussed last time its a low-priority task to protect every parameter's potential reasonable bounds, since that would take weeks and you're only finding these by setting insane values. If you find more in the future, feel free to append to your ticket (#4005).

@GoesM
Copy link
Contributor Author

GoesM commented Mar 1, 2024

feel free to append to your ticket(#4005)

no problem, I got it ^_^

@SteveMacenski
Copy link
Member

SteveMacenski commented Mar 1, 2024

I will say that if this interests you to address, something I thought of was adding a Nav2 util eq of ‘get_parameter’ whos arguments can include min-max ranges for ints & doubles and throws if not met. That would be a relatively time consuming, but feasible for someone that wants it, action.

Then the hard work comes to populating all those ranges. I figure one node at a time, once per week is a good way to break it into managable chunks.

Dynamic parameter updates are another issue. Perhaps we could refactor the params for all nodes/servers into their own param handler util (some have already) so all that range checking is handled in a separate file to keep the algorithm implementations cleaner. If we wanted to go even a bridge further, we could change all member params into rclcpp::Parameters that have valid ranges in their descriptions.

There’s actually not a shortage of good technical solutions. Its simply the scale that is daunting. But if that was important to you, I’d be happy to help flush out your design and then knock out the packages one at a time over a couple of months.

@GoesM
Copy link
Contributor Author

GoesM commented Mar 1, 2024

We have some concerns about such security issue, while it is also a relatively low priority issue for us. Our submission of such issues mainly aims to provide a reminder and record of such issue for the navigation2 stack. Should we discover similar parameter issues in the future, we will add them directly to the ticket #4005 rather than open a new issue.

adding a Nav2 util eq of ‘get_parameter’ whos arguments can include min-max ranges for ints & doubles and throws if not met

it seems feasible, is it in need for us to open a PR for it?

@SteveMacenski
Copy link
Member

I try not do to do things half baked, since there may be some functional problems that require reworking the problem, but I was thinking something like

rclcpp::Parameter get_parameter<TypeT>(Node & node, string param_name, TypeT min, TypeT max)
{
  rclcpp::Parameter param;
  if (node->get_parameter(param_name, param)) {
    if (param >= min && min <= max) {
      return param;
    }
    // throw exception, out of bounds 
  }
  // throw exception, did not obtain
}

Then the TypeT of this function have overrides for the different versions. The double/int use something like this, but the string/bool just do the normal get parameter logic. It would be expanded with the double/int arrays to also check those parameters' values in the array AND also check the array size.

A couple of open questions:

  • Which rclcpp get_parameters API makes most sense: the bool check or let it throw itself one if it doesn't exist?
  • Even if we replace inline with this everywhere, how do we want to handle the dynamic parameters callback function

@GoesM
Copy link
Contributor Author

GoesM commented Mar 4, 2024

I try not do to do things half baked

So do I, while It seems I need some time to delve deeper into this section of code and the API. I'd come back here to discuss further once I have more matured ideas.

@GoesM
Copy link
Contributor Author

GoesM commented Mar 22, 2024

I spent some time studying the code in the ros2/rclcpp repository, and I noticed that the current code for get_parameter() in rclcpp doesn't seem to provide an interface for setting valid boundaries such as maximum and minimum values. Do you suggest that I propose such a design to rclcpp first and then apply it to nav2 later?

@SteveMacenski
Copy link
Member

SteveMacenski commented Mar 22, 2024

The ‘ParameterDescriptor‘ has that!

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