mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
AllocationExpr.getSizeMult() now analyzes the size expression of function calls.
This yields more precise size information in a lot of the common cases of C allocation code, as the common pattern malloc(count * sizeof(type)) is now understood.
This commit is contained in:
@@ -255,6 +255,24 @@ class OperatorNewAllocationFunction extends AllocationFunction {
|
||||
}
|
||||
}
|
||||
|
||||
pragma[inline]
|
||||
private predicate deconstructSizeExpr(Expr sizeExpr, Expr lengthExpr, int sizeof) {
|
||||
sizeExpr instanceof MulExpr and
|
||||
exists(SizeofOperator sizeofOp |
|
||||
sizeofOp = sizeExpr.(MulExpr).getAnOperand() and
|
||||
lengthExpr = sizeExpr.(MulExpr).getAnOperand() and
|
||||
sizeofOp != lengthExpr and
|
||||
sizeof = sizeofOp.getValue().toInt()
|
||||
)
|
||||
or
|
||||
not exists(int s, SizeofOperator sizeofOp |
|
||||
sizeofOp = sizeExpr.(MulExpr).getAnOperand() and
|
||||
s = sizeofOp.(SizeofOperator).getValue().toInt()
|
||||
) and
|
||||
lengthExpr = sizeExpr and
|
||||
sizeof = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* An allocation expression that is a function call, such as call to `malloc`.
|
||||
*/
|
||||
@@ -272,7 +290,21 @@ class CallAllocationExpr extends AllocationExpr, FunctionCall {
|
||||
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
|
||||
}
|
||||
|
||||
override Expr getSizeExpr() { result = getArgument(target.getSizeArg()) }
|
||||
override Expr getSizeExpr() {
|
||||
exists(Expr sizeExpr | sizeExpr = getArgument(target.getSizeArg()) |
|
||||
if exists(target.getSizeMult())
|
||||
then result = sizeExpr
|
||||
else (
|
||||
exists(Expr lengthExpr |
|
||||
deconstructSizeExpr(sizeExpr, lengthExpr, _) and
|
||||
result = lengthExpr
|
||||
)
|
||||
or
|
||||
not exists(Expr lengthExpr | deconstructSizeExpr(sizeExpr, lengthExpr, _)) and
|
||||
result = sizeExpr
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override int getSizeMult() {
|
||||
// malloc with multiplier argument that is a constant
|
||||
@@ -280,7 +312,7 @@ class CallAllocationExpr extends AllocationExpr, FunctionCall {
|
||||
or
|
||||
// malloc with no multiplier argument
|
||||
not exists(target.getSizeMult()) and
|
||||
result = 1
|
||||
deconstructSizeExpr(getArgument(target.getSizeArg()), _, result)
|
||||
}
|
||||
|
||||
override int getSizeBytes() { result = getSizeExpr().getValue().toInt() * getSizeMult() }
|
||||
|
||||
@@ -86,11 +86,11 @@ allocationExprs
|
||||
| allocators.cpp:144:13:144:31 | new[] | getSizeExpr = x, getSizeMult = 900, requiresDealloc |
|
||||
| allocators.cpp:149:8:149:19 | call to operator new | getSizeBytes = 4, getSizeExpr = sizeof(int), getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:156:3:156:8 | call to malloc | getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:157:3:157:8 | call to malloc | getSizeBytes = 20, getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:157:3:157:8 | call to malloc | getSizeBytes = 20, getSizeExpr = 5, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:158:3:158:8 | call to malloc | getSizeExpr = count, getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:159:3:159:8 | call to malloc | getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:159:3:159:8 | call to malloc | getSizeExpr = count, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:160:3:160:8 | call to malloc | getSizeExpr = ... + ..., getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:161:3:161:8 | call to malloc | getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:161:3:161:8 | call to malloc | getSizeExpr = count, getSizeMult = 8, requiresDealloc |
|
||||
deallocationFunctions
|
||||
| allocators.cpp:11:6:11:20 | operator delete | getFreedArg = 0 |
|
||||
| allocators.cpp:12:6:12:22 | operator delete[] | getFreedArg = 0 |
|
||||
|
||||
Reference in New Issue
Block a user