@@ -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 a 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
@@ -1912,6 +1943,84 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
1912
1943
g .controls ( result .getBasicBlock ( ) , edge )
1913
1944
)
1914
1945
}
1946
+
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 a non-indirect expression is tracked, use `getABarrierNode` instead.
1979
+ */
1980
+ IndirectExprNode getAnIndirectBarrierNode ( ) { result = getAnIndirectBarrierNode ( _) }
1981
+
1982
+ /**
1983
+ * Gets an indirect expression node with indirection index `indirectionIndex` that is
1984
+ * safely guarded by the given guard check.
1985
+ *
1986
+ * For example, given the following code:
1987
+ * ```cpp
1988
+ * int* p;
1989
+ * // ...
1990
+ * *p = source();
1991
+ * if(is_safe_pointer(p)) {
1992
+ * sink(*p);
1993
+ * }
1994
+ * ```
1995
+ * and the following barrier guard check:
1996
+ * ```ql
1997
+ * predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
1998
+ * exists(Call call |
1999
+ * g.getUnconvertedResultExpression() = call and
2000
+ * call.getTarget().hasName("is_safe_pointer") and
2001
+ * e = call.getAnArgument() and
2002
+ * branch = true
2003
+ * )
2004
+ * }
2005
+ * ```
2006
+ * implementing `isBarrier` as:
2007
+ * ```ql
2008
+ * predicate isBarrier(DataFlow::Node barrier) {
2009
+ * barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode(1)
2010
+ * }
2011
+ * ```
2012
+ * will block flow from `x = source()` to `sink(x)`.
2013
+ *
2014
+ * NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
2015
+ */
2016
+ IndirectExprNode getAnIndirectBarrierNode ( int indirectionIndex ) {
2017
+ exists ( IRGuardCondition g , Expr e , ValueNumber value , boolean edge |
2018
+ e = value .getAnInstruction ( ) .getConvertedResultExpression ( ) and
2019
+ result .getConvertedExpr ( indirectionIndex ) = e and
2020
+ guardChecks ( g , value .getAnInstruction ( ) .getConvertedResultExpression ( ) , edge ) and
2021
+ g .controls ( result .getBasicBlock ( ) , edge )
2022
+ )
2023
+ }
1915
2024
}
1916
2025
1917
2026
/**
0 commit comments