Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explanation of memcpy memmove GLIBC_2.14/2.2.5

My issue originated with a shared library I was given without the option to recompile the library. The error stated undefined reference to memcpy@GLIBC_2.14.

The version of GLIBC on my machine was 2.12. I have seen fixes people have done online using the line

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

The fix I made was using a hex editor to change the reference of 2.14 to GLIBC_2.2.5. When executing the command readelf -V lib_name.so, the outputs changed from:

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

to:

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

This fixed my error. What I want to know is what effects this will have. I have attempted to research memcpy vs. memmove and the change to memcpy starting in GLIBC_2.14, but I do not quite understand what is going on and what the original problem with memcpy was. I am worried about this "fix", although it allows my program to run, in case whatever memcpy is doing is not behaving correctly. Why do all the fixes I have seen online specifically link to the version 2.2.5?

I would appreciate if anyone could give me some insight on this topic or provide some links with relevant info.

like image 589
PickleWeasel Avatar asked Feb 26 '16 16:02

PickleWeasel


1 Answers

What I want to know is what effects this will have.

The most likely effect is that the first time your 3rd party library calls memcpy, it will crash.

There is a reason a new version of memcpy@GLIBC_2.14 was introduced: it's not ABI-compatible with the old memcpy (what happened here is that as of GLIBC-2.14, memcpy is a GNU_IFUNC, which means it returns the address of actual memcpy; the code in the 3rd party library will then call the returned routine. But the return value of memcpy@GLIBC_2.2.5 is the destination parameter and not a function address, so you are expected to immediately crash).

if anyone could give me some insight

The library you were given requires GLIBC-2.14. By running it on a GLIBC-2.12 machine, you've voided all warranties. Your best bet is to either:

  • work with 3rd party vendor to get a version of the library compatible with your execution environment, or
  • make your execution environment compatible with the library you are given (i.e. update your OS). You should probably do that anyway so your system can't be powned by recent vulnerabilities, such as CVE-2015-7547.

Update:

I'm not using the returned value from memcpy

You didn't understand how GNU_IFUNCs work. Here is a description. The problem is that while you aren't using the return value, the dynamic linker does.

The code inside dynamic linker does something like:

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!
}

By substituting non-ifunc version for an infunc-version via asm hack, you guaranteed that pfun == to, and so your to is getting called as if it were a function. That should normally immediately SIGSEGV.

like image 184
Employed Russian Avatar answered Oct 19 '22 19:10

Employed Russian