当尝试在共享库中使用popen()并通过LD_PRELOAD或/etc/ld.so.preload预加载时,进程陷入无限循环,并显示一条错误消息,指出无法预加载共享库,或者系统只是冻结,需要重新启动,具体取决于代码。
请注意,编译不是共享库(gcc test.c; ./a.out
)可以正常工作。
如果它有用,我正在VirtualBox上运行全新的Debian安装:
Linux debian 3.16.0-4-586#1 Debian 3.16.36-1 + deb8u2(2016-10-19)i686 GNU / Linux的
好的,所以这段代码:
#define _GNU_SOURCE
#include <stdio.h>
__attribute__((constructor, visibility("hidden")))
void init()
{
FILE *fp = popen("/usr/bin/id", "r");
pclose(fp);
}
第一种情况的结果:
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.
此代码:
...
#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("%s\n", buf);
pclose(fp); // Never gets here: VM just freezes.
}
第二种情况的结果(系统冻结)。我怀疑这是因为while循环没有结束并导致pclose()没有被调用,因为第一个代码示例将冻结系统而没有pclose()。
任何帮助将不胜感激。谢谢!
答案 0 :(得分:3)
LD_PRELOAD
中的构造函数将导致/usr/bin/id
永久执行(因为每个新实例都会预先加载您的库),很可能会停止您的计算机。在开始教育之前你应该unsetenv
。