OverflowTruncationSufficiency

From C

Jump to: navigation, search

Terms

Overflow

When the sprintf function writes a sequence of bytes to a destination of insufficient allocated length, overflow occurs. Put on your rain coat.

Truncation

When the (so-called "safe") snprintf function attempts to write a sequence of bytes, and the number of which is greater than the maximum length specified by the user, the number of bytes written to the destination are truncated to the maximum length.

Sufficiency

Somehow obtaining knowledge of the number of bytes that will be written to the desintation, before allocating the destintation itself, allows one always to allocate sufficient space before commencing the write operation with sprintf or snprintf.

Do not rely on so-called "safe" functions so blindly

This page is meant to discuss the use of so-called "safe" functions like strncpy, snprintf, etc.

Imagine that your bank uses only "safe" functions like snprintf(). Doesn't that make you feel all warm and fuzzy?

#include <stdio.h>
int
main(void)
{
  char amount[7];
  snprintf(amount, sizeof amount, "%d", 1000000);
  puts(amount);
  return 0;
}

The main point is that while swapping sprintf() for snprintf() may eliminate buffer overflow, it doesn't make your program any "safer". Doing proper input checking is still required -- there is no magic shortcut around it.

Using sufficiency instead of truncation

Sanity checking the length of your data is very good practise. Unfortunately, there are some cases where one might not know the length of the output of sprintf to dest.

One may lose (assumingly) valuable data in the name of false --even the warm, fuzzy feeling-- safety, if snprintf is used unwisely.

One should always be able to allocate sufficient space before commencing the write. Such as in the code below:

#include <stdlib.h>
#include <stdio.h>

int
main(void)
{
  char *amount;
  size_t len;
  int num = 1000000;
  len = snprintf(NULL, 0, "%d", num);
  amount = malloc(len + 1);
  if (amount != NULL)
  {
    snprintf(amount, len + 1, "%d", num);
    printf("string: %s\n"
           "length was: %d\n",
           amount, len);
    free(amount);
  }
  return 0;
}

(Failure-checks added for correctness.)

Program output:

string: 1000000
length was: 7
Personal tools