зеркало из https://github.com/microsoft/clang-1.git
[analyzer] Add socket API as a source of taint.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148518 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
be97b7edb1
Коммит
2bf8fd8408
|
@ -76,6 +76,7 @@ private:
|
|||
typedef const ProgramState *(GenericTaintChecker::*FnCheck)(const CallExpr *,
|
||||
CheckerContext &C) const;
|
||||
const ProgramState *postScanf(const CallExpr *CE, CheckerContext &C) const;
|
||||
const ProgramState *postSocket(const CallExpr *CE, CheckerContext &C) const;
|
||||
const ProgramState *postRetTaint(const CallExpr *CE, CheckerContext &C) const;
|
||||
|
||||
/// Taint the scanned input if the file is tainted.
|
||||
|
@ -207,6 +208,8 @@ GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
|
|||
.Case("atoi", TaintPropagationRule(0, ReturnValueIndex))
|
||||
.Case("atol", TaintPropagationRule(0, ReturnValueIndex))
|
||||
.Case("atoll", TaintPropagationRule(0, ReturnValueIndex))
|
||||
.Case("read", TaintPropagationRule(0, 2, 1, true))
|
||||
.Case("pread", TaintPropagationRule(InvalidArgIndex, 1, true))
|
||||
.Default(TaintPropagationRule());
|
||||
|
||||
if (!Rule.isNull())
|
||||
|
@ -360,6 +363,7 @@ void GenericTaintChecker::addSourcesPost(const CallExpr *CE,
|
|||
.Case("fopen", &GenericTaintChecker::postRetTaint)
|
||||
.Case("fdopen", &GenericTaintChecker::postRetTaint)
|
||||
.Case("freopen", &GenericTaintChecker::postRetTaint)
|
||||
.Case("socket", &GenericTaintChecker::postSocket)
|
||||
.Default(0);
|
||||
|
||||
// If the callee isn't defined, it is not of security concern.
|
||||
|
@ -501,6 +505,23 @@ const ProgramState *GenericTaintChecker::preFscanf(const CallExpr *CE,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// If argument 0(protocol domain) is network, the return value should get taint.
|
||||
const ProgramState *GenericTaintChecker::postSocket(const CallExpr *CE,
|
||||
CheckerContext &C) const {
|
||||
assert(CE->getNumArgs() >= 3);
|
||||
const ProgramState *State = C.getState();
|
||||
|
||||
SourceLocation DomLoc = CE->getArg(0)->getExprLoc();
|
||||
StringRef DomName = C.getMacroNameOrSpelling(DomLoc);
|
||||
// White list the internal communication protocols.
|
||||
if (DomName.equals("AF_SYSTEM") || DomName.equals("AF_LOCAL") ||
|
||||
DomName.equals("AF_UNIX") || DomName.equals("AF_RESERVED_36"))
|
||||
return State;
|
||||
State = State->addTaint(CE, C.getLocationContext());
|
||||
return State;
|
||||
}
|
||||
|
||||
const ProgramState *GenericTaintChecker::postScanf(const CallExpr *CE,
|
||||
CheckerContext &C) const {
|
||||
const ProgramState *State = C.getState();
|
||||
|
@ -627,6 +648,12 @@ bool GenericTaintChecker::checkSystemCall(const CallExpr *CE,
|
|||
unsigned ArgNum = llvm::StringSwitch<unsigned>(Name)
|
||||
.Case("system", 0)
|
||||
.Case("popen", 0)
|
||||
.Case("execl", 0)
|
||||
.Case("execle", 0)
|
||||
.Case("execlp", 0)
|
||||
.Case("execv", 0)
|
||||
.Case("execvp", 0)
|
||||
.Case("execvP", 0)
|
||||
.Default(UINT_MAX);
|
||||
|
||||
if (ArgNum == UINT_MAX)
|
||||
|
|
|
@ -148,5 +148,26 @@ void testTaintedBufferSize() {
|
|||
// If both buffers are trusted, do not issue a warning.
|
||||
char *dst2 = (char*)malloc(ts*sizeof(char)); // expected-warning {{Tainted data is used to specify the buffer size}}
|
||||
strncat(dst2, dst, ts); // no-warning
|
||||
|
||||
}
|
||||
|
||||
#define AF_UNIX 1 /* local to host (pipes) */
|
||||
#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
|
||||
#define AF_LOCAL AF_UNIX /* backward compatibility */
|
||||
#define SOCK_STREAM 1
|
||||
int socket(int, int, int);
|
||||
size_t read(int, void *, size_t);
|
||||
int execl(const char *, const char *, ...);
|
||||
|
||||
void testSocket() {
|
||||
int sock;
|
||||
char buffer[100];
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
read(sock, buffer, 100);
|
||||
execl(buffer, "filename", 0); // expected-warning {{Tainted data passed to a system call}}
|
||||
|
||||
sock = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
read(sock, buffer, 100);
|
||||
execl(buffer, "filename", 0); // no-warning
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче