Author: henrywong Date: Mon Mar 5 07:41:15 2018 New Revision: 326709 URL: http://llvm.org/viewvc/llvm-project?rev=326709&view=rev Log: [analyzer] Improves the logic of GenericTaintChecker identifying stdin.
Summary: GenericTaintChecker can't recognize stdin in some cases. The reason is that `if (PtrTy->getPointeeType() == C.getASTContext().getFILEType()` does not hold when stdin is encountered. My platform is ubuntu16.04 64bit, gcc 5.4.0, glibc 2.23. The definition of stdin is as follows: ``` __BEGIN_NAMESPACE_STD /* The opaque type of streams. This is the definition used elsewhere. */ typedef struct _IO_FILE FILE; ___END_NAMESPACE_STD ... /* The opaque type of streams. This is the definition used elsewhere. */ typedef struct _IO_FILE __FILE; ... /* Standard streams. */ extern struct _IO_FILE *stdin; /* Standard input stream. */ extern struct _IO_FILE *stdout; /* Standard output stream. */ extern struct _IO_FILE *stderr; /* Standard error output stream. */ ``` The type of stdin is as follows AST: ``` ElaboratedType 0xc911170'struct _IO_FILE'sugar `-RecordType 0xc911150'struct _IO_FILE' `-CXXRecord 0xc923ff0'_IO_FILE' ``` `C.getASTContext().GetFILEType()` is as follows AST: ``` TypedefType 0xc932710 'FILE' sugar |-Typedef 0xc9111c0 'FILE' `-ElaboratedType 0xc911170 'struct _IO_FILE' sugar `-RecordType 0xc911150 'struct _IO_FILE' `-CXXRecord 0xc923ff0 '_IO_FILE' ``` So I think it's better to use `getCanonicalType()`. Reviewers: zaks.anna, NoQ, george.karpenkov, a.sidorin Reviewed By: zaks.anna, a.sidorin Subscribers: a.sidorin, cfe-commits, xazax.hun, szepet, MTC Differential Revision: https://reviews.llvm.org/D39159 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp cfe/trunk/test/Analysis/taint-generic.c Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp?rev=326709&r1=326708&r2=326709&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Mon Mar 5 07:41:15 2018 @@ -646,7 +646,8 @@ bool GenericTaintChecker::isStdin(const if ((D->getName().find("stdin") != StringRef::npos) && D->isExternC()) if (const PointerType * PtrTy = dyn_cast<PointerType>(D->getType().getTypePtr())) - if (PtrTy->getPointeeType() == C.getASTContext().getFILEType()) + if (PtrTy->getPointeeType().getCanonicalType() == + C.getASTContext().getFILEType().getCanonicalType()) return true; } return false; Modified: cfe/trunk/test/Analysis/taint-generic.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-generic.c?rev=326709&r1=326708&r2=326709&view=diff ============================================================================== --- cfe/trunk/test/Analysis/taint-generic.c (original) +++ cfe/trunk/test/Analysis/taint-generic.c Mon Mar 5 07:41:15 2018 @@ -1,10 +1,16 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s +// RUN: %clang_analyze_cc1 -DFILE_IS_STRUCT -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s int scanf(const char *restrict format, ...); int getchar(void); typedef struct _FILE FILE; +#ifdef FILE_IS_STRUCT +extern struct _FILE *stdin; +#else extern FILE *stdin; +#endif + int fscanf(FILE *restrict stream, const char *restrict format, ...); int sprintf(char *str, const char *format, ...); void setproctitle(const char *fmt, ...); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits