【发布时间】:2010-10-27 07:06:09
【问题描述】:
我阅读了一些关于使用 LD_LIBRARY_PATH 的问题的文章,甚至作为包装脚本的一部分:
http://linuxmafia.com/faq/Admin/ld-lib-path.html
http://blogs.oracle.com/ali/entry/avoiding_ld_library_path_the
在这种情况下 - 推荐的替代方案是什么?
谢谢。
【问题讨论】:
我阅读了一些关于使用 LD_LIBRARY_PATH 的问题的文章,甚至作为包装脚本的一部分:
http://linuxmafia.com/faq/Admin/ld-lib-path.html
http://blogs.oracle.com/ali/entry/avoiding_ld_library_path_the
在这种情况下 - 推荐的替代方案是什么?
谢谢。
【问题讨论】:
您可以尝试添加:
-Wl,-rpath,path/to/lib
链接器选项。这将使您不必担心LD_LIBRARY_PATH 环境变量,并且您可以在编译时决定指向特定的库。
相对于二进制文件的路径,可以使用$ORIGIN,例如
-Wl,-rpath,'$ORIGIN/../lib'
(使用 ld 静态链接到共享库时,$ORIGIN 可能不起作用,请使用 -Wl,--allow-shlib-undefined 来解决此问题)
【讨论】:
--enable-new-dtags,例如-Wl,--enable-new-dtags,-rpath,'$ORIGIN/../lib'
-Wl,-rpath,'$$ORIGIN/../lib'
-Wl,-z,origin 来告诉链接器处理 ORIGIN,请参阅 [stackoverflow.com/questions/6324131/… stackoverflow 帖子)
我一直设置 LD_LIBRARY_PATH,从来没有遇到过问题。
引用您的第一个链接:
我应该什么时候设置 LD_LIBRARY_PATH?简短的回答是永远不会。为什么? 有些用户设置此环境变量似乎是因为其他用户的错误建议或他们不知道如何修复的错误链接代码。
这不是我称之为明确的问题陈述。事实上,它让人想起I don't like it。 [YouTube,但 SFW]。
第二个博客条目 (http://blogs.oracle.com/ali/entry/avoiding_ld_library_path_the) 对问题的性质提出了更多的看法……简而言之,库版本冲突 ThisProgram 需要 Foo1.2,但 ThatProgram 需要 Foo1.3,因此您不能(轻松地)运行这两个程序。请注意,大多数这些问题都可以通过一个简单的包装脚本来解决,该脚本仅为正在执行的 shell 设置 LD_LIBRARY_PATH,它(几乎总是)是交互式 shell 的单独子进程。
另请注意,替代方案在帖子中得到了很好的解释。
我只是很困惑为什么你会发布一个包含文章链接的问题,这些文章显然回答了你的问题......你有没有在这两篇文章中涵盖(足够清楚)的特定问题?
【讨论】:
答案在你引用的第一篇文章中。
在 UNIX 中,可以使用编译器的 -L dir 选项指定库的位置。 …… 作为使用 -L 和 -R 选项的替代方法,您可以在编译代码之前设置环境变量 LD_RUN_PATH。
【讨论】:
我发现现有的答案实际上并没有以直接的方式回答问题:
LD_RUN_PATH 由链接器在链接软件时使用(请参阅ld)。仅当命令行上没有-rpath ...(gcc 命令行上的-Wl,rpath ...)时才使用它。该变量中定义的路径将添加到 ELF 二进制文件中的 RPATH 条目中。 (您可以看到 RPATH 使用 objdump -x binary-filename — 但在大多数情况下它不存在!它出现在我的开发二进制文件中,但一旦安装了最终版本,RPATH 就会被删除。)
LD_LIBRARY_PATH 在运行时使用,当您要指定动态链接器(请参阅ldd)需要搜索库的目录时。指定错误的路径可能会导致加载错误的库。这是在二进制文件中定义的RPATH 值之外使用的(如在 1 中)。
LD_RUN_PATH 确实不会造成安全威胁,除非您是程序员并且不知道如何使用它。当我使用 CMake 构建我的软件时,-rpath 一直在使用。这样我就不必安装所有东西来运行我的软件。 ldd 可以自动找到所有的 .so 文件。 (automake 环境也应该这样做,但相比之下它不是很擅长。)
LD_LIBRARY_PATH 是一个运行时变量,因此您必须小心使用它。话虽如此,如果我们没有这个特殊功能,许多共享对象将很难处理。无论是安全威胁,都可能不是。如果黑客控制了您的计算机,那么该黑客无论如何都可以访问LD_LIBRARY_PATH。可能发生的情况是您在该变量中使用了错误的路径,您的二进制文件可能无法加载,但如果它加载,您最终可能会得到一个崩溃的二进制文件,或者至少是一个不能正常工作的二进制文件。一个问题是,随着时间的推移,您会获得新版本的库,并且您可能会忘记删除 LD_LIBRARY_PATH,这意味着您可能正在使用不安全的库版本。
另一种安全性的可能性是,如果黑客安装了一个与二进制文件正在搜索的同名的假库,该库包含所有相同的功能,但其中一些功能被偷偷摸摸的代码替换了。他可以通过更改LD_LIBRARY_PATH 变量来加载该库。然后它最终会被黑客执行。同样,如果黑客可以将这样的库添加到您的系统中,那么他已经进入并且可能一开始就不需要做任何类似的事情(因为他已经进入了他无论如何都可以完全控制您的系统。)因为实际上,如果黑客只能将库放在他的帐户中,他不会做任何事情(除非您的 Unix 机器总体上不安全......)如果黑客可以替换您的 /usr/lib/... 库之一,他已经可以完全访问您的系统。所以不需要LD_LIBRARY_PATH。
【讨论】: