From e578988832bf5efd93c8d1f48eb0a05d470a0bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 14 Aug 2015 08:03:46 +0200 Subject: [PATCH] invalidScanf: removed the checking for 'scanf crash with huge input data for old glibc'. new systems are not vulnerable to this bug anymore. --- lib/checkio.cpp | 34 +++++----------------------------- lib/checkio.h | 5 ++--- test/testio.cpp | 15 --------------- 3 files changed, 7 insertions(+), 47 deletions(-) diff --git a/lib/checkio.cpp b/lib/checkio.cpp index 53be34d6c..0d18df9cf 100644 --- a/lib/checkio.cpp +++ b/lib/checkio.cpp @@ -367,12 +367,9 @@ void CheckIO::seekOnAppendedFileError(const Token *tok) //--------------------------------------------------------------------------- void CheckIO::invalidScanf() { - const bool printWarning = _settings->isEnabled("warning"); - const bool printPortability = _settings->isEnabled("portability"); - if (!printWarning && !printPortability) + if (!_settings->isEnabled("warning")) return; - const bool windows = _settings->isWindowsPlatform(); const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase(); std::size_t functions = symbolDatabase->functionScopes.size(); for (std::size_t j = 0; j < functions; ++j) { @@ -406,10 +403,8 @@ void CheckIO::invalidScanf() } else if (std::isalpha((unsigned char)formatstr[i]) || formatstr[i] == '[') { - if (printWarning && (formatstr[i] == 's' || formatstr[i] == '[' || formatstr[i] == 'S' || (formatstr[i] == 'l' && formatstr[i+1] == 's'))) // #3490 - field width limits are only necessary for string input - invalidScanfError(tok, false); - else if (printPortability && formatstr[i] != 'n' && formatstr[i] != 'c' && !windows) - invalidScanfError(tok, true); // Warn about libc bug in versions prior to 2.13-25 + if (formatstr[i] == 's' || formatstr[i] == '[' || formatstr[i] == 'S' || (formatstr[i] == 'l' && formatstr[i+1] == 's')) // #3490 - field width limits are only necessary for string input + invalidScanfError(tok); format = false; } } @@ -417,28 +412,9 @@ void CheckIO::invalidScanf() } } -void CheckIO::invalidScanfError(const Token *tok, bool portability) +void CheckIO::invalidScanfError(const Token *tok) { - if (portability) - reportError(tok, Severity::portability, - "invalidscanf_libc", "scanf without field width limits can crash with huge input data on some versions of libc.\n" - "scanf without field width limits can crash with huge input data on libc versions older than 2.13-25. Add a field " - "width specifier to fix this problem:\n" - " %i => %3i\n" - "\n" - "Sample program that can crash:\n" - "\n" - "#include \n" - "int main()\n" - "{\n" - " int a;\n" - " scanf(\"%i\", &a);\n" - " return 0;\n" - "}\n" - "\n" - "To make it crash:\n" - "perl -e 'print \"5\"x2100000' | ./a.out"); - else + reportError(tok, Severity::warning, "invalidscanf", "scanf without field width limits can crash with huge input data.\n" "scanf without field width limits can crash with huge input data. Add a field width " diff --git a/lib/checkio.h b/lib/checkio.h index 0f258838b..210ef729d 100644 --- a/lib/checkio.h +++ b/lib/checkio.h @@ -102,7 +102,7 @@ private: void writeReadOnlyFileError(const Token *tok); void useClosedFileError(const Token *tok); void seekOnAppendedFileError(const Token *tok); - void invalidScanfError(const Token *tok, bool portability); + void invalidScanfError(const Token *tok); void wrongPrintfScanfArgumentsError(const Token* tok, const std::string &function, unsigned int numFormat, @@ -133,8 +133,7 @@ private: c.writeReadOnlyFileError(0); c.useClosedFileError(0); c.seekOnAppendedFileError(0); - c.invalidScanfError(0, false); - c.invalidScanfError(0, true); + c.invalidScanfError(0); c.wrongPrintfScanfArgumentsError(0,"printf",3,2); c.invalidScanfArgTypeError_s(0, 1, "s", NULL); c.invalidScanfArgTypeError_int(0, 1, "d", NULL, false); diff --git a/test/testio.cpp b/test/testio.cpp index 40069bb7e..6073dcd93 100644 --- a/test/testio.cpp +++ b/test/testio.cpp @@ -44,7 +44,6 @@ private: TEST_CASE(testScanf1); // Scanf without field limiters TEST_CASE(testScanf2); - TEST_CASE(testScanf3); TEST_CASE(testScanf4); // #ticket 2553 TEST_CASE(testScanfArgument); @@ -702,20 +701,6 @@ private: ASSERT_EQUALS("[test.cpp:4]: (warning) scanf format string requires 0 parameters but 1 is given.\n", errout.str()); } - void testScanf3() { - check("void foo() {\n" - " scanf(\"%d\", &a);\n" - " scanf(\"%n\", &a);\n" // No warning on %n, since it doesn't expect user input - " scanf(\"%c\", &c);\n" // No warning on %c; it expects only one character - "}", false, true, Settings::Unspecified); - ASSERT_EQUALS("[test.cpp:2]: (portability) scanf without field width limits can crash with huge input data on some versions of libc.\n", errout.str()); - - check("void foo() {\n" - " scanf(\"%d\", &a);\n" - "}", false, true, Settings::Win32A); - ASSERT_EQUALS("", errout.str()); - } - void testScanf4() { // ticket #2553 check("void f()\n" "{\n"