当用户抱怨 e2fsck(8) 编译错误导致数据丢失时,glibc 2.1.3 添加了链接时警告
“该
llseek
函数可能很危险;请改用 `lseek64。”如果需要无警告编译,这使得该函数无法使用。
从 glibc 2.28 开始,该函数符号不再对新链接的应用程序可用。
这背后有什么故事?
答案1
问题是 glibc 包含一个llseek
符号,但在其头文件中没有相应的声明。e2fsck
的配置脚本检测到该符号,并假设这意味着该功能可用。然而,隐式函数声明与函数期望的不匹配,导致函数调用最终被错误编译。特别是,llseek
需要 64 位偏移量,但隐式声明会产生int
参数 - 这就是导致数据丢失的原因,因为e2fsck
在与预期不同的偏移量处进行了更改。
e2fsck
使用的原因llseek
是 libc5(Linux 上 glibc 的前身)声明了它并使其可用(它位于unistd.h
)。因此e2fsck
,当针对 libc5 构建时,请正确使用llseek
;但是当针对 glibc 构建时,构建成功但无法正常工作。
此问题已在 e2fsprogs 1.12 中修复,更改日志条目如下:
E2fsprogs 现在可与 glibc 配合使用(至少与 RedHat 5.0 附带的版本配合使用)。即使 llseek() 不存在,ext2fs_llseek() 函数现在也应该可以使用 i386 ELF 共享库。我们还显式地进行配置测试,以查看 (a) llseek 是否在 libc 中,以及 (b) llseek 是否在系统头文件中声明。 (请参阅有关 libc 开发人员不理解与以前版本的 libc 兼容的概念的标准投诉。)
llseek
C 库也进行了更改,以便在代码尝试使用;时发出警告。讨论可以在邮件列表档案中找到。