Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How strcat_s avoids buffer overflow problem?

Tags:

c

I have below piece of code

#include <stdio.h>
#include <string.h>

void fn(char *status, size_t maxLen)
{
    strcat(status, "1234567890");
}

int main()
{
    char status[5] = { 0 };
    size_t statusMaxLen = sizeof(status) / sizeof(status[0]);
    printf("%s%zu", "size of a status string ", statusMaxLen);
    fn(status, statusMaxLen);
    return 0;
}

I am getting

run-time check failure #2 - Stack around the variable was corrupted

erro when using strcat. If I replace strcat with strcat_s() like this

strcat_s(status, maxLen, "1234567890");

getting

Debug assertion failed. Buffer is too small

So only type of error is different but still my program crashes. The solution to avoid crash is to check the size before concatenating. In this case why I need strcat_s. strcat also will work fine when size check done. So what will be the real use of strcat_s here.

Whether I use strcat or strcat_s, I need to check the size before copying / concatenating. If I do size check, then why should I prefer strcat_s over strcat?

if((strlen("1234567890") + strlen(status)) < maxLen){ 
    strcat(status, "1234567890");}`
like image 490
Arun Avatar asked Sep 17 '25 17:09

Arun


1 Answers

You should always check buffer sizes, regardless of which string concatenation function you use. That said, the code with strcat_s is better in two ways:

  • This is no longer a buffer overflow vulnerability.

    A buffer overflow vulnerability occurs when an attacker is able to supply a piece of data that is too long, and that data then overwrites something outside of the buffer, in some cases allowing the attacker to take control of the process by tricking it to run malicious code or misbehave in some other way.

    Since strcat_s crashes instead of allowing this to happen, the behaviour is now predictable and cannot be exploited by an attacker.

  • You can choose a more useful behaviour than crashing the process.

    You can set the constraint handler that gets invoked when strcat_s detects that the destination buffer is too small.

There isn't really any way around checking the buffer size. Even if you use strncat, you have the issue that strncat doesn't null-terminate the destination buffer if it is too small, which can cause all kinds of problems. Never mind, I mixed up strncpy and strncat. Note that the size argument to strncat probably doesn't do what you expect.

like image 194
legoscia Avatar answered Sep 19 '25 07:09

legoscia