1

I was just marked down on coursework for this incorrect solution to a buffer overflow in c but was not provided feedback on how it was wrong. Could somebody let me know what the problem is? Thank you.

The question stated to provide a solution in case a longer string than 16 was passed in to this function:

void function(char *str)
{
    char buffer[16];
    strcpy(buffer, str);
}

And here is my solution

void function(char *str)
{
    size_t str_length = strlen(str);

    char buffer[str_length];
    strcpy(buffer, str);
}

Thanks

1
  • Your solution also relies on variable length arrays, which were not available until C99. It's possible that the instructor is not aware that they are allowed now. Commented May 19, 2015 at 0:28

2 Answers 2

11

You need to account for the null character terminating the string:

char buffer[str_length + 1];

Void_ptr points out that the above is not enough. So to be more robust:

void function(char *str)
{
    size_t str_length = strlen(str);
    char *buffer = malloc(str_length + 1);
    if (buffer == NULL)
        return;
    memcpy(buffer, str, str_length+1); // Thanks chux
    // Do something with with buffer...
    free(buffer);
}

Or maybe the professor was simply looking for this:

void function(char *str)
{
    char buffer[16];
    strncpy(buffer, str, sizeof(buffer));
    buffer[sizeof(buffer)-1] = '\0';
}
Sign up to request clarification or add additional context in comments.

2 Comments

Still looks kinda unsafe. 1) buffer is allocated on the stack - what if you get stack overflow? 2) There's no upper limit on str_length - what if there's no terminating 0 for gigabytes and gigabytes of memory space?
Code paid the price to calculate the length of str. strcpy() effectively does that again. Instead of strcpy(buffer, str);, consider the more efficient memcpy(buffer, str, str_length+1).
1

It depends on what you are allowed to use but I guess the safest way would be to use strdup and check if it has returned NULL.

void function(char *str)
{
    char *buffer;

    buffer = strdup(str);
    if (!buffer)
        exit(EXIT_FAILURE);
    free(buffer);
    /* free buffer or keep track of it or you'll end up with memory leaks */
}

In the case where you're not allowed to dynamically allocate memory, the use of strncpy is still a more secure alternative to strcpy.

void function(char *str)
{
    size_t str_length = strlen(str);
    char buffer[str_length + 1]; /* /!\ This is C99 */

    strncpy(buffer, str, str_length);
    buffer[str_length] = '\0';
}

1 Comment

1) strncpy(buffer, str, str_length); buffer[str_length] = '\0'; serves no additional security. Just use memcpy(buffer, str, str_length+1); 2) There is no limit to the size of buffer[] - now that is a stack smashing security issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.