|
| 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