DevNull DevNull - 2 months ago 10
C Question

Interposing library functions via linker script: other functions cause segfault

I'm currently utilizing the

LD_PRELOAD
trick and am utilizing a linker version script as detailed in an article on another website. My MCVE code is included below.

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE (1024)


int __printf__(const char *fmt, ...)
{
char buf[BUFFER_SIZE] = { 0 };
int ret;
int len;
va_list args;
va_start(args, fmt);

vsnprintf(buf, BUFFER_SIZE - 1, fmt, args);

#if 1
//typeof(vsnprintf) *real_func = dlsym(RTLD_NEXT, "vsnprintf");
//(*real_func)(buf, BUFFER_SIZE - 1, fmt, args);
#endif

len = strlen(buf);
ret = write(STDOUT_FILENO, buf, len);
va_end(args);

return ret;
}
asm(".symver __printf__, __printf_chk@GLIBC_2.3.4");


If I modify my custom
printf
function to simply write a static string, no problems. However, I want to modify the data being sent to the console via
printf
(add a prefix, suffix, and set certain character to UPPERCASE, etc). It seems that whenever I attempt to use any other
printf
-family functions to generate a copy of the user-provided string, I get a segfault, as shown below.

Program received signal SIGSEGV, Segmentation fault.
strchrnul () at ../sysdeps/x86_64/strchr.S:32
32 ../sysdeps/x86_64/strchr.S: No such file or directory.
(gdb) bt
#0 strchrnul () at ../sysdeps/x86_64/strchr.S:32
#1 0x00007ffff78591c8 in __find_specmb (format=0x1 <error: Cannot access memory at address 0x1>) at printf-parse.h:108
#2 _IO_vfprintf_internal (s=s@entry=0x7fffffffc380, format=format@entry=0x1 <error: Cannot access memory at address 0x1>, ap=ap@entry=0x7fffffffc4f8) at vfprintf.c:1312
#3 0x00007ffff7882989 in _IO_vsnprintf (string=0x7fffffffc510 "", maxlen=<optimized out>, format=0x1 <error: Cannot access memory at address 0x1>, args=0x7fffffffc4f8)
at vsnprintf.c:114
#4 0x00007ffff7bd58a1 in __printf__ (fmt=0x1 <error: Cannot access memory at address 0x1>) at libfakeprintf.c:19
#5 0x00000000004004aa in printf (__fmt=0x400644 "%s received %d args\n") at /usr/include/x86_64-linux-gnu/bits/stdio2.h:104
#6 main (argc=<optimized out>, argv=<optimized out>) at print_args.c:5
(gdb) quit


What is causing this crash?

Thank you.

nos nos
Answer

You have overridden the glibc internal function __printf_chk , however this function does not have a prototype that matches printf. It's prototype is:

int __printf_chk(int flag, const char * format, ...);

So make sure your own __printf__ function has that prototype too. There's a brief description of __printf_chk here