ros2/rcpputils

find_library_path() for rmw fails when running node with root capabilities

wieset opened this issue · 4 comments

I already mentioned this in ros2/rcutils#143, but thought it would warrant its own issue, as the use case might be common.

If a binary is run with capabilities set via setcap or with the setuid bit, LD_LIBRARY_PATH is omitted during execution. Since find_library_path() relies exclusively on LD_LIBRARY_PATH, a ros2 node requiring root capabilities fails with

terminate called after throwing an instance of 'rclcpp::exceptions::RCLError'
  what():  failed to initialized rcl init options: failed to find shared library of rmw implementation. Searched rmw_fastrtps_cpp, at /tmp/binarydeb/ros-eloquent-rmw-implementation-0.8.2/src/functions.cpp:130, at /tmp/binarydeb/ros-eloquent-rcl-0.8.3/src/rcl/init_options.c:55

In our case, we need raw socket access in our node. Maybe introducing another environment variable like RMW_LIBRARY_PATH could solve this, or reading out RPATH from the binary header. Any suggestions for a workaround in the meantime would be greatly appreciated!

As per http://man7.org/linux/man-pages/man7/raw.7.html / https://linux.die.net/man/7/capabilities -

EDIT: can you give CAP_NET_RAW to your executable so that you can use raw sockets without being user 0? See "File capabilities" section (esp. setcap utility) in the linked capabilities documentation

EDIT 2: Oh - you already mentioned setcap and that it removes LD_LIBRARY_PATH - I do not have an immediate idea then

+1 on this.
I also think that libraries should be looked for in standard locations if the LD_LIBRARY_PATH env variable is not provided.

This is interesting. Thanks for posting! I'll read into it.

My use case:

  • build a yocto image in developer mode, with the layers in ros/meta-ros
  • run ros2 commands as root

Unexpectedly (for me that is), I got errors, and had to set LD_LIBRARY_PATH manually. After setting this, it worked, but I expected the RMW library loader to look into /usr/lib, this is where librmw_fastrtps_cpp.so is located. So, I set LD_LIBRARY_PATH to /usr/lib, which feels a bit weird. It works for now though, so this is good!

This is addressed by #122 -- you then have to add the library directories to ldconfig, but that should be okay for most use-cases.