【发布时间】:2013-01-30 12:56:32
【问题描述】:
在尝试让“Steam for Linux”在 Debian 上运行时,我遇到了一个问题。 libcef(Chromium 嵌入式框架)与 GLIBC_2.13(Debian 测试中的 eglibc 可以提供)可以正常工作,但需要来自 GLIBC_2.15 的一个讨厌的小额外功能(eglibc 无法提供):
$ readelf -s libcef.so | grep -E "@GLIBC_2\.1[4567]"
1037: 00000000 0 FUNC GLOBAL DEFAULT UND __fdelt_chk@GLIBC_2.15 (49)
2733: 00000000 0 FUNC GLOBAL DEFAULT UND __fdelt_chk@@GLIBC_2.15
我的攻击计划是LD_PRELOAD 一个仅提供这些功能的 shim 库。这似乎不起作用。我真的很想避免安装 GLIBC_2.17(因为它在 Debian 实验中;甚至 Debian sid 仍然有 GLIBC_2.13)。
这是我尝试过的。
fdelt_chk.c基本被盗from the GNU C library:
#include <sys/select.h>
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
unsigned long int
__fdelt_chk (unsigned long int d)
{
if (d >= FD_SETSIZE)
__chk_fail ();
return d / __NFDBITS;
}
strong_alias (__fdelt_chk, __fdelt_warn)
我的Versions 脚本如下所示:
GLIBC_2.15 {
__fdelt_chk; __fdelt_warn;
};
然后我按如下方式构建库:
$ gcc -m32 -c -fPIC fdelt_chk.c -o fdelt_chk.o
$ gcc -m32 -shared -nostartfiles -Wl,-s -Wl,--version-script Versions -o fdelt_chk.so fdelt_chk.o
但是,如果我随后运行 Steam(首先使用一堆额外的东西让它工作),加载程序仍然拒绝找到符号:
% LD_LIBRARY_PATH="/home/tinctorius/.local/share/Steam/ubuntu12_32" LD_PRELOAD=./fdelt_chk.so:./steamui.so ./steam
./steam: /lib/i386-linux-gnu/i686/cmov/libc.so.6: version `GLIBC_2.15' not found (required by /home/tinctorius/.local/share/Steam/ubuntu12_32/libcef.so)
不过版本符号也是我刚建的.so提供的:
% readelf -s fdelt_chk.so
Symbol table '.dynsym' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FUNC GLOBAL DEFAULT UND __chk_fail@GLIBC_2.3.4 (3)
2: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS _edata
3: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS _end
4: 00000310 44 FUNC GLOBAL DEFAULT 11 __fdelt_warn@@GLIBC_2.15
5: 00000310 44 FUNC GLOBAL DEFAULT 11 __fdelt_chk@@GLIBC_2.15
6: 00000000 0 OBJECT GLOBAL DEFAULT ABS GLIBC_2.15
7: 0000146c 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
此时,我不知道我能做些什么来欺骗加载程序(谁?)选择我的符号。我是否朝着正确的方向前进?
【问题讨论】:
-
尝试启用LD_DEBUG
=all并检查rtld(ld-linux.so)如何搜索__fdelt和@@GLIBC_2.15 -
这么多的垃圾邮件。好像只看了
/lib/i386-linux-gnu/i686/cmov/libc.so.6就立马放弃了。也许我需要为 fdelt_chk.so 选择一个合适的 soname... -
设置
-Wl,-soname,libc.so.6会杀死一切,因为现在它看起来不会比我自己的库更远。是否可以通过绝对 soname 导入实际的libc,然后重新导出所有其他符号? -
为什么不在steam库路径中添加来自ubuntu的glibc?
标签: ld glibc dynamic-linking fortify-source