Ao tentar usar o popen () em um compartilhamentobiblioteca e pré-carregando via LD_PRELOAD ou /etc/ld.so.preload, o processo fica preso em um loop infinito com uma mensagem de erro dizendo que a biblioteca compartilhada não pode ser pré-carregada, ou o sistema apenas congela e precisa ser reinicializado, dependendo no código.
Por favor, note que compilar não como uma biblioteca compartilhada (gcc test.c; ./a.out
) funcionará sem erro.
Se for útil, estou executando uma nova instalação do Debian no VirtualBox:
Debian debian 3.16.0-4-586 # 1 Debian 3.16.36-1 + deb8u2 (2016-10-19) i686 GNU / Linux
Ok, então este código:
#define _GNU_SOURCE
#include <stdio.h>
__attribute__((constructor, visibility("hidden")))
void init()
{
FILE *fp = popen("/usr/bin/id", "r");
pclose(fp);
}
Resultados no primeiro caso:
root@debian:/mnt/group/hcfrk# gcc test.c -o test.so -std=c99 -shared -fPIC
root@debian:/mnt/group/hcfrk# LD_PRELOAD=./test.so whoami
ERROR: ld.so: object "./test.so" from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object "./test.so" from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object "./test.so" from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object "./test.so" from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
# For eternity.
Este código:
...
#include <limits.h>
...
{
FILE *fp = popen("/usr/bin/id", "r");
if(!fp)
puts("Error.n");
char buf[PATH_MAX];
while(fgets(buf, sizeof buf, fp))
printf("%sn", buf);
pclose(fp); // Never gets here: VM just freezes.
}
Resultados no segundo caso (o sistema congela). Eu suspeito que é por causa do loop while não terminar e causando pclose () para não ser chamado, como o primeiro exemplo de código irá congelar o sistema sem pclose () também.
Qualquer ajuda seria apreciada. Obrigado!
Respostas:
2 para resposta № 1Aren "t você forkbombing aqui? Construtor em LD_PRELOAD
vai causar /usr/bin/id
para se executar para sempre (já que cada nova instância terá sua biblioteca pré-carregada), provavelmente parando sua máquina. Você deveria provavelmente unsetenv
antes de aparecer.