mirror of
https://github.com/hohn/codeql-sample-polkit.git
synced 2025-12-16 05:43:04 +01:00
76 lines
2.6 KiB
Plaintext
76 lines
2.6 KiB
Plaintext
/**
|
|
* @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
|