@@ -1903,7 +1903,38 @@ signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
1903
1903
* in data flow and taint tracking.
1904
1904
*/
1905
1905
module BarrierGuard< guardChecksSig / 3 guardChecks> {
1906
- /** Gets an expression node that is safely guarded by the given guard check. */
1906
+ /**
1907
+ * Gets an expression node that is safely guarded by the given guard check.
1908
+ *
1909
+ * For example, given the following code:
1910
+ * ```cpp
1911
+ * int x = source();
1912
+ * // ...
1913
+ * if(is_safe_int(x)) {
1914
+ * sink(x);
1915
+ * }
1916
+ * ```
1917
+ * and the following barrier guard predicate:
1918
+ * ```ql
1919
+ * predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
1920
+ * exists(Call call |
1921
+ * g.getUnconvertedResultExpression() = call and
1922
+ * call.getTarget().hasName("is_safe_int") and
1923
+ * e = call.getAnArgument() and
1924
+ * branch = true
1925
+ * )
1926
+ * }
1927
+ * ```
1928
+ * implementing `isBarrier` as:
1929
+ * ```ql
1930
+ * predicate isBarrier(DataFlow::Node barrier) {
1931
+ * barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getABarrierNode()
1932
+ * }
1933
+ * ```
1934
+ * will block flow from `x = source()` to `sink(x)`.
1935
+ *
1936
+ * NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
1937
+ */
1907
1938
ExprNode getABarrierNode ( ) {
1908
1939
exists ( IRGuardCondition g , Expr e , ValueNumber value , boolean edge |
1909
1940
e = value .getAnInstruction ( ) .getConvertedResultExpression ( ) and
@@ -1913,7 +1944,39 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
1913
1944
)
1914
1945
}
1915
1946
1916
- /** Gets an indirect expression node that is safely guarded by the given guard check. */
1947
+ /**
1948
+ * Gets an indirect expression node that is safely guarded by the given guard check.
1949
+ *
1950
+ * For example, given the following code:
1951
+ * ```cpp
1952
+ * int* p;
1953
+ * // ...
1954
+ * *p = source();
1955
+ * if(is_safe_pointer(p)) {
1956
+ * sink(*p);
1957
+ * }
1958
+ * ```
1959
+ * and the following barrier guard check:
1960
+ * ```ql
1961
+ * predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
1962
+ * exists(Call call |
1963
+ * g.getUnconvertedResultExpression() = call and
1964
+ * call.getTarget().hasName("is_safe_pointer") and
1965
+ * e = call.getAnArgument() and
1966
+ * branch = true
1967
+ * )
1968
+ * }
1969
+ * ```
1970
+ * implementing `isBarrier` as:
1971
+ * ```ql
1972
+ * predicate isBarrier(DataFlow::Node barrier) {
1973
+ * barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode()
1974
+ * }
1975
+ * ```
1976
+ * will block flow from `x = source()` to `sink(x)`.
1977
+ *
1978
+ * NOTE: If an non-indirect expression is tracked, use `getABarrierNode` instead.
1979
+ */
1917
1980
IndirectExprNode getAnIndirectBarrierNode ( ) {
1918
1981
exists ( IRGuardCondition g , Expr e , ValueNumber value , boolean edge |
1919
1982
e = value .getAnInstruction ( ) .getConvertedResultExpression ( ) and
0 commit comments