diff --git a/.lgtm/cpp-queries/chunk_from_chars.ql b/.lgtm/cpp-queries/chunk_from_chars.ql new file mode 100644 index 000000000..c393e7ee5 --- /dev/null +++ b/.lgtm/cpp-queries/chunk_from_chars.ql @@ -0,0 +1,51 @@ +/** + * @name Invalid use of chunk_from_chars() macro + * @description The chunk_from_chars() macro creates a temporary chunk_t, which + * is not defined outside of the block in which it has been used, + * therefore, compilers might optimize out the assignment. + * @kind path-problem + * @problem.severity error + * @id strongswan/invalid-chunk-from-chars + * @tags correctness + * @precision very-high + */ +import cpp +import DataFlow::PathGraph +import semmle.code.cpp.dataflow.DataFlow + +class ChunkFromChars extends Expr { + ChunkFromChars() { + this = any(MacroInvocation mi | + mi.getOutermostMacroAccess().getMacroName() = "chunk_from_chars" + /* ignore global static uses of the macro */ + and exists (Block b | mi.getExpr().getEnclosingBlock() = b) + ).getExpr() + } +} + +class ChunkFromCharsUsage extends DataFlow::Configuration { + ChunkFromCharsUsage() { this = "ChunkFromCharsUsage" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr() instanceof ChunkFromChars + } + + override predicate isSink(DataFlow::Node sink) { + exists(sink.asExpr()) + } + + override predicate isBarrierOut(DataFlow::Node node) { + /* don't track beyond function calls */ + exists(FunctionCall fc | node.asExpr().getParent*() = fc) + } +} + +Block enclosingBlock(Block b) { + result = b.getEnclosingBlock() +} + +from ChunkFromCharsUsage usage, DataFlow::PathNode source, DataFlow::PathNode sink +where + usage.hasFlowPath(source, sink) + and not source.getNode().asExpr().getEnclosingBlock() = enclosingBlock*(sink.getNode().asExpr().getEnclosingBlock()) +select source, source, sink, "Invalid use of chunk_from_chars() result in sibling/parent block."