mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
C++: Add ReadSideEffect as a possible end instruction for load chains
This commit is contained in:
@@ -611,19 +611,7 @@ private newtype TLoadChain =
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This class abstracts out the information needed to end a `LoadChain`. For now the only
|
||||
* implementation is `LoadChainEndInstructionLoad`, but we may need another implementation similar
|
||||
* to `StoreChainEndInstructionSideEffect` to handle cases like:
|
||||
* ```
|
||||
* void read_f(Inner* inner) {
|
||||
* sink(inner->f);
|
||||
* }
|
||||
* ...
|
||||
* outer.inner.f = taint();
|
||||
* read_f(&outer.inner);
|
||||
* ```
|
||||
*/
|
||||
/** This class abstracts out the information needed to end a `LoadChain`. */
|
||||
abstract private class LoadChainEndInstruction extends Instruction {
|
||||
abstract FieldAddressInstruction getFieldInstruction();
|
||||
|
||||
@@ -643,6 +631,32 @@ private class LoadChainEndInstructionLoad extends LoadChainEndInstruction, LoadI
|
||||
override Instruction getReadValue() { result = getSourceValueOperand().getAnyDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a `LoadChain` with a `ReadSideEffectInstruction`. This ensures that we pop content from the
|
||||
* access path when passing an argument that reads a field. For example in:
|
||||
* ```
|
||||
* void read_f(Inner* inner) {
|
||||
* sink(inner->f);
|
||||
* }
|
||||
* ...
|
||||
* outer.inner.f = taint();
|
||||
* read_f(&outer.inner);
|
||||
* ```
|
||||
* In order to register `inner->f` as a `readStep`, the head of the access path must
|
||||
* be `f`, and thus reading `&outer.inner` must pop `inner` from the access path
|
||||
* before entering `read_f`.
|
||||
*/
|
||||
private class LoadChainInstructionSideEffect extends LoadChainEndInstruction,
|
||||
ReadSideEffectInstruction {
|
||||
FieldAddressInstruction fi;
|
||||
|
||||
LoadChainInstructionSideEffect() { fi = skipConversion*(this.getArgumentDef()) }
|
||||
|
||||
override FieldAddressInstruction getFieldInstruction() { result = fi }
|
||||
|
||||
override Instruction getReadValue() { result = getSideEffectOperand().getAnyDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `LoadChain` represents a series of field lookups that compute the source address of a load.
|
||||
* For example, given the field lookup in `f(a.b.c)`, there are two `LoadChains`s:
|
||||
|
||||
@@ -158,7 +158,7 @@ struct Outer
|
||||
|
||||
void read_f(Inner *inner)
|
||||
{
|
||||
sink(inner->f); //$ast $f-:ir
|
||||
sink(inner->f); //$ast,ir
|
||||
}
|
||||
|
||||
void test()
|
||||
|
||||
Reference in New Issue
Block a user