Capturar llamadas al sistema con LD_PRELOAD
Mediante el uso de la variable de entorno LD_PRELOAD podemos cargar librerías dinámicas que sobrescriban llamadas al sistema. Vamos a ver como:
Un ejemplo en el que muy bien podemos utilizar LD_PRELOAD es cuando algún daemon no tiene la opción de funcionar sin pasar a background y luego no utiliza más la llamada fork().
Primero de todo creamos una función igual que la que queremos substituir con cualquier acción que queramos que se haga, en este caso no realizar el fork i devolver el zero:
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void)
{
return 0;
}
Para crear la librería dinámica lo haremos mediante el siguiente comando:
gcc -Wall -fPIC -shared -o forkfaker.so forkfaker.c
A continuación podremos ejecutar el daemon con la variable LD_PRELOAD:
LD_PRELOAD="./forkfaker.so" /usr/bin/daemon.ejemplo
En el caso que el daemon vaya a background pero después necesite realizar más forks no nos vale ya que los siguientes forks no funcionaran correctamente. Para ello podemos crear una librería que no realice el primer fork pero si todo el resto mediante la llamada a syscall() para realizar el fork real:
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
static int count=0;
pid_t fork(void)
{
if (count < 1)
{
++count;
return 0;
}
return syscall(SYS_fork);
}
De esta manera podemos usar con daemontools cualquier daemon que pase a background y del cual no queramos modificar el código fuente. Un ejemplo sería el miniserv de webmin:
#!/bin/bash LD_PRELOAD="/usr/local/lib/forkfaker.so" exec /usr/bin/perl /usr/local/webmin/miniserv.pl /usr/local/webmin/etc/miniserv.conf
En el caso que sea necesario más de un fork inicial sólo deberemos cambiar la condición del if que cuenta las veces que denegamos los forks.
Relacionados
Imprimir


28. September 2009 at 3:50 pm :
¡Sencillamente EXCELENTE!