ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

RPATH in installed executable

asked 2018-06-04 19:08:33 -0500

rohbotics gravatar image

I am trying to make a ROS node that runs as setuid (I know, but it has to run as root).

When building from source using 'catkin_make' and then chmoding to 4755, everything works fine.

But when building a debian from that source, (and adding a postinst for chmoding to 4755), it fails to resolve any dynamic libraries.

This seems to be because the installed version of the executable doesn't include RPATH.

If I add it manually with sudo patchelf --force-rpath --set-rpath '/opt/ros/kinetic/lib/' /opt/ros/kinetic/lib/pi_sonar/pi_sonar, everything works again.

How do I force the debians coming from the bloom generated gbp to embed the RPATH into the executable?

Output of readelf -d on the catkin_make version

  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libtf2_ros.so]
 0x00000001 (NEEDED)                     Shared library: [libactionlib.so]
 0x00000001 (NEEDED)                     Shared library: [libtf2.so]
 0x00000001 (NEEDED)                     Shared library: [libroscpp.so]
 0x00000001 (NEEDED)                     Shared library: [librosconsole.so]
 0x00000001 (NEEDED)                     Shared library: [libroscpp_serialization.so]
 0x00000001 (NEEDED)                     Shared library: [librostime.so]
 0x00000001 (NEEDED)                     Shared library: [libboost_system.so.1.58.0]
 0x00000001 (NEEDED)                     Shared library: [libboost_thread.so.1.58.0]
 0x00000001 (NEEDED)                     Shared library: [libpthread.so.0]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x00000001 (NEEDED)                     Shared library: [ld-linux-armhf.so.3]
 0x0000000f (RPATH)                      Library rpath: [/opt/ros/kinetic/lib:/usr/lib/arm-linux-gnueabihf/hdf5/openmpi/lib:/usr/lib/openmpi/lib:]

Output of readelf -d on the debian version (notice no rpath).

  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libtf2_ros.so]
 0x00000001 (NEEDED)                     Shared library: [libactionlib.so]
 0x00000001 (NEEDED)                     Shared library: [libtf2.so]
 0x00000001 (NEEDED)                     Shared library: [libroscpp.so]
 0x00000001 (NEEDED)                     Shared library: [librosconsole.so]
 0x00000001 (NEEDED)                     Shared library: [libroscpp_serialization.so]
 0x00000001 (NEEDED)                     Shared library: [librostime.so]
 0x00000001 (NEEDED)                     Shared library: [libboost_system.so.1.58.0]
 0x00000001 (NEEDED)                     Shared library: [libboost_thread.so.1.58.0]
 0x00000001 (NEEDED)                     Shared library: [libpthread.so.0]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x00000001 (NEEDED)                     Shared library: [ld-linux-armhf.so.3]
 0x0000000c (INIT)                       0x3b928
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
3

answered 2018-06-04 19:56:22 -0500

ahendrix gravatar image

It looks like this is the default behavior for CMake, and has very little to do with ROS or the bloom packaging process: https://gitlab.kitware.com/cmake/comm... .

In particular, it looks like the Always full RPATH section will do what you're asking for:

# use, i.e. don't skip the full RPATH for the build tree
SET(CMAKE_SKIP_BUILD_RPATH  FALSE)

# when building, don't use the install RPATH already
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)


# the RPATH to be used when installing, but only if it's not a system directory
LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
IF("${isSystemDir}" STREQUAL "-1")
   SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
ENDIF("${isSystemDir}" STREQUAL "-1")

P.S. - The gpio library you're using looks dangerous; it's opening /dev/mem and reading and writing hardware addresses: https://github.com/UbiquityRobotics/p... . On any processor other than the intended target, this may result in a bus error in your program, or memory corruption in any part of the kernel or another program. This may cause an immediate crash, or may not be noticeable for quite some time after the corruption occurs. Be warned that you're playing with the software equivalent of fire and live explosives.

edit flag offensive delete link more

Comments

Thanks, I found that wiki page a little before you posted your answer. set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) solves the issue.

As for the fire and live explosives, agreed, its definitely a non-ideal situation.

rohbotics gravatar image rohbotics  ( 2018-06-04 20:12:16 -0500 )edit

Hi, I am also trying to make a ROS node (for a .py file) run as root. However, I am quite lost in the documentations of RPATH and other threads discussing this. I've made myself a passwordless sudo and added launch-prefix="sudo" to the launch file. I've also added the line Defaults env_keep += "PYTHONPATH" to the /etc/sudoers file, as well as the code from the Allways Full RPATH section to the end of the CMakeLists.txt file within my ROS package.

I am left with the error message rospkg.common.ResourceNotFound: rosgraph, which leads me to believe that I messed something up with the RPATH. Is there any obvious mistake I'm making?

JuliusHendrix gravatar image JuliusHendrix  ( 2020-03-10 09:55:01 -0500 )edit

Hey Julius,

First off RPATH is only going to be relevant to compiled and linked executables that you are trying to use setuid with, not python scripts and sudo. The easiest way to do what you are trying to do would be to make a bash script that sources the correct setup,bash and then runs the correct rosrun. There are many environment variables that you want to keep, and that would be the easiest way to keep them.

(possibly incomplete) list of env vars that you want to maintain: ROS_ROOT

ROS_MASTER_URI

ROS_HOSTNAME

ROS_IP

ROS_ETC_DIR

ROS_PACKAGE_PATH (What you are probably missing right now)

ROS_DISTRO

ROS_VERSION

ROS_PYTHON_VERSION

PYTHONPATH

PATH (not sure on this one)

rohbotics gravatar image rohbotics  ( 2020-03-10 10:41:32 -0500 )edit

Thank you!

JuliusHendrix gravatar image JuliusHendrix  ( 2020-03-12 04:16:16 -0500 )edit

Question Tools

Stats

Asked: 2018-06-04 19:08:33 -0500

Seen: 1,241 times

Last updated: Jun 04 '18