¿ Sabías que…la variable LD_PRELOAD… ?

Nos permite construir librerías para la interposición de nuestras propias funciones en el sistema. La interposición de librerías es un método empleado, para que de forma totalmente transparente para el software compilado, podamos modificar parte de su comportamiento. La interposición se basa en que las funciones de la librería que estamos utilizando para la interposición serán utilizadas por el linkador para llamar a las funciones originales. Cuando realizamos una interposición, tenemos la opciones de llamar a la función original, cuando lo creamos conveniente.Vamos a realizar un sencillo ejemplo, en el que construiremos una librería a la que llamaremos my_libc.so.1, la cual tendrá la función chmod(), en el siguiete ejemplo podemos ver el contenido de programa my_chmod.c

#include < sys/types.h >
#include < sys/stat.h >
#include < dlfcn.h >

int chmod(const char *path, mode_t mode)
{
        int (*chmod_orig)(const char *path, mode_t mode);
        int val;
        chmod_orig=dlsym(RTLD_NEXT,"chmod");
        printf("n my_chmod: ATENCION!!! Se ha modificado los permisos del fichero %sn",path);
        val=chmod_orig(path,mode);
}

Como se puede ver, el ejemplo es extremadamente sencillo, se utiliza la llamada dlsym() para que en tiempo de ejecución, el linkador nos devuelva un puntero a la función chmod() original, seguidamente imprimimos un mensaje por pantalla y por último utilizamos el puntero chmod_orig (para los neófitos de C, este lenguaje permite punteros a funciones) el cual apunta a la verdadera función chmod() que cambiará los permisos del fichero.NOTA – Sería interesante leer el man de la función dlsym, para comprobar las posibilidades de las funciones para trabajar con el linkado dinámico.Ahora vamos crear un programa en C, el cual realizará una llamada a la función chmod(), para cambiar los permisos de un fichero.

#include < stdio.h >
#include < sys/types.h >
#include < sys/stat.h >
void main(){
        chmod("/tmp/ejemplo1.txt",S_IRWXG|S_IRWXO|S_IRWXU);
        printf("n ejemplo: Cambiados los permisos del fichero /tmp/ejemplo1.txt a 777 nn");
}

Como podemos ver, el ejemplo.c, cambia los permisos del fichero /tmp/ejemplo1.txt para ponerlos a 777.Vamos ver cuales son los pasos para compilar nuestro dos programas. Primero debemos crear una librería con nuestra versión de la función chmod(). Creamos el fichero objeto my_chmod.o.

bash-3.00# gcc -fPIC -g -c -Wall my_chmod.c
bash-3.00# ls -lrt
total 12
-rw-r--r--   1 root     root         323 Apr 15 16:04 my_chmod.c
-rw-r--r--   1 root     root         228 Apr 15 16:05 ejemplo.c
-rw-r--r--   1 root     root        3220 Apr 15 16:06 my_chmod.o

Creamos la librería con nuestro nuevo fichero objeto.

bash-3.00# gcc -shared -Wl -o my_libc.so.1 my_chmod.o
bash-3.00# ls -lrt
total 28
-rw-r--r--   1 root     root         323 Apr 15 16:04 my_chmod.c
-rw-r--r--   1 root     root         228 Apr 15 16:05 ejemplo.c
-rw-r--r--   1 root     root        3220 Apr 15 16:06 my_chmod.o
-rwxr-xr-x   1 root     root        7296 Apr 15 16:07 my_libc.so.1

Por último compilamos nuestro sencillo programa de ejemplo ejemplo.c.

bash-3.00# gcc ejemplo.c -o ejemplo

En este momento tenemos, por un lado, nuesta librería my_libc.so.1 y por otro, el programa ejemplo, que se encarga de modificar los permisos del fichero

bash-3.00# ls -l /tmp/ejemplo1.txt
-rw-r--r--   1 root     root           0 Apr 15 17:13 /tmp/ejemplo1.txt
bash-3.00#
bash-3.00# ./ejemplo 

ejemplo: Cambiados los permisos del fichero /tmp/ejemplo1.txt a 777

bash-3.00# ls -l /tmp/ejemplo1.txt
-rwxrwxrwx   1 root     root           0 Apr 15 17:13 /tmp/ejemplo1.txt
bash-3.00#

Ahora utilizamos la variable de entorno LD_PRELOAD, para que cargue nuestra librería my_libc.so.1.

bash-3.00#
bash-3.00# LD_PRELOAD=/export/home/user1/my_libc.so.1
bash-3.00#
bash-3.00# ./ejemplo 

my_chmod: ATENCION!!! Se ha modificado los permisos del fichero /tmp/ejemplo1.txt 

ejemplo: Cambiados los permisos del fichero /tmp/ejemplo1.txt a 777
bash-3.00#

Ahora cada vez que se llame a la función chmod(), aparecerá el siguiente mensaje.my_chmod: ATENCION!!! Se ha modificado los permisos del fichero < file>De echo podemos ejecutar el comando del sistema chmod para cambiar los permisos del un fichero.

bash-3.00# ls > /tmp/ejemplo2.txt
bash-3.00# ls -l /tmp/ejemplo2.txt
-rw-r--r--   1 root     root          68 Apr 15 17:18 /tmp/ejemplo2.txt
bash-3.00#
bash-3.00# chmod 755 /tmp/ejemplo2.txt 

my_chmod: ATENCION!!! Se ha modificado los permisos del fichero /tmp/ejemplo2.txt

bash-3.00#

Como podemos ver, ahora el comando chmod tambien devuelve la cadena con el aviso. Todos los programas o comandos que ejecutemos, cada vez que se llame a la función chmod(), devolveran un mensaje de aviso, debemos cambiar el contenido de la variable de entornos LD_PRELOAD para que se deje de utilizar la interposición de nuestra libreria.

bash-3.00#
bash-3.00# LD_PRELOAD=
bash-3.00# chmod 755 /tmp/ejemplo2.txt
bash-3.00#

Ya no aparecerá el mensaje de aviso. ¿ Para qué podemos utilizar la interposición de librerías a nivel de administración de sistemas ?, pues desde la elaboración de estadísticas, auditoría, control de los recursos, las posibilidades son ilimitadas, creo que el únic límite está en nuestra imaginación, de todas formas, aunque no le veamos demasiada utilidad ahora, creo que es una herramienta lo suficientemente potente como para que la tengamos en cuenta y sobre todo que no veamos la interposición de librerías como una herramienta únicamente de desarrollo.