【问题标题】:Explanation of memcpy memmove GLIBC_2.14/2.2.5memcpy memmove GLIBC_2.14/2.2.5的解释
【发布时间】:2016-06-09 23:05:57
【问题描述】:

我的问题源于一个共享库,我没有重新编译该库的选项。错误声明为undefined reference to memcpy@GLIBC_2.14

我机器上的 GLIBC 版本是 2.12。我已经看到人们使用该行在网上完成的修复

__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");

我所做的修复是使用十六进制编辑器将 2.14 的引用更改为 GLIBC_2.2.5。执行命令readelf -V lib_name.so时,输出变为:

0x0060  Name: GLIBC_2.14 Flags: none Version 6
......
0x0080  Name: GLIBC_2.2.5 Flags: none Version 4

到:

0x0060  Name: GLIBC_2.2.5 Flags: none Version 6
......
0x0080  Name: GLIBC_2.2.5 Flags: none Version 4

这修正了我的错误。我想知道的是这会有什么影响。我试图研究 memcpy 与 memmove 以及从 GLIBC_2.14 开始对 memcpy 的更改,但我不太了解发生了什么以及 memcpy 的原始问题是什么。我担心这个“修复”,尽管它允许我的程序运行,以防 memcpy 所做的任何事情都无法正常运行。为什么我在网上看到的所有修复都专门链接到 2.2.5 版本?

如果有人能给我关于这个主题的一些见解或提供一些相关信息的链接,我将不胜感激。

【问题讨论】:

    标签: linux gcc linker glibc memcpy


    【解决方案1】:

    我想知道的是这会有什么影响。

    最可能的影响是你的 3rd 方库第一次调用memcpy,它会崩溃。

    有一个原因引入了新版本的memcpy@GLIBC_2.14:它与旧的memcpy 不兼容ABI(这里发生的情况是从GLIBC-2.14 开始,memcpyGNU_IFUNC,表示返回实际memcpy的地址;第三方库中的代码会调用返回的例程,但memcpy@GLIBC_2.2.5的返回值是目的地参数而不是函数地址,因此您应该立即崩溃)。

    如果有人能给我一些见解

    您获得的库需要 GLIBC-2.14。通过在 GLIBC-2.12 机器上运行它,您已经取消了所有保修。您最好的选择是:

    • 与第 3 方供应商合作以获得与您的执行环境兼容的库版本,或
    • 使您的执行环境与您提供的库兼容(即更新您的操作系统)。您可能应该这样做无论如何,这样您的系统就不会被最近的漏洞所破坏,例如CVE-2015-7547

    更新:

    我没有使用 memcpy 的返回值

    您不了解GNU_IFUNCs 的工作原理。这是description。问题在于,虽然没有使用返回值,但动态链接器使用

    动态链接器中的代码执行以下操作:

    if (symbol type == STT_GNU_IFUNC) {
      // call the IFUNC to get an address of the actual implementation
      void (*pfun)() = memcpy();
      // call the actual (non-IFUNC) implementation of memcpy.
      return (*pfun)(to, from, size);  // You will crash here!
    }
    

    通过 asm hack 用非ifunc 版本替换infunc 版本,您保证了pfun == to,因此您的to 被调用,就好像它是一个函数一样。这通常应该立即SIGSEGV

    【讨论】:

    • 获取与您的执行环境兼容的库版本有没有办法交叉编译库或可执行文件,所以它需要比旧版本的 glibc在 GCC 工具链中使用?
    • @starfury 是的,有,但不是小事:stackoverflow.com/a/8658468/50617
    • 非常感谢,如果只有我的代码使用memcpy 而我的编译器生成的是GLIBC_2.14,我必须把这个__asm__ hack 让它在@ 上运行987654341@ machine ,我没有使用来自memcpyreturned 值,该值已在两个版本之间更改,我只是像这样使用它memcpy(to, from 100); 我仍然处于危险之中因__asm__ hack 导致的崩溃?
    • @Accountantم 哦,如果它没有崩溃,那么我的解释可能不正确。您的 hack 可能是偶然起作用的,或者我错过了它起作用的其他一些原因。
    • 嗯...我猜它没有崩溃,因为这个 hack 是向后兼容的,不是向前。如果我们在期望返回地址的新链接器上运行旧的memcpy,它将崩溃,但在这里我们正在做相反的事情,我们在旧的链接器上运行新的memcpy,它不希望地址返回被退回,所以没有发生崩溃,对吗?
    猜你喜欢
    • 2011-05-23
    • 1970-01-01
    • 2019-04-06
    • 2021-02-05
    • 2011-04-17
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 2015-04-21
    相关资源
    最近更新 更多