Skip to content

Commit 3a28d26

Browse files
committed
Add sun-misc-Unsafe-bad-array-offset.ql
1 parent a574ff4 commit 3a28d26

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Finds usage of `sun.misc.Unsafe` methods with arrays as argument where the
3+
* 'offset' argument is not based on `Unsafe.ARRAY_..._BASE_OFFSET`. This most likely
4+
* means that the code is by accident either reading or overwriting the header value
5+
* at the start of the array object, which could corrupt it.
6+
*
7+
* @kind problem
8+
* @id todo
9+
*/
10+
11+
import java
12+
13+
from MethodAccess unsafeCall, Method unsafeMethod, int arrayArgIndex, Expr badOffsetArg
14+
where
15+
unsafeCall.getMethod() = unsafeMethod and
16+
unsafeMethod.getDeclaringType().hasQualifiedName("sun.misc", "Unsafe") and
17+
unsafeCall.getArgument(arrayArgIndex).getType() instanceof Array and
18+
// For all existing `Unsafe` reading and writing methods there is first the `Object` parameter
19+
// and then directly afterwards the `long` 'offset' parameter
20+
unsafeMethod.getParameterType(arrayArgIndex + 1).hasName("long") and
21+
badOffsetArg = unsafeCall.getArgument(arrayArgIndex + 1) and
22+
(
23+
// If it is a constant, then it is not based on `Unsafe.ARRAY_..._BASE_OFFSET` because those
24+
// values are currently not compile time constants in the `Unsafe` implementation
25+
badOffsetArg instanceof CompileTimeConstantExpr
26+
or
27+
// Or variable where all assigned values are constant (and therefore not based on `Unsafe.ARRAY_..._BASE_OFFSET`)
28+
// Require that `v.getInitializer()` exists to ignore variables with implicit assigned value, e.g. method parameters
29+
// (TODO: This is not completely correct because this excludes local variables which are initalized by a separate assignment)
30+
exists(Variable v | v = badOffsetArg.(RValue).getVariable() and exists(v.getInitializer()) |
31+
forex(Expr e | e = v.getAnAssignedValue() | e instanceof CompileTimeConstantExpr)
32+
)
33+
)
34+
select badOffsetArg, "'offset' argument is missing base offset for array"

0 commit comments

Comments
 (0)