Compact findings from argv-out-of-bounds-1 in -2, update README

This commit is contained in:
Michael Hohn
2022-03-04 12:43:55 -08:00
committed by =Michael Hohn
parent 3660be0eeb
commit 182f7794a6
3 changed files with 90 additions and 6 deletions

75
argv-out-of-bounds-2.ql Normal file
View File

@@ -0,0 +1,75 @@
/**
* @name Argv index out-of-bounds-2
* @ kind problem
* @id cpp/example/argv-out-of-bounds-2
*/
import cpp
import semmle.code.cpp.controlflow.SSA
//
// Use https://codeql.github.com/docs/codeql-language-guides/codeql-library-for-cpp/
// to find the codeql class matching c++ syntax
//
// See https://codeql.github.com/docs/codeql-language-guides/using-range-analsis-in-cpp/
// for the entry points to the range analysis library. Namely,
// `import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis`
// and
// `lowerBound(expr)`
//
// There is a short example of SSA use at
// https://codeql.github.com/docs/codeql-language-guides/detecting-a-potential-buffer-overflow/#improving-the-query-using-the-ssa-library
//
from
Parameter argc, RelationalOperation cmp, Variable n, Parameter argv, ArrayExpr argvAccess,
AssignExpr argvSet, SsaDefinition invalidN, SsaDefinition invalidNDef
where
//
// consider argc and n when they occur in the same comparison
//
argc.getName() = "argc" and
argc.getAnAccess() = cmp.getAnOperand().getAChild*() and
n.getAnAccess() = cmp.getAnOperand().getAChild*() and
not n instanceof Parameter and
//
// find indexed reads of argv using n
//
argvAccess.getArrayBase() = argv.getAnAccess() and
argvAccess.getArrayOffset() = n.getAnAccess() and
//
// find the indexed writes of argv
//
exists(ArrayExpr aa |
aa.getArrayBase() = argv.getAnAccess() and
aa.getArrayOffset() = n.getAnAccess() and
argvSet.getLValue() = aa and
/* Separate the read */
aa != argvAccess
) and
//
// Ignore argv use when it's an argument of strcmp
//
not exists(FunctionCall strcmp |
strcmp.getTarget().getName() = "strcmp" and
strcmp.getAnArgument*() = argvAccess
) and
//
// To track only values of the argv index that are too high, we need to
// stay on branches of the CFG matching a SSA definition of the index
// variable with known high value.
//
cmp.getLesserOperand() = invalidN.getAUse(n) and
cmp.getGreaterOperand() = argc.getAnAccess() and
invalidNDef = invalidN.getAnUltimateSsaDefinition(n) and
invalidNDef.getDefiningValue(n).getValue().toInt() > 0 and
//
// We still find an access inside the loop,
// opt_user = g_strdup (argv[n]);
// so let's narrow to branches outside the loop.
//
invalidN.getAUse(n) = argvAccess.getArrayOffset() and
argvSet = cmp.getAFalseSuccessor().getASuccessor*() and
argvAccess = cmp.getAFalseSuccessor().getASuccessor*()
select argc, cmp, n, argvAccess, argvSet, invalidNDef, invalidN