1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
| import cpp import semmle.code.cpp.controlflow.Guards import semmle.code.cpp.dataflow.DataFlow import semmle.code.cpp.controlflow.StackVariableReachability
predicate checkNameOpen(Function func) { func.getName().matches("RSA_new") }
predicate checkNameClose(Function func) { func.getName().matches("RSA_free") }
predicate mayCallFunction(Expr call, Function f) { call.(FunctionCall).getTarget() = f or call.(VariableCall).getVariable().getAnAssignedValue().getAChild*().(FunctionAccess).getTarget() = f }
predicate assignedToFieldOrGlobal(StackVariable v, Expr e) { e.(Assignment).getRValue() = v.getAnAccess() and not e.(Assignment).getLValue().(VariableAccess).getTarget() instanceof StackVariable or exists(Expr midExpr, Function mid, int arg | e.(FunctionCall).getArgument(arg) = v.getAnAccess() and mayCallFunction(e, mid) and midExpr.getEnclosingFunction() = mid and assignedToFieldOrGlobal(mid.getParameter(arg), midExpr) ) or e.(ConstructorFieldInit).getExpr() = v.getAnAccess() }
predicate openCall(Expr e) { checkNameOpen(e.(FunctionCall).getTarget()) or exists(ReturnStmt rtn | mayCallFunction(e, rtn.getEnclosingFunction()) and ( openCall(rtn.getExpr()) or exists(Variable v | v = rtn.getExpr().(VariableAccess).getTarget() and openCall(v.getAnAssignedValue()) and not assignedToFieldOrGlobal(v, _) ) ) ) }
predicate closeCall(ControlFlowNode n, Variable v) { exists(int arg | n.(Call).getArgument(arg) = v.getAnAccess() and checkNameClose(n.(Call).getTarget())) or exists(FunctionCall midcall, Function mid, int arg | n.(Call).getArgument(arg) = v.getAnAccess() and mayCallFunction(n, mid) and midcall.getEnclosingFunction() = mid and closeCall(midcall, mid.getParameter(arg)) ) }
predicate openDefinition(StackVariable v, ControlFlowNode def) { exists(Expr expr | exprDefinition(v, def, expr) and openCall(expr)) }
class OpenVariableReachability extends StackVariableReachabilityWithReassignment { OpenVariableReachability() { this = "OpenVariableReachability" }
override predicate isSourceActual(ControlFlowNode node, StackVariable v) { openDefinition(v, node) }
override predicate isSinkActual(ControlFlowNode node, StackVariable v) { exists(node.(AnalysedExpr).getNullSuccessor(v)) or closeCall(node, v) or assignedToFieldOrGlobal(v, node) or v.getFunction() = node.(ReturnStmt).getEnclosingFunction() }
override predicate isBarrier(ControlFlowNode node, StackVariable v) { definitionBarrier(v, node) } }
predicate openVariableReaches(StackVariable v, ControlFlowNode def, ControlFlowNode node) { exists(OpenVariableReachability r | r.reachesTo(def, _, node, v) or r.isSource(def, v) and node = def ) }
class OpenReachability extends StackVariableReachabilityExt { OpenReachability() { this = "OpenReachability" }
override predicate isSource(ControlFlowNode node, StackVariable v) { openDefinition(v, node) }
override predicate isSink(ControlFlowNode node, StackVariable v) { v.getFunction() = node.(ReturnStmt).getEnclosingFunction() }
override predicate isBarrier( ControlFlowNode source, ControlFlowNode node, ControlFlowNode next, StackVariable v ) { isSource(source, v) and next = node.getASuccessor() and exists(StackVariable v0 | openVariableReaches(v0, source, node) | node.(AnalysedExpr).getNullSuccessor(v0) = next or closeCall(node, v0) or assignedToFieldOrGlobal(v0, node) ) } }
predicate openReaches(ControlFlowNode def, ControlFlowNode node) { exists(OpenReachability r | r.reaches(def, _, node)) }
from ControlFlowNode def, ReturnStmt ret where openReaches(def, ret) and not exists(StackVariable v | openVariableReaches(v, def, ret) and ret.getAChild*() = v.getAnAccess() ) select def, ret,def.getLocation()
|