Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using snprintf to avoid buffer overruns

Tags:

I am using snprintf like this to avoid a buffer overrun:

char err_msg[32] = {0}; snprintf(err_msg, sizeof(err_msg) - 1, "[ ST_ENGINE_FAILED ]"); 

I added the -1 to reserve space for the null terminator in case the string is more than 32 bytes long.

Am I correct in my thinking?

Platform:

  • GCC 4.4.1
  • C99
like image 998
ant2009 Avatar asked Nov 21 '09 12:11

ant2009


People also ask

Is Snprintf safe from buffer overflow?

It is safe as you long as you provide the correct length for the buffer.

Why should we use Snprintf () instead of sprintf ()?

Snprintf is safer to use because characters are not omitted and it is stored in the buffer for later usage. Both sprintf and snprintf store the string and produces the output as needed by user.

What is the use of Snprintf?

The snprintf is a predefined library function of the stdio. h header file, which redirects the output of the standard printf() function to other buffers. The snprint() function is used to format the given strings into a series of characters or values in the buffer area.

Is Sprintf memory unbounded?

The sprintf() function facilitates unbounded copying of text, in turn leaving the buffer susceptible to overflow attack. A buffer overflow occurs when a process attemps to store more data than the boundaries allow in the fixe-length buffer.


2 Answers

As others have said, you do not need the -1 in this case. If the array is fixed size, I would use strncpy instead. It was made for copying strings - sprintf was made for doing difficult formatting. However, if the size of the array is unknown or you are trying to determine how much storage is necessary for a formatted string. This is what I really like about the Standard specified version of snprintf:

char* get_error_message(char const *msg) {     size_t needed = snprintf(NULL, 0, "%s: %s (%d)", msg, strerror(errno), errno);     char  *buffer = malloc(needed+1);     sprintf(buffer, "%s: %s (%d)", msg, strerror(errno), errno);     return buffer; } 

Combine this feature with va_copy and you can create very safe formatted string operations.  

like image 192
D.Shawley Avatar answered Sep 28 '22 02:09

D.Shawley


You don't need the -1, as the reference states:

The functions snprintf() and vsnprintf() do not write more than size bytes (including the trailing '\0').

Note the "including the trailing '\0'" part

like image 37
Eli Bendersky Avatar answered Sep 28 '22 01:09

Eli Bendersky