@@ -2417,6 +2417,19 @@ class ContentSet instanceof Content {
24172417 }
24182418}
24192419
2420+ private signature class ParamSig ;
2421+
2422+ private module WithParam< ParamSig P> {
2423+ /**
2424+ * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
2425+ *
2426+ * The expression `e` is expected to be a syntactic part of the guard `g`.
2427+ * For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
2428+ * the argument `x`.
2429+ */
2430+ signature predicate guardChecksSig ( IRGuardCondition g , Expr e , boolean branch , P param ) ;
2431+ }
2432+
24202433/**
24212434 * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
24222435 *
@@ -2438,7 +2451,7 @@ private predicate controls(IRGuardCondition g, Node n, boolean edge) {
24382451 * This is expected to be used in `isBarrier`/`isSanitizer` definitions
24392452 * in data flow and taint tracking.
24402453 */
2441- module BarrierGuard < guardChecksSig / 3 guardChecks> {
2454+ module ParameterizedBarrierGuard < ParamSig P , WithParam < P > :: guardChecksSig / 4 guardChecks> {
24422455 bindingset [ value, n]
24432456 pragma [ inline_late]
24442457 private predicate convertedExprHasValueNumber ( ValueNumber value , Node n ) {
@@ -2448,12 +2461,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
24482461 )
24492462 }
24502463
2451- private predicate guardChecksNode ( IRGuardCondition g , Node n , boolean branch ) {
2452- guardChecks ( g , n .asOperand ( ) .getDef ( ) .getConvertedResultExpression ( ) , branch )
2464+ private predicate guardChecksNode ( IRGuardCondition g , Node n , boolean branch , P p ) {
2465+ guardChecks ( g , n .asOperand ( ) .getDef ( ) .getConvertedResultExpression ( ) , branch , p )
24532466 }
24542467
24552468 /**
2456- * Gets an expression node that is safely guarded by the given guard check.
2469+ * Gets an expression node that is safely guarded by the given guard check
2470+ * when the parameter is `p`.
24572471 *
24582472 * For example, given the following code:
24592473 * ```cpp
@@ -2484,19 +2498,27 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
24842498 *
24852499 * NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
24862500 */
2487- Node getABarrierNode ( ) {
2501+ Node getABarrierNode ( P p ) {
24882502 exists ( IRGuardCondition g , ValueNumber value , boolean edge |
24892503 convertedExprHasValueNumber ( value , result ) and
24902504 guardChecks ( g ,
2491- pragma [ only_bind_into ] ( value .getAnInstruction ( ) .getConvertedResultExpression ( ) ) , edge ) and
2505+ pragma [ only_bind_into ] ( value .getAnInstruction ( ) .getConvertedResultExpression ( ) ) , edge , p ) and
24922506 controls ( g , result , edge )
24932507 )
24942508 or
2495- result = SsaImpl:: BarrierGuard< guardChecksNode / 3 > :: getABarrierNode ( )
2509+ result = SsaImpl:: BarrierGuard< P , guardChecksNode / 4 > :: getABarrierNode ( p )
24962510 }
24972511
24982512 /**
2499- * Gets an indirect expression node that is safely guarded by the given guard check.
2513+ * Gets an expression node that is safely guarded by the given guard check.
2514+ *
2515+ * See `getABarrierNode/1` for examples.
2516+ */
2517+ Node getABarrierNode ( ) { result = getABarrierNode ( _) }
2518+
2519+ /**
2520+ * Gets an indirect expression node that is safely guarded by the given
2521+ * guard check with parameter `p`.
25002522 *
25012523 * For example, given the following code:
25022524 * ```cpp
@@ -2528,6 +2550,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
25282550 *
25292551 * NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
25302552 */
2553+ Node getAnIndirectBarrierNode ( P p ) { result = getAnIndirectBarrierNode ( _, p ) }
2554+
2555+ /**
2556+ * Gets an indirect expression node that is safely guarded by the given guard check.
2557+ *
2558+ * See `getAnIndirectBarrierNode/1` for examples.
2559+ */
25312560 Node getAnIndirectBarrierNode ( ) { result = getAnIndirectBarrierNode ( _) }
25322561
25332562 bindingset [ value, n]
@@ -2542,10 +2571,10 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
25422571 }
25432572
25442573 private predicate guardChecksIndirectNode (
2545- IRGuardCondition g , Node n , boolean branch , int indirectionIndex
2574+ IRGuardCondition g , Node n , boolean branch , int indirectionIndex , P p
25462575 ) {
25472576 guardChecks ( g , n .asIndirectOperand ( indirectionIndex ) .getDef ( ) .getConvertedResultExpression ( ) ,
2548- branch )
2577+ branch , p )
25492578 }
25502579
25512580 /**
@@ -2582,19 +2611,44 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
25822611 *
25832612 * NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
25842613 */
2585- Node getAnIndirectBarrierNode ( int indirectionIndex ) {
2614+ Node getAnIndirectBarrierNode ( int indirectionIndex , P p ) {
25862615 exists ( IRGuardCondition g , ValueNumber value , boolean edge |
25872616 indirectConvertedExprHasValueNumber ( indirectionIndex , value , result ) and
25882617 guardChecks ( g ,
2589- pragma [ only_bind_into ] ( value .getAnInstruction ( ) .getConvertedResultExpression ( ) ) , edge ) and
2618+ pragma [ only_bind_into ] ( value .getAnInstruction ( ) .getConvertedResultExpression ( ) ) , edge , p ) and
25902619 controls ( g , result , edge )
25912620 )
25922621 or
25932622 result =
2594- SsaImpl:: BarrierGuardWithIntParam< guardChecksIndirectNode / 4 > :: getABarrierNode ( indirectionIndex )
2623+ SsaImpl:: BarrierGuardWithIntParam< P , guardChecksIndirectNode / 5 > :: getABarrierNode ( indirectionIndex ,
2624+ p )
25952625 }
25962626}
25972627
2628+ /**
2629+ * Provides a set of barrier nodes for a guard that validates an expression.
2630+ *
2631+ * This is expected to be used in `isBarrier`/`isSanitizer` definitions
2632+ * in data flow and taint tracking.
2633+ */
2634+ module BarrierGuard< guardChecksSig / 3 guardChecks> {
2635+ private predicate guardChecks ( IRGuardCondition g , Expr e , boolean branch , Unit unit ) {
2636+ guardChecks ( g , e , branch ) and
2637+ exists ( unit )
2638+ }
2639+
2640+ import ParameterizedBarrierGuard< Unit , guardChecks / 4 >
2641+ }
2642+
2643+ private module InstrWithParam< ParamSig P> {
2644+ /**
2645+ * Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
2646+ */
2647+ signature predicate instructionGuardChecksSig (
2648+ IRGuardCondition g , Instruction instr , boolean branch , P p
2649+ ) ;
2650+ }
2651+
25982652/**
25992653 * Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
26002654 */
@@ -2606,7 +2660,9 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
26062660 * This is expected to be used in `isBarrier`/`isSanitizer` definitions
26072661 * in data flow and taint tracking.
26082662 */
2609- module InstructionBarrierGuard< instructionGuardChecksSig / 3 instructionGuardChecks> {
2663+ module ParameterizedInstructionBarrierGuard<
2664+ ParamSig P, InstrWithParam< P > :: instructionGuardChecksSig / 4 instructionGuardChecks>
2665+ {
26102666 bindingset [ value, n]
26112667 pragma [ inline_late]
26122668 private predicate operandHasValueNumber ( ValueNumber value , Node n ) {
@@ -2616,21 +2672,27 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
26162672 )
26172673 }
26182674
2619- private predicate guardChecksNode ( IRGuardCondition g , Node n , boolean branch ) {
2620- instructionGuardChecks ( g , n .asOperand ( ) .getDef ( ) , branch )
2675+ private predicate guardChecksNode ( IRGuardCondition g , Node n , boolean branch , P p ) {
2676+ instructionGuardChecks ( g , n .asOperand ( ) .getDef ( ) , branch , p )
26212677 }
26222678
2623- /** Gets a node that is safely guarded by the given guard check. */
2624- Node getABarrierNode ( ) {
2679+ /**
2680+ * Gets a node that is safely guarded by the given guard check with
2681+ * parameter `p`.
2682+ */
2683+ Node getABarrierNode ( P p ) {
26252684 exists ( IRGuardCondition g , ValueNumber value , boolean edge |
2626- instructionGuardChecks ( g , pragma [ only_bind_into ] ( value .getAnInstruction ( ) ) , edge ) and
2685+ instructionGuardChecks ( g , pragma [ only_bind_into ] ( value .getAnInstruction ( ) ) , edge , p ) and
26272686 operandHasValueNumber ( value , result ) and
26282687 controls ( g , result , edge )
26292688 )
26302689 or
2631- result = SsaImpl:: BarrierGuard< guardChecksNode / 3 > :: getABarrierNode ( )
2690+ result = SsaImpl:: BarrierGuard< P , guardChecksNode / 4 > :: getABarrierNode ( p )
26322691 }
26332692
2693+ /** Gets a node that is safely guarded by the given guard check. */
2694+ Node getABarrierNode ( ) { result = getABarrierNode ( _) }
2695+
26342696 bindingset [ value, n]
26352697 pragma [ inline_late]
26362698 private predicate indirectOperandHasValueNumber ( ValueNumber value , int indirectionIndex , Node n ) {
@@ -2641,25 +2703,52 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
26412703 }
26422704
26432705 private predicate guardChecksIndirectNode (
2644- IRGuardCondition g , Node n , boolean branch , int indirectionIndex
2706+ IRGuardCondition g , Node n , boolean branch , int indirectionIndex , P p
26452707 ) {
2646- instructionGuardChecks ( g , n .asIndirectOperand ( indirectionIndex ) .getDef ( ) , branch )
2708+ instructionGuardChecks ( g , n .asIndirectOperand ( indirectionIndex ) .getDef ( ) , branch , p )
26472709 }
26482710
26492711 /**
26502712 * Gets an indirect node with indirection index `indirectionIndex` that is
2651- * safely guarded by the given guard check.
2713+ * safely guarded by the given guard check with parameter `p` .
26522714 */
2653- Node getAnIndirectBarrierNode ( int indirectionIndex ) {
2715+ Node getAnIndirectBarrierNode ( int indirectionIndex , P p ) {
26542716 exists ( IRGuardCondition g , ValueNumber value , boolean edge |
2655- instructionGuardChecks ( g , pragma [ only_bind_into ] ( value .getAnInstruction ( ) ) , edge ) and
2717+ instructionGuardChecks ( g , pragma [ only_bind_into ] ( value .getAnInstruction ( ) ) , edge , p ) and
26562718 indirectOperandHasValueNumber ( value , indirectionIndex , result ) and
26572719 controls ( g , result , edge )
26582720 )
26592721 or
26602722 result =
2661- SsaImpl:: BarrierGuardWithIntParam< guardChecksIndirectNode / 4 > :: getABarrierNode ( indirectionIndex )
2723+ SsaImpl:: BarrierGuardWithIntParam< P , guardChecksIndirectNode / 5 > :: getABarrierNode ( indirectionIndex ,
2724+ p )
26622725 }
2726+
2727+ /**
2728+ * Gets an indirect node that is safely guarded by the given guard check
2729+ * with parameter `p`.
2730+ */
2731+ Node getAnIndirectBarrierNode ( P p ) { result = getAnIndirectBarrierNode ( _, p ) }
2732+
2733+ /** Gets an indirect node that is safely guarded by the given guard check. */
2734+ Node getAnIndirectBarrierNode ( ) { result = getAnIndirectBarrierNode ( _) }
2735+ }
2736+
2737+ /**
2738+ * Provides a set of barrier nodes for a guard that validates an instruction.
2739+ *
2740+ * This is expected to be used in `isBarrier`/`isSanitizer` definitions
2741+ * in data flow and taint tracking.
2742+ */
2743+ module InstructionBarrierGuard< instructionGuardChecksSig / 3 instructionGuardChecks> {
2744+ private predicate instructionGuardChecks (
2745+ IRGuardCondition g , Instruction i , boolean branch , Unit unit
2746+ ) {
2747+ instructionGuardChecks ( g , i , branch ) and
2748+ exists ( unit )
2749+ }
2750+
2751+ import ParameterizedInstructionBarrierGuard< Unit , instructionGuardChecks / 4 >
26632752}
26642753
26652754/**
0 commit comments