|
1 | 1 | import semmle.code.cpp.ir.dataflow.DataFlow
|
| 2 | +private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate |
| 3 | +private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil |
| 4 | +private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon |
2 | 5 | private import codeql.util.Unit
|
3 | 6 |
|
4 | 7 | module ProductFlow {
|
@@ -352,32 +355,119 @@ module ProductFlow {
|
352 | 355 | pragma[only_bind_out](succ.getNode().getEnclosingCallable())
|
353 | 356 | }
|
354 | 357 |
|
| 358 | + private newtype TKind = |
| 359 | + TInto(DataFlowCall call) { |
| 360 | + intoImpl1(_, _, call) or |
| 361 | + intoImpl2(_, _, call) |
| 362 | + } or |
| 363 | + TOutOf(DataFlowCall call) { |
| 364 | + outImpl1(_, _, call) or |
| 365 | + outImpl2(_, _, call) |
| 366 | + } or |
| 367 | + TJump() |
| 368 | + |
| 369 | + private predicate intoImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) { |
| 370 | + Flow1::PathGraph::edges(pred1, succ1) and |
| 371 | + pred1.getNode().(ArgumentNode).getCall() = call and |
| 372 | + succ1.getNode() instanceof ParameterNode |
| 373 | + } |
| 374 | + |
| 375 | + private predicate into1(Flow1::PathNode pred1, Flow1::PathNode succ1, TKind kind) { |
| 376 | + exists(DataFlowCall call | |
| 377 | + kind = TInto(call) and |
| 378 | + intoImpl1(pred1, succ1, call) |
| 379 | + ) |
| 380 | + } |
| 381 | + |
| 382 | + private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) { |
| 383 | + Flow1::PathGraph::edges(pred1, succ1) and |
| 384 | + exists(ReturnKindExt returnKind | |
| 385 | + succ1.getNode() = returnKind.getAnOutNode(call) and |
| 386 | + pred1.getNode().(ReturnNodeExt).getKind() = returnKind |
| 387 | + ) |
| 388 | + } |
| 389 | + |
| 390 | + private predicate out1(Flow1::PathNode pred1, Flow1::PathNode succ1, TKind kind) { |
| 391 | + exists(DataFlowCall call | |
| 392 | + outImpl1(pred1, succ1, call) and |
| 393 | + kind = TOutOf(call) |
| 394 | + ) |
| 395 | + } |
| 396 | + |
| 397 | + private predicate intoImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) { |
| 398 | + Flow2::PathGraph::edges(pred2, succ2) and |
| 399 | + pred2.getNode().(ArgumentNode).getCall() = call and |
| 400 | + succ2.getNode() instanceof ParameterNode |
| 401 | + } |
| 402 | + |
| 403 | + private predicate into2(Flow2::PathNode pred2, Flow2::PathNode succ2, TKind kind) { |
| 404 | + exists(DataFlowCall call | |
| 405 | + kind = TInto(call) and |
| 406 | + intoImpl2(pred2, succ2, call) |
| 407 | + ) |
| 408 | + } |
| 409 | + |
| 410 | + private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) { |
| 411 | + Flow2::PathGraph::edges(pred2, succ2) and |
| 412 | + exists(ReturnKindExt returnKind | |
| 413 | + succ2.getNode() = returnKind.getAnOutNode(call) and |
| 414 | + pred2.getNode().(ReturnNodeExt).getKind() = returnKind |
| 415 | + ) |
| 416 | + } |
| 417 | + |
| 418 | + private predicate out2(Flow2::PathNode pred2, Flow2::PathNode succ2, TKind kind) { |
| 419 | + exists(DataFlowCall call | |
| 420 | + kind = TOutOf(call) and |
| 421 | + outImpl2(pred2, succ2, call) |
| 422 | + ) |
| 423 | + } |
| 424 | + |
355 | 425 | pragma[nomagic]
|
356 | 426 | private predicate interprocEdge1(
|
357 |
| - Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1 |
| 427 | + Declaration predDecl, Declaration succDecl, Flow1::PathNode pred1, Flow1::PathNode succ1, |
| 428 | + TKind kind |
358 | 429 | ) {
|
359 | 430 | Flow1::PathGraph::edges(pred1, succ1) and
|
360 | 431 | predDecl != succDecl and
|
361 | 432 | pred1.getNode().getEnclosingCallable() = predDecl and
|
362 |
| - succ1.getNode().getEnclosingCallable() = succDecl |
| 433 | + succ1.getNode().getEnclosingCallable() = succDecl and |
| 434 | + ( |
| 435 | + into1(pred1, succ1, kind) |
| 436 | + or |
| 437 | + out1(pred1, succ1, kind) |
| 438 | + or |
| 439 | + kind = TJump() and |
| 440 | + not into1(pred1, succ1, _) and |
| 441 | + not out1(pred1, succ1, _) |
| 442 | + ) |
363 | 443 | }
|
364 | 444 |
|
365 | 445 | pragma[nomagic]
|
366 | 446 | private predicate interprocEdge2(
|
367 |
| - Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2 |
| 447 | + Declaration predDecl, Declaration succDecl, Flow2::PathNode pred2, Flow2::PathNode succ2, |
| 448 | + TKind kind |
368 | 449 | ) {
|
369 | 450 | Flow2::PathGraph::edges(pred2, succ2) and
|
370 | 451 | predDecl != succDecl and
|
371 | 452 | pred2.getNode().getEnclosingCallable() = predDecl and
|
372 |
| - succ2.getNode().getEnclosingCallable() = succDecl |
| 453 | + succ2.getNode().getEnclosingCallable() = succDecl and |
| 454 | + ( |
| 455 | + into2(pred2, succ2, kind) |
| 456 | + or |
| 457 | + out2(pred2, succ2, kind) |
| 458 | + or |
| 459 | + kind = TJump() and |
| 460 | + not into2(pred2, succ2, _) and |
| 461 | + not out2(pred2, succ2, _) |
| 462 | + ) |
373 | 463 | }
|
374 | 464 |
|
375 | 465 | private predicate interprocEdgePair(
|
376 | 466 | Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2
|
377 | 467 | ) {
|
378 |
| - exists(Declaration predDecl, Declaration succDecl | |
379 |
| - interprocEdge1(predDecl, succDecl, pred1, succ1) and |
380 |
| - interprocEdge2(predDecl, succDecl, pred2, succ2) |
| 468 | + exists(Declaration predDecl, Declaration succDecl, TKind kind | |
| 469 | + interprocEdge1(predDecl, succDecl, pred1, succ1, kind) and |
| 470 | + interprocEdge2(predDecl, succDecl, pred2, succ2, kind) |
381 | 471 | )
|
382 | 472 | }
|
383 | 473 |
|
|
0 commit comments