Swift: Understand binary pointwise operations.

This commit is contained in:
Geoffrey White
2023-03-02 12:26:00 +00:00
parent ec2c58b416
commit 27ec36298f
8 changed files with 128 additions and 14 deletions

View File

@@ -46,6 +46,9 @@ private module Cached {
// allow flow through arithmetic (this case includes string concatenation)
nodeTo.asExpr().(ArithmeticOperation).getAnOperand() = nodeFrom.asExpr()
or
// allow flow through bitwise operations
nodeTo.asExpr().(BitwiseOperation).getAnOperand() = nodeFrom.asExpr()
or
// allow flow through assignment operations (e.g. `+=`)
exists(AssignOperation op |
nodeFrom.asExpr() = op.getSource() and

View File

@@ -6,6 +6,8 @@ private import codeql.swift.elements.expr.PrefixUnaryExpr
* A bitwise operation, such as:
* ```
* a & b
* a << b
* ~a
* ```
*/
class BitwiseOperation extends Expr {
@@ -27,6 +29,8 @@ class BitwiseOperation extends Expr {
* A binary bitwise operation, such as:
* ```
* a & b
* a << b
* a .^ b
* ```
*/
class BinaryBitwiseOperation extends BinaryExpr {
@@ -34,6 +38,9 @@ class BinaryBitwiseOperation extends BinaryExpr {
this instanceof AndBitwiseExpr or
this instanceof OrBitwiseExpr or
this instanceof XorBitwiseExpr or
this instanceof PointwiseAndExpr or
this instanceof PointwiseOrExpr or
this instanceof PointwiseXorExpr or
this instanceof ShiftLeftBitwiseExpr or
this instanceof ShiftRightBitwiseExpr
}
@@ -69,6 +76,36 @@ class XorBitwiseExpr extends BinaryExpr {
XorBitwiseExpr() { this.getStaticTarget().getName() = "^(_:_:)" }
}
/**
* A pointwise bitwise-and expression:
* ```
* a .& b
* ```
*/
class PointwiseAndExpr extends BinaryExpr {
PointwiseAndExpr() { this.getOperator().getName() = ".&(_:_:)" }
}
/**
* A pointwise bitwise-or expression:
* ```
* a .| b
* ```
*/
class PointwiseOrExpr extends BinaryExpr {
PointwiseOrExpr() { this.getOperator().getName() = ".|(_:_:)" }
}
/**
* A pointwise bitwise exclusive-or expression:
* ```
* a .^ b
* ```
*/
class PointwiseXorExpr extends BinaryExpr {
PointwiseXorExpr() { this.getOperator().getName() = ".^(_:_:)" }
}
/**
* A bitwise shift left expression.
* ```

View File

@@ -101,6 +101,27 @@
| simple.swift:68:3:68:3 | [post] &... | simple.swift:69:13:69:13 | e |
| simple.swift:68:3:68:3 | e | simple.swift:68:3:68:3 | &... |
| simple.swift:68:8:68:8 | 100 | simple.swift:68:3:68:3 | &... |
| simple.swift:73:13:73:13 | 0 | simple.swift:73:13:73:24 | ... .\|(_:_:) ... |
| simple.swift:73:17:73:24 | call to source() | simple.swift:73:13:73:24 | ... .\|(_:_:) ... |
| simple.swift:74:13:74:20 | call to source() | simple.swift:74:13:74:24 | ... .\|(_:_:) ... |
| simple.swift:74:24:74:24 | 0 | simple.swift:74:13:74:24 | ... .\|(_:_:) ... |
| simple.swift:76:13:76:13 | 0xffff | simple.swift:76:13:76:29 | ... .&(_:_:) ... |
| simple.swift:76:22:76:29 | call to source() | simple.swift:76:13:76:29 | ... .&(_:_:) ... |
| simple.swift:77:13:77:20 | call to source() | simple.swift:77:13:77:24 | ... .&(_:_:) ... |
| simple.swift:77:24:77:24 | 0xffff | simple.swift:77:13:77:24 | ... .&(_:_:) ... |
| simple.swift:79:13:79:13 | 0xffff | simple.swift:79:13:79:29 | ... .^(_:_:) ... |
| simple.swift:79:22:79:29 | call to source() | simple.swift:79:13:79:29 | ... .^(_:_:) ... |
| simple.swift:80:13:80:20 | call to source() | simple.swift:80:13:80:24 | ... .^(_:_:) ... |
| simple.swift:80:24:80:24 | 0xffff | simple.swift:80:13:80:24 | ... .^(_:_:) ... |
| simple.swift:82:13:82:20 | call to source() | simple.swift:82:13:82:25 | ... .<<(_:_:) ... |
| simple.swift:82:25:82:25 | 1 | simple.swift:82:13:82:25 | ... .<<(_:_:) ... |
| simple.swift:83:13:83:20 | call to source() | simple.swift:83:13:83:26 | ... .&<<(_:_:) ... |
| simple.swift:83:26:83:26 | 1 | simple.swift:83:13:83:26 | ... .&<<(_:_:) ... |
| simple.swift:84:13:84:20 | call to source() | simple.swift:84:13:84:25 | ... .>>(_:_:) ... |
| simple.swift:84:25:84:25 | 1 | simple.swift:84:13:84:25 | ... .>>(_:_:) ... |
| simple.swift:85:13:85:20 | call to source() | simple.swift:85:13:85:26 | ... .&>>(_:_:) ... |
| simple.swift:85:26:85:26 | 1 | simple.swift:85:13:85:26 | ... .&>>(_:_:) ... |
| simple.swift:87:14:87:21 | call to source() | simple.swift:87:13:87:21 | call to ~(_:) |
| subscript.swift:1:7:1:7 | SSA def(self) | subscript.swift:1:7:1:7 | self[return] |
| subscript.swift:1:7:1:7 | SSA def(self) | subscript.swift:1:7:1:7 | self[return] |
| subscript.swift:1:7:1:7 | self | subscript.swift:1:7:1:7 | SSA def(self) |

View File

@@ -26,6 +26,17 @@ edges
| simple.swift:60:8:60:15 | call to source() : | simple.swift:63:13:63:13 | d |
| simple.swift:66:8:66:15 | call to source() : | simple.swift:67:13:67:13 | e |
| simple.swift:66:8:66:15 | call to source() : | simple.swift:69:13:69:13 | e |
| simple.swift:73:17:73:24 | call to source() : | simple.swift:73:13:73:24 | ... .\|(_:_:) ... |
| simple.swift:74:13:74:20 | call to source() : | simple.swift:74:13:74:24 | ... .\|(_:_:) ... |
| simple.swift:76:22:76:29 | call to source() : | simple.swift:76:13:76:29 | ... .&(_:_:) ... |
| simple.swift:77:13:77:20 | call to source() : | simple.swift:77:13:77:24 | ... .&(_:_:) ... |
| simple.swift:79:22:79:29 | call to source() : | simple.swift:79:13:79:29 | ... .^(_:_:) ... |
| simple.swift:80:13:80:20 | call to source() : | simple.swift:80:13:80:24 | ... .^(_:_:) ... |
| simple.swift:82:13:82:20 | call to source() : | simple.swift:82:13:82:25 | ... .<<(_:_:) ... |
| simple.swift:83:13:83:20 | call to source() : | simple.swift:83:13:83:26 | ... .&<<(_:_:) ... |
| simple.swift:84:13:84:20 | call to source() : | simple.swift:84:13:84:25 | ... .>>(_:_:) ... |
| simple.swift:85:13:85:20 | call to source() : | simple.swift:85:13:85:26 | ... .&>>(_:_:) ... |
| simple.swift:87:14:87:21 | call to source() : | simple.swift:87:13:87:21 | call to ~(_:) |
| subscript.swift:13:15:13:22 | call to source() : | subscript.swift:13:15:13:25 | ...[...] |
| subscript.swift:14:15:14:23 | call to source2() : | subscript.swift:14:15:14:26 | ...[...] |
| try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... |
@@ -81,6 +92,28 @@ nodes
| simple.swift:66:8:66:15 | call to source() : | semmle.label | call to source() : |
| simple.swift:67:13:67:13 | e | semmle.label | e |
| simple.swift:69:13:69:13 | e | semmle.label | e |
| simple.swift:73:13:73:24 | ... .\|(_:_:) ... | semmle.label | ... .\|(_:_:) ... |
| simple.swift:73:17:73:24 | call to source() : | semmle.label | call to source() : |
| simple.swift:74:13:74:20 | call to source() : | semmle.label | call to source() : |
| simple.swift:74:13:74:24 | ... .\|(_:_:) ... | semmle.label | ... .\|(_:_:) ... |
| simple.swift:76:13:76:29 | ... .&(_:_:) ... | semmle.label | ... .&(_:_:) ... |
| simple.swift:76:22:76:29 | call to source() : | semmle.label | call to source() : |
| simple.swift:77:13:77:20 | call to source() : | semmle.label | call to source() : |
| simple.swift:77:13:77:24 | ... .&(_:_:) ... | semmle.label | ... .&(_:_:) ... |
| simple.swift:79:13:79:29 | ... .^(_:_:) ... | semmle.label | ... .^(_:_:) ... |
| simple.swift:79:22:79:29 | call to source() : | semmle.label | call to source() : |
| simple.swift:80:13:80:20 | call to source() : | semmle.label | call to source() : |
| simple.swift:80:13:80:24 | ... .^(_:_:) ... | semmle.label | ... .^(_:_:) ... |
| simple.swift:82:13:82:20 | call to source() : | semmle.label | call to source() : |
| simple.swift:82:13:82:25 | ... .<<(_:_:) ... | semmle.label | ... .<<(_:_:) ... |
| simple.swift:83:13:83:20 | call to source() : | semmle.label | call to source() : |
| simple.swift:83:13:83:26 | ... .&<<(_:_:) ... | semmle.label | ... .&<<(_:_:) ... |
| simple.swift:84:13:84:20 | call to source() : | semmle.label | call to source() : |
| simple.swift:84:13:84:25 | ... .>>(_:_:) ... | semmle.label | ... .>>(_:_:) ... |
| simple.swift:85:13:85:20 | call to source() : | semmle.label | call to source() : |
| simple.swift:85:13:85:26 | ... .&>>(_:_:) ... | semmle.label | ... .&>>(_:_:) ... |
| simple.swift:87:13:87:21 | call to ~(_:) | semmle.label | call to ~(_:) |
| simple.swift:87:14:87:21 | call to source() : | semmle.label | call to source() : |
| subscript.swift:13:15:13:22 | call to source() : | semmle.label | call to source() : |
| subscript.swift:13:15:13:25 | ...[...] | semmle.label | ...[...] |
| subscript.swift:14:15:14:23 | call to source2() : | semmle.label | call to source2() : |
@@ -120,6 +153,17 @@ subpaths
| simple.swift:63:13:63:13 | d | simple.swift:60:8:60:15 | call to source() : | simple.swift:63:13:63:13 | d | result |
| simple.swift:67:13:67:13 | e | simple.swift:66:8:66:15 | call to source() : | simple.swift:67:13:67:13 | e | result |
| simple.swift:69:13:69:13 | e | simple.swift:66:8:66:15 | call to source() : | simple.swift:69:13:69:13 | e | result |
| simple.swift:73:13:73:24 | ... .\|(_:_:) ... | simple.swift:73:17:73:24 | call to source() : | simple.swift:73:13:73:24 | ... .\|(_:_:) ... | result |
| simple.swift:74:13:74:24 | ... .\|(_:_:) ... | simple.swift:74:13:74:20 | call to source() : | simple.swift:74:13:74:24 | ... .\|(_:_:) ... | result |
| simple.swift:76:13:76:29 | ... .&(_:_:) ... | simple.swift:76:22:76:29 | call to source() : | simple.swift:76:13:76:29 | ... .&(_:_:) ... | result |
| simple.swift:77:13:77:24 | ... .&(_:_:) ... | simple.swift:77:13:77:20 | call to source() : | simple.swift:77:13:77:24 | ... .&(_:_:) ... | result |
| simple.swift:79:13:79:29 | ... .^(_:_:) ... | simple.swift:79:22:79:29 | call to source() : | simple.swift:79:13:79:29 | ... .^(_:_:) ... | result |
| simple.swift:80:13:80:24 | ... .^(_:_:) ... | simple.swift:80:13:80:20 | call to source() : | simple.swift:80:13:80:24 | ... .^(_:_:) ... | result |
| simple.swift:82:13:82:25 | ... .<<(_:_:) ... | simple.swift:82:13:82:20 | call to source() : | simple.swift:82:13:82:25 | ... .<<(_:_:) ... | result |
| simple.swift:83:13:83:26 | ... .&<<(_:_:) ... | simple.swift:83:13:83:20 | call to source() : | simple.swift:83:13:83:26 | ... .&<<(_:_:) ... | result |
| simple.swift:84:13:84:25 | ... .>>(_:_:) ... | simple.swift:84:13:84:20 | call to source() : | simple.swift:84:13:84:25 | ... .>>(_:_:) ... | result |
| simple.swift:85:13:85:26 | ... .&>>(_:_:) ... | simple.swift:85:13:85:20 | call to source() : | simple.swift:85:13:85:26 | ... .&>>(_:_:) ... | result |
| simple.swift:87:13:87:21 | call to ~(_:) | simple.swift:87:14:87:21 | call to source() : | simple.swift:87:13:87:21 | call to ~(_:) | result |
| subscript.swift:13:15:13:25 | ...[...] | subscript.swift:13:15:13:22 | call to source() : | subscript.swift:13:15:13:25 | ...[...] | result |
| subscript.swift:14:15:14:26 | ...[...] | subscript.swift:14:15:14:23 | call to source2() : | subscript.swift:14:15:14:26 | ...[...] | result |
| try.swift:9:13:9:24 | try ... | try.swift:9:17:9:24 | call to source() : | try.swift:9:13:9:24 | try ... | result |

View File

@@ -70,19 +70,19 @@ func taintThroughAssignmentArithmetic() {
}
func taintThroughBitwiseOperators() {
sink(arg: 0 | source()) // $ MISSING: tainted=73
sink(arg: source() | 0) // $ MISSING: tainted=74
sink(arg: 0 | source()) // $ tainted=73
sink(arg: source() | 0) // $ tainted=74
sink(arg: 0xffff & source()) // $ MISSING: tainted=76
sink(arg: source() & 0xffff) // $ MISSING: tainted=77
sink(arg: 0xffff & source()) // $ tainted=76
sink(arg: source() & 0xffff) // $ tainted=77
sink(arg: 0xffff ^ source()) // $ MISSING: tainted=79
sink(arg: source() ^ 0xffff) // $ MISSING: tainted=80
sink(arg: 0xffff ^ source()) // $ tainted=79
sink(arg: source() ^ 0xffff) // $ tainted=80
sink(arg: source() << 1) // $ MISSING: tainted=82
sink(arg: source() &<< 1) // $ MISSING: tainted=83
sink(arg: source() >> 1) // $ MISSING: tainted=84
sink(arg: source() &>> 1) // $ MISSING: tainted=85
sink(arg: source() << 1) // $ tainted=82
sink(arg: source() &<< 1) // $ tainted=83
sink(arg: source() >> 1) // $ tainted=84
sink(arg: source() &>> 1) // $ tainted=85
sink(arg: ~source()) // $ MISSING: tainted=87
sink(arg: ~source()) // $ tainted=87
}

View File

@@ -6,3 +6,6 @@
| bitwiseoperation.swift:7:7:7:12 | ... .>>(_:_:) ... | BinaryBitwiseOperation, ShiftRightBitwiseExpr |
| bitwiseoperation.swift:10:7:10:13 | ... .&<<(_:_:) ... | BinaryBitwiseOperation, ShiftLeftBitwiseExpr |
| bitwiseoperation.swift:11:7:11:13 | ... .&>>(_:_:) ... | BinaryBitwiseOperation, ShiftRightBitwiseExpr |
| bitwiseoperation.swift:17:7:17:12 | ... ..&(_:_:) ... | BinaryBitwiseOperation, PointwiseAndExpr |
| bitwiseoperation.swift:18:7:18:12 | ... ..\|(_:_:) ... | BinaryBitwiseOperation, PointwiseOrExpr |
| bitwiseoperation.swift:19:7:19:12 | ... ..^(_:_:) ... | BinaryBitwiseOperation, PointwiseXorExpr |

View File

@@ -9,6 +9,12 @@ string describe(BitwiseOperation e) {
or
e instanceof XorBitwiseExpr and result = "XorBitwiseExpr"
or
e instanceof PointwiseAndExpr and result = "PointwiseAndExpr"
or
e instanceof PointwiseOrExpr and result = "PointwiseOrExpr"
or
e instanceof PointwiseXorExpr and result = "PointwiseXorExpr"
or
e instanceof ShiftLeftBitwiseExpr and result = "ShiftLeftBitwiseExpr"
or
e instanceof ShiftRightBitwiseExpr and result = "ShiftRightBitwiseExpr"

View File

@@ -14,7 +14,7 @@ func bitwise() {
let a = SIMD4<Int>(1, 2, 3, 4)
let b = SIMD4<Int>(4, 3, 2, 1)
let m = a .< b
_ = m .& m // NOT DETECTED
_ = m .| m // NOT DETECTED
_ = m .^ m // NOT DETECTED
_ = m .& m
_ = m .| m
_ = m .^ m
}