Chromium运行时LD_PRELOAD加载libgtk3-nocsd.so.0失败的问题咨询
问题描述
我在bash shell里运行Chromium的时候,总会弹出这个错误:
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (failed to map segment from shared object): ignored.
但运行普通的可执行文件,比如gcc编译的helloworld程序时,就不会出现这个错误提示,这让我有点困惑。
环境信息
| 属性 | 具体值 |
|---|---|
| 操作系统 | Linux |
| 架构 | aarch64 |
| 发行版 | Ubuntu 20.04.5 LTS |
我做的调研
首先我用ldd命令检查了libgtk3-nocsd.so.0的定位情况,发现不管是helloworld还是Chromium,都能正确找到这个共享对象的绝对路径:
$ ldd helloworld | grep -F libgtk3-nocsd.so.0 libgtk3-nocsd.so.0 => /lib/aarch64-linux-gnu/libgtk3-nocsd.so.0 (0x0000ffffa9a73000) $ ldd /snap/bin/chromium | grep -F libgtk3-nocsd.so.0 libgtk3-nocsd.so.0 => /lib/aarch64-linux-gnu/libgtk3-nocsd.so.0 (0x0000ffff7e370000) $ ldd /snap/chromium/current/usr/lib/chromium-browser/chrome | grep -F libgtk3-nocsd.so.0 libgtk3-nocsd.so.0 => /lib/aarch64-linux-gnu/libgtk3-nocsd.so.0 (0x0000ffff7a299000)
然后我查看了这个共享对象的权限,发现它带有setuid位:
$ ls -l /lib/aarch64-linux-gnu/libgtk3-nocsd.so.0 -rwSr--r-- 1 root root 26464 Mar 3 2018 /lib/aarch64-linux-gnu/libgtk3-nocsd.so.0
接着我找到了LD_PRELOAD环境变量的设置位置:
$ sudo grep -2r LD_PRELOAD /etc/ ... /etc/X11/Xsession.d/51gtk3-nocsd-detect- if [ x"$GTK_CSD"x = x"0"x ] ; then /etc/X11/Xsession.d/51gtk3-nocsd-detect: export LD_PRELOAD="libgtk3-nocsd.so.0${LD_PRELOAD:+:$LD_PRELOAD}" /etc/X11/Xsession.d/51gtk3-nocsd-detect- fi ...
另外我还找到了一段可能和问题相关的配置说明:
$ sudo grep -2r LD_PRELOAD /etc/ ... /etc/apparmor.d/abstractions/ubuntu-helpers- # While the chromium and chrome sandboxes are setuid root, they only link /etc/apparmor.d/abstractions/ubuntu-helpers- # in limited libraries so glibc's secure execution should be enough to not /etc/apparmor.d/abstractions/ubuntu-helpers: # require the santized_helper (ie, LD_PRELOAD will only use standard system /etc/apparmor.d/abstractions/ubuntu-helpers- # paths (man ld.so)). ...
我也查看了ld.so的手册内容,里面提到:
In secure-execution mode, preload pathnames containing slashes are ignored. Furthermore, shared objects are preloaded only from the stan‐
dard search directories and only if they have set-user-ID mode bit enabled (which is not typical).
我尝试的解决办法
根据上面查到的文档,我试了两个方案:
- 把LD_PRELOAD改成libgtk3-nocsd.so.0的绝对路径
文档里说Chromium和Chrome的沙箱环境下,LD_PRELOAD只会使用标准系统路径。所以我打算修改/etc/X11/Xsession.d/51gtk3-nocsd-detect里的配置,把原来的:
export LD_PRELOAD="libgtk3-nocsd.so.0${LD_PRELOAD:+:$LD_PRELOAD}"
替换成:
export LD_PRELOAD="/lib/aarch64-linux-gnu/libgtk3-nocsd.so.0${LD_PRELOAD:+:$LD_PRELOAD}"
之后重启桌面环境应该就可以了。不过要注意不同平台下这个共享对象的绝对路径可能不一样。
- 用root身份无沙箱运行Chromium
看起来问题和Chromium/Chrome的setuid root沙箱有关,我试了用sudo chromium --no-sandbox命令运行,错误消息确实消失了,但浏览器会弹出一个警告:You are using an unsupported command-line flag:--no-sandbox. Stability and security will suffer.,安全性和稳定性都会打折扣,这个方案感觉不太靠谱。
我的疑问
现在还有几个问题没弄明白,希望大家能帮忙解答:
- 文档里提到的“standard system paths/standard search directories(标准系统路径/标准搜索目录)”具体指哪些路径?我查了
/etc/ld.so.cache里面有libgtk3-nocsd.so.0的记录,而且/lib/aarch64-linux-gnu也在/etc/ld.so.conf.d/aarch64-linux-gnu.conf里,难道这个路径不算标准系统路径吗?
$ grep -aoP '(?<=\x00)[^\x00]*?libgtk3-nocsd\.so\.0' /etc/ld.so.cache libgtk3-nocsd.so.0 /lib/aarch64-linux-gnu/libgtk3-nocsd.so.0 $ cat /etc/ld.so.conf.d/aarch64-linux-gnu.conf # Multiarch support /usr/local/lib/aarch64-linux-gnu /lib/aarch64-linux-gnu /usr/lib/aarch64-linux-gnu
手册里说在安全执行模式下,包含斜杠的预加载路径名会被忽略,那是不是意味着如果LD_PRELOAD设置成
/lib/aarch64-linux-gnu/libgtk3-nocsd.so.0这样的绝对路径,就会被直接忽略掉?那我第一个解决办法是不是反而没用?这两个方案哪个更安全合理?有没有更好的解决办法?我有没有哪里理解错了文档里的内容?
备注:内容来源于stack exchange,提问作者Shuangcheng Ni

