Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid dangerous vsprintf when you don't know the buffer size

__inline int my_sprintf (char *dest,char *format,...)
{
    va_list va;
    va_start(va,format);
    return vsprintf(dest,format,va);
}

My issue is that I can't add the buffer size parameter to my_sprintf because it's used in more than 50k places, this I can't replace vsprintf with vsprintf_s or vsnprintf.

any alternative to make the above function safer ?

like image 594
user327843 Avatar asked Dec 25 '22 18:12

user327843


2 Answers

What you're asking here is a specialization of the (in)famous question: "how to get the size of an array if all I have is a pointer?"

There's no way to figure out what's the size of the object pointed to by dest. Your best option is likely to bite the bullet and change those 50k places to pass the size.


There might be more to your code that you're not telling us. For example, in those "50k" places that you mention, is the size known? If so you could get away with a dirty variadic macro that uses sizeof behind the scenes and then calls a function that takes a length parameter.

like image 61
cnicutar Avatar answered Jan 18 '23 23:01

cnicutar


Sorry, there's no silver bullet for you here, as @cnicutar already mentioned.

You can start by restricting the buffer size and asserting on overflows. Something like:

#define SPRINTF_TRACE_BUFSIZE 4096

int my_sprintf( char* dest, const char* fmt, ... )
{
    /* in threaded code use malloc(3) instead */
    static char trace_buf[SPRINTF_TRACE_BUFSIZE];

    va_list va;
    va_start( va, fmt );
    int rc = vsnprintf( trace_buf, SPRINTF_TRACE_BUFSIZE, fmt, va );

    assert( rc != -1 && rc < SPRINTF_TRACE_BUFSIZE );

    memcpy( dest, trace_buf, rc + 1 ); /* +1 for \0 terminator */
    return rc;
}

And then start lowering the tracing buffer size until asserts start firing. At that point you can find and fix the offending calls.

This will of course slow down the overall system, but we are not talking about performance here.

Just to underscore it - this is a quick and dirty hack to fight with large old existing code-base, do not use it for new development.

like image 34
Nikolai Fetissov Avatar answered Jan 19 '23 00:01

Nikolai Fetissov