|
6 | 6 | * @precision very-high |
7 | 7 | * @problem.severity error |
8 | 8 | * @tags external/cert/id/sig35-c |
| 9 | + * correctness |
| 10 | + * security |
9 | 11 | * external/cert/obligation/rule |
10 | 12 | */ |
11 | 13 |
|
12 | 14 | import cpp |
13 | 15 | import codingstandards.c.cert |
| 16 | +import codingstandards.c.Signal |
| 17 | +import semmle.code.cpp.dataflow.DataFlow |
14 | 18 |
|
15 | | -from |
| 19 | +/** |
| 20 | + * CFG nodes preceeding a `ReturnStmt` |
| 21 | + */ |
| 22 | +ControlFlowNode reachesReturn(ReturnStmt return) { |
| 23 | + result = return |
| 24 | + or |
| 25 | + exists(ControlFlowNode mid | |
| 26 | + result = mid.getAPredecessor() and |
| 27 | + mid = reachesReturn(return) and |
| 28 | + // stop recursion on calls to `abort`, `_Exit` and "quick_exit" |
| 29 | + not result instanceof AbortCall |
| 30 | + ) |
| 31 | +} |
| 32 | + |
| 33 | +from ReturnStmt return, ComputationalExceptionSignal e |
16 | 34 | where |
17 | | - not isExcluded(x, SignalHandlersPackage::doNotReturnFromAComputationalExceptionHandlerQuery()) and |
18 | | -select |
| 35 | + not isExcluded(return, SignalHandlersPackage::doNotReturnFromAComputationalExceptionHandlerQuery()) and |
| 36 | + exists(SignalHandler handler | |
| 37 | + handler = return.getEnclosingFunction() and |
| 38 | + // computational exception handler |
| 39 | + DataFlow::localExprFlow(e.getExpr(), handler.getRegistration().getArgument(0)) and |
| 40 | + // control flow reaches a return statement |
| 41 | + reachesReturn(return) = handler.getBlock() |
| 42 | + ) |
| 43 | +select return, "Do not return from a $@ signal handler.", e, "computational exception" |
0 commit comments