Dangerous printf

The fragment is taken from TortoiseSVN project. The code contains an error that analyzer diagnoses in the following way: V618 It’s dangerous to call the ‘printf’ function in such a manner, as the line being passed could contain format specification. The example of the safe code: printf(“%s”, str);

BOOL CPOFile::ParseFile(....)
{
  ....
  printf(File.getloc().name().c_str());
  ....
}

Explanation

When you want to print or, for example, to write a string to the file, many programmers write code that resembles the following:

printf(str);
fprintf(file, str);

A good programmer should always remember that these are extremely unsafe constructions. The thing is, that if a formatting specifier somehow gets inside the string, it will lead to unpredictable consequences.

Let’s go back to the original example. If the file name is “file%s%i%s.txt”, then the program may crash or print some rubbish. But that’s only a half of the trouble. In fact, such a function call is a real vulnerability. One can attack programs with its help. Having prepared strings in a special way, one can print private data stored in the memory.

16d5cz

More information about these vulnerabilities can be found in this article. You’ll find not only theoretical basis, but practical examples as well.

Correct code

printf("%s", File.getloc().name().c_str());

Recommendation

Printf()-like functions can cause a lot of security related issues. It is better not to use them at all, but switch to something more modern. For example, you may find boost::format or std::stringstream quite useful.

In general, sloppy usage of the functions printf(), sprintf(), fprintf(), and so on, not only can lead to incorrect work of the program, but cause potential vulnerabilities, that someone can take advantage of.

Written by Andrey Karpov.
This error was found with PVS-Studio static analysis tool.

3 thoughts on “Dangerous printf

  1. It is probably better to use “puts” or “fputs” in this case. That said, compilers are smart enough to optimize the printf call into a puts equivalent when the argument list consists of a single string literal. I do not know if compilers are able to optimize the correct code presented here.

    Like

  2. > It is probably better to use “puts” or “fputs” in this case. It is probably better to use “puts” or “fputs” in this case.

    I agree with you and it is better to use these functions in newly written code.The important thing is that everybody has to be aware of dangerous behavior of the “printf” function when you’re passing the single string parameter into the “printf” function.

    > That said, compilers are smart enough to optimize the printf call into a puts equivalent when the argument list consists of a single string literal. I do not know if compilers are able to optimize the correct code presented here.

    I’ve tested code with Godbolt. The first example is when you’re passing a string literal into the “printf” function:

    https://gcc.godbolt.org/z/OmGYh5

    So, gcc and clang have optimized this code and replaced the “printf” function call into the “puts”, but msvc hasn’t (I love Microsoft).

    The second example is when you’re passing an unknown pointer to a const char into the “printf” function:

    https://gcc.godbolt.org/z/AvfDKH

    So, no one has optimized that code because compilers haven’t had information about the “format” parameter.

    Finally, the third example is when a compiler has possibilites to inline the function:

    https://gcc.godbolt.org/z/AcSFCr

    Here compilers could inline the “Print” function into “main” and has changed “printf” with “puts”.

    Like

  3. Pingback: Native code: always faster? – WriteAsync .NET

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.