mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Make ImplicitFieldReadInstruction include implicit deref when needed
When an ImplicitFieldReadInstruction reads an embedded field which has a pointer type, it now includes the implicit dereference. It might be better to extend MkImplicitDeref to cover this case, so we have an explicit instruction for this. Then it would be easier to see when dereferences are happening, and hence when they might cause a nil pointer dereference.
This commit is contained in:
@@ -302,8 +302,11 @@ newtype TControlFlowNode =
|
||||
)
|
||||
} or
|
||||
/**
|
||||
* A control-flow node that represents the implicit selection of a field when accessing a
|
||||
* promoted field.
|
||||
* A control-flow node that represents the implicit selection of a field when
|
||||
* accessing a promoted field.
|
||||
*
|
||||
* If that field has a pointer type then this control-flow node also
|
||||
* represents an implicit dereference of it.
|
||||
*/
|
||||
MkImplicitFieldSelection(SelectorExpr e, int i, Field implicitField) {
|
||||
exists(Type baseType, StructType baseStructType, Field eField, int minDepth |
|
||||
@@ -313,8 +316,12 @@ newtype TControlFlowNode =
|
||||
baseStructType.getFieldAtDepth(_, minDepth) = eField
|
||||
|
|
||||
baseStructType.getFieldAtDepth(_, i) = implicitField and
|
||||
implicitField.getType().getUnderlyingType().(StructType).getFieldAtDepth(_, minDepth - i - 1) =
|
||||
eField
|
||||
exists(Type implicitFieldType, StructType implicitFieldStructType |
|
||||
implicitFieldType = implicitField.getType().getUnderlyingType() and
|
||||
implicitFieldStructType =
|
||||
[implicitFieldType, implicitFieldType.(PointerType).getBaseType().getUnderlyingType()] and
|
||||
implicitFieldStructType.getFieldAtDepth(_, minDepth - i - 1) = eField
|
||||
)
|
||||
)
|
||||
} or
|
||||
/**
|
||||
|
||||
@@ -277,9 +277,15 @@ module IR {
|
||||
not exists(MkImplicitDeref(se.getBase())) and
|
||||
result = evalExprInstruction(se.getBase())
|
||||
else
|
||||
exists(ImplicitFieldReadInstruction ifri |
|
||||
exists(
|
||||
ImplicitFieldReadInstruction ifri, Type implicitFieldType,
|
||||
StructType implicitFieldStructType
|
||||
|
|
||||
ifri.getSelectorExpr() = se and
|
||||
ifri.getField().getType().getUnderlyingType().(StructType).getOwnField(_, _) = field
|
||||
implicitFieldType = ifri.getField().getType().getUnderlyingType() and
|
||||
implicitFieldStructType =
|
||||
[implicitFieldType, implicitFieldType.(PointerType).getBaseType().getUnderlyingType()] and
|
||||
implicitFieldStructType.getOwnField(_, _) = field
|
||||
|
|
||||
result = ifri
|
||||
)
|
||||
@@ -339,7 +345,11 @@ module IR {
|
||||
}
|
||||
|
||||
/**
|
||||
* An IR instruction for an implicit field read as part of reading a promoted field.
|
||||
* An IR instruction for an implicit field read as part of reading a
|
||||
* promoted field.
|
||||
*
|
||||
* If that field has a pointer type then this instruction also represents an
|
||||
* implicit dereference of it.
|
||||
*/
|
||||
class ImplicitFieldReadInstruction extends Instruction, MkImplicitFieldSelection {
|
||||
SelectorExpr e;
|
||||
@@ -353,7 +363,11 @@ module IR {
|
||||
|
||||
override predicate reads(ValueEntity v) { v = implicitField }
|
||||
|
||||
override Type getResultType() { result = implicitField.getType() }
|
||||
override Type getResultType() {
|
||||
if implicitField.getType() instanceof PointerType
|
||||
then result = implicitField.getType().(PointerType).getBaseType()
|
||||
else result = implicitField.getType()
|
||||
}
|
||||
|
||||
override ControlFlow::Root getRoot() { result.isRootOf(e) }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user