Closed giulianobelinassi closed 2 years ago
So after further investigation, the reason why the livepatch failed on the current commit is:
strcpy
. This function has the following prototype: char * strcpy(char *, const char *)
The following function is an intuitive replacement for it:
char *mystrcpy(char *dst, const char *src)
{
char *rdst = dst;
while (*src != '\0')
*dst++ = *src++;
*dst = '\0';
return rdst;
}
libc.so.6
's strcpy
will result in a crash. The reason of this crash is that strcpy
is actually an alias to strcpy_ifunc
(notice that the offsets are the same, thus they point to the same function):
objdump -t libc.so.6 | grep strcpy
**00000000000b4d9e** l F .text 0000000000000083 **strcpy_ifunc**
00000000001adf50 l F .text 0000000000000433 __strcpy_evex
00000000000b4d9e l i .text 0000000000000083 __GI_strcpy
0000000000185470 l F .text 00000000000017a2 __strcpy_ssse3
000000000019a050 l F .text 0000000000000388 __strcpy_avx2
00000000000c9f10 l F .text 00000000000000ec __strcpy_sse2
00000000000ca0f0 l F .text 0000000000000623 __strcpy_sse2_unaligned
00000000001a69a0 l F .text 00000000000003a9 __strcpy_avx2_rtm
00000000000bbf2e l F .text 00000000000000ba __old_strcpy_small
00000000000bbf2e g F .text 00000000000000ba __strcpy_small@GLIBC_2.2.5
**00000000000b4d9e** g i .text 0000000000000083 **strcpy**
0000000000135a0e g F .text 0000000000000038 __strcpy_chk
strcpy_ifunc
actually is just a selector for an optimized strcpy
function. On my machine, it returns a pointer to __strcpy_evex
, and this address is put into strcpy
's entry on the .plt
table of the process.
void *mystrcpy_selector()
{
return (void *) mystrcpy;
}
char mystrcpy(char dst, const char src) { char rdst = dst; while (src != '\0') dst++ = src++; dst = '\0';
return rdst; }
and instruct to patch `strcpy` to `mystrcpy_selector`, the livepatch succeeds.
6. If the selector has already run, then `__strcpy_evex` will be at `strcpy` entry at plt. This is not a problem if that function is written in C, because `-fpatchable-function-entry` would generate patchable assembly for it. However, `__strcpy_evex` is written in assembly and thus cannot be livepatched.
Since this is not a regression, I am closing this.
For some reason parsing the ELF PHDRs in libc.so.6 seems to not be returning the correct address. This is breaking glibc livepatches, althrough this commit is required in order to get openssl livepatches to work.
Probably the solution would be finding the target library path using the dl_iterate, but still dlsym that file for the correct symbol.