[clang][analyzer] Support fprintf in the SecuritySyntaxChecker (#73247)
This commit is contained in:
@@ -144,38 +144,39 @@ void WalkAST::VisitCallExpr(CallExpr *CE) {
|
||||
Name = Name.substr(10);
|
||||
|
||||
// Set the evaluation function by switching on the callee name.
|
||||
FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
|
||||
.Case("bcmp", &WalkAST::checkCall_bcmp)
|
||||
.Case("bcopy", &WalkAST::checkCall_bcopy)
|
||||
.Case("bzero", &WalkAST::checkCall_bzero)
|
||||
.Case("gets", &WalkAST::checkCall_gets)
|
||||
.Case("getpw", &WalkAST::checkCall_getpw)
|
||||
.Case("mktemp", &WalkAST::checkCall_mktemp)
|
||||
.Case("mkstemp", &WalkAST::checkCall_mkstemp)
|
||||
.Case("mkdtemp", &WalkAST::checkCall_mkstemp)
|
||||
.Case("mkstemps", &WalkAST::checkCall_mkstemp)
|
||||
.Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy)
|
||||
.Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat)
|
||||
.Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
|
||||
"vscanf", "vwscanf", "vfscanf", "vfwscanf",
|
||||
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
|
||||
.Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
|
||||
"snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove",
|
||||
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
|
||||
.Cases("strncpy", "strncat", "memset",
|
||||
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
|
||||
.Case("drand48", &WalkAST::checkCall_rand)
|
||||
.Case("erand48", &WalkAST::checkCall_rand)
|
||||
.Case("jrand48", &WalkAST::checkCall_rand)
|
||||
.Case("lrand48", &WalkAST::checkCall_rand)
|
||||
.Case("mrand48", &WalkAST::checkCall_rand)
|
||||
.Case("nrand48", &WalkAST::checkCall_rand)
|
||||
.Case("lcong48", &WalkAST::checkCall_rand)
|
||||
.Case("rand", &WalkAST::checkCall_rand)
|
||||
.Case("rand_r", &WalkAST::checkCall_rand)
|
||||
.Case("random", &WalkAST::checkCall_random)
|
||||
.Case("vfork", &WalkAST::checkCall_vfork)
|
||||
.Default(nullptr);
|
||||
FnCheck evalFunction =
|
||||
llvm::StringSwitch<FnCheck>(Name)
|
||||
.Case("bcmp", &WalkAST::checkCall_bcmp)
|
||||
.Case("bcopy", &WalkAST::checkCall_bcopy)
|
||||
.Case("bzero", &WalkAST::checkCall_bzero)
|
||||
.Case("gets", &WalkAST::checkCall_gets)
|
||||
.Case("getpw", &WalkAST::checkCall_getpw)
|
||||
.Case("mktemp", &WalkAST::checkCall_mktemp)
|
||||
.Case("mkstemp", &WalkAST::checkCall_mkstemp)
|
||||
.Case("mkdtemp", &WalkAST::checkCall_mkstemp)
|
||||
.Case("mkstemps", &WalkAST::checkCall_mkstemp)
|
||||
.Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy)
|
||||
.Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat)
|
||||
.Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
|
||||
"vscanf", "vwscanf", "vfscanf", "vfwscanf",
|
||||
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
|
||||
.Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
|
||||
"snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove",
|
||||
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
|
||||
.Cases("strncpy", "strncat", "memset", "fprintf",
|
||||
&WalkAST::checkDeprecatedOrUnsafeBufferHandling)
|
||||
.Case("drand48", &WalkAST::checkCall_rand)
|
||||
.Case("erand48", &WalkAST::checkCall_rand)
|
||||
.Case("jrand48", &WalkAST::checkCall_rand)
|
||||
.Case("lrand48", &WalkAST::checkCall_rand)
|
||||
.Case("mrand48", &WalkAST::checkCall_rand)
|
||||
.Case("nrand48", &WalkAST::checkCall_rand)
|
||||
.Case("lcong48", &WalkAST::checkCall_rand)
|
||||
.Case("rand", &WalkAST::checkCall_rand)
|
||||
.Case("rand_r", &WalkAST::checkCall_rand)
|
||||
.Case("random", &WalkAST::checkCall_random)
|
||||
.Case("vfork", &WalkAST::checkCall_vfork)
|
||||
.Default(nullptr);
|
||||
|
||||
// If the callee isn't defined, it is not of security concern.
|
||||
// Check and evaluate the call.
|
||||
@@ -737,10 +738,10 @@ void WalkAST::checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD) {
|
||||
// Check: Any use of 'sprintf', 'vsprintf', 'scanf', 'wscanf', 'fscanf',
|
||||
// 'fwscanf', 'vscanf', 'vwscanf', 'vfscanf', 'vfwscanf', 'sscanf',
|
||||
// 'swscanf', 'vsscanf', 'vswscanf', 'swprintf', 'snprintf', 'vswprintf',
|
||||
// 'vsnprintf', 'memcpy', 'memmove', 'strncpy', 'strncat', 'memset'
|
||||
// is deprecated since C11.
|
||||
// 'vsnprintf', 'memcpy', 'memmove', 'strncpy', 'strncat', 'memset',
|
||||
// 'fprintf' is deprecated since C11.
|
||||
//
|
||||
// Use of 'sprintf', 'vsprintf', 'scanf', 'wscanf','fscanf',
|
||||
// Use of 'sprintf', 'fprintf', 'vsprintf', 'scanf', 'wscanf', 'fscanf',
|
||||
// 'fwscanf', 'vscanf', 'vwscanf', 'vfscanf', 'vfwscanf', 'sscanf',
|
||||
// 'swscanf', 'vsscanf', 'vswscanf' without buffer limitations
|
||||
// is insecure.
|
||||
@@ -768,8 +769,9 @@ void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE,
|
||||
int ArgIndex =
|
||||
llvm::StringSwitch<int>(Name)
|
||||
.Cases("scanf", "wscanf", "vscanf", "vwscanf", 0)
|
||||
.Cases("sprintf", "vsprintf", "fscanf", "fwscanf", "vfscanf",
|
||||
"vfwscanf", "sscanf", "swscanf", "vsscanf", "vswscanf", 1)
|
||||
.Cases("fscanf", "fwscanf", "vfscanf", "vfwscanf", "sscanf",
|
||||
"swscanf", "vsscanf", "vswscanf", 1)
|
||||
.Cases("sprintf", "vsprintf", "fprintf", 1)
|
||||
.Cases("swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy",
|
||||
"memmove", "memset", "strncpy", "strncat", DEPR_ONLY)
|
||||
.Default(UNKNOWN_CALL);
|
||||
|
||||
@@ -5,15 +5,24 @@
|
||||
// RUN: %clang_analyze_cc1 %s -verify -std=gnu99 \
|
||||
// RUN: -analyzer-checker=security.insecureAPI
|
||||
|
||||
#include "Inputs/system-header-simulator.h"
|
||||
|
||||
extern FILE *fp;
|
||||
extern char buf[128];
|
||||
|
||||
void builtin_function_call_crash_fixes(char *c) {
|
||||
__builtin_strncpy(c, "", 6);
|
||||
__builtin_memset(c, '\0', (0));
|
||||
__builtin_memcpy(c, c, 0);
|
||||
__builtin_sprintf(buf, "%s", c);
|
||||
__builtin_fprintf(fp, "%s", c);
|
||||
|
||||
#if __STDC_VERSION__ > 199901
|
||||
// expected-warning@-5{{Call to function 'strncpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
|
||||
// expected-warning@-5{{Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard.}}
|
||||
// expected-warning@-5{{Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
|
||||
// expected-warning@-7{{Call to function 'strncpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
|
||||
// expected-warning@-7{{Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard.}}
|
||||
// expected-warning@-7{{Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard.}}
|
||||
// expected-warning@-7{{Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard.}}
|
||||
// expected-warning@-7{{Call to function 'fprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard.}}
|
||||
#else
|
||||
// expected-no-diagnostics
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user