¿Hay alguna forma de inspeccionar el rpath actual en Linux?


83

Soy consciente de que es posible usarlo readelf -d <elf> | grep RPATHpara inspeccionar un binario dado desde el shell, pero ¿es posible hacer esto dentro de un proceso?

Algo como (mi llamada al sistema completamente inventada):

  /* get a copy of current rpath into buffer */
  sys_get_current_rpath(&buffer);

Estoy tratando de diagnosticar algunos problemas sospechosos de vinculación de SO en nuestra base de código y me gustaría inspeccionar el RPATH de esta manera si es posible (prefiero no tener que generar un script externo).


1
Tenga en cuenta que al diagnosticar problemas de bibliotecas compartidas, también debe inspeccionar la etiqueta RUNPATH. Por lo tanto, debería grep PATHhacerlo. Depende del vinculador si se usa RPATH o RUNPATH, y existen diferencias sutiles pero importantes entre los dos: stackoverflow.com/a/52020177
— Nicolas Capens

Respuestas:


54
#include <stdio.h>
#include <elf.h>
#include <link.h>

int main()
{
  const ElfW(Dyn) *dyn = _DYNAMIC;
  const ElfW(Dyn) *rpath = NULL;
  const char *strtab = NULL;
  for (; dyn->d_tag != DT_NULL; ++dyn) {
    if (dyn->d_tag == DT_RPATH) {
      rpath = dyn;
    } else if (dyn->d_tag == DT_STRTAB) {
      strtab = (const char *)dyn->d_un.d_val;
    }
  }

  if (strtab != NULL && rpath != NULL) {
    printf("RPATH: %s\n", strtab + rpath->d_un.d_val);
  }
  return 0;
}

1
es brillante, pero no funciona con $ ORIGIN. $ ORIGIN no se interpreta y la función lo devuelve tal cual. ¿Hay alguna forma de agregar la interpretación $ ORIGIN?
— Jérôme

5
@ Jérôme Si está ejecutando en un entorno donde /procestá montado, entonces expandir $ORIGINes tan simple como readlink("/proc/self/exe", ...)luego terminar en NUL en la última barra.
— Empleado ruso

Si bien la pregunta era específicamente sobre RPATH, me gustaría señalar que es igualmente importante verificar la DT_RUNPATHetiqueta si uno desea saber las rutas desde las que un binario podría estar cargando sus bibliotecas compartidas.
— Nicolas Capens

154

Para el registro, aquí hay un par de comandos que mostrarán el rpathencabezado.

objdump -x binary-or-library |grep RPATH

Quizás una forma aún mejor de hacerlo es la siguiente:

readelf -d binary-or-library |head -20

El segundo comando también enumera las dependencias directas de otras bibliotecas seguidas de rpath.


7
En ubuntu 15.04 tengo que usar: objdump -x binary-or-library | grep RUNPATH
— Andreas Roth


11
Esta respuesta no tiene nada que ver con la pregunta que se hizo (y está contenida en la pregunta en sí).
— Empleado ruso


1

Esto es lo que uso por conveniencia, como función de shell:

function getrpath {
    eu-readelf -d "${1:?}" | sed -e '/RUNPATH/{s~.*\[\(.*\)\]~\1~;n};d'
}

Esto consume la eu-readelfsalida de elfutilscomo:

Type              Value
NEEDED            Shared library: [libpq.so.5]
NEEDED            Shared library: [libc.so.6]
RUNPATH           Library runpath: [/some/path/to/lib]
....

y emite

 /some/path/to/lib

Debería funcionar bien con binutils en readelflugar de elfutils eu-readelftambién.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.