11import cpp
2-
3- private predicate allocationFunctionWithSize ( Function f , int sizeArg ) {
4- exists ( string name |
5- f .hasGlobalOrStdName ( name ) and
6- (
7- ( name = "malloc" and sizeArg = 0 ) // malloc(size)
8- )
9- or
10- f .hasGlobalName ( name ) and
11- (
12- ( name = "ExAllocatePool" and sizeArg = 1 ) or // ExAllocatePool(type, size)
13- ( name = "ExAllocatePoolWithTag" and sizeArg = 1 ) or // ExAllocatePool(type, size, tag)
14- ( name = "ExAllocatePoolWithTagPriority" and sizeArg = 1 ) or // ExAllocatePoolWithTagPriority(type, size, tag, priority)
15- ( name = "ExAllocatePoolWithQuota" and sizeArg = 1 ) or // ExAllocatePoolWithQuota(type, size)
16- ( name = "ExAllocatePoolWithQuotaTag" and sizeArg = 1 ) or // ExAllocatePoolWithQuotaTag(type, size, tag)
17- ( name = "IoAllocateMdl" and sizeArg = 1 ) or // IoAllocateMdl(address, size, flag, flag, irp)
18- ( name = "IoAllocateErrorLogEntry" and sizeArg = 1 ) or // IoAllocateErrorLogEntry(object, size)
19- ( name = "MmAllocateContiguousMemory" and sizeArg = 0 ) or // MmAllocateContiguousMemory(size, maxaddress)
20- ( name = "MmAllocateContiguousNodeMemory" and sizeArg = 0 ) or // MmAllocateContiguousNodeMemory(size, minaddress, maxaddress, bound, flag, prefer)
21- ( name = "MmAllocateContiguousMemorySpecifyCache" and sizeArg = 0 ) or // MmAllocateContiguousMemorySpecifyCache(size, minaddress, maxaddress, bound, type)
22- ( name = "MmAllocateContiguousMemorySpecifyCacheNode" and sizeArg = 0 ) or // MmAllocateContiguousMemorySpecifyCacheNode(size, minaddress, maxaddress, bound, type, prefer)
23- ( name = "MmAllocateNonCachedMemory" and sizeArg = 0 ) or // MmAllocateNonCachedMemory(size)
24- ( name = "MmAllocateMappingAddress" and sizeArg = 0 ) or // MmAllocateMappingAddress(size, tag)
25- ( name = "MmAllocatePagesForMdl" and sizeArg = 3 ) or // MmAllocatePagesForMdl(minaddress, maxaddress, skip, size)
26- ( name = "MmAllocatePagesForMdlEx" and sizeArg = 3 ) or // MmAllocatePagesForMdlEx(minaddress, maxaddress, skip, size, type, flags)
27- ( name = "MmAllocateNodePagesForMdlEx" and sizeArg = 3 ) or // MmAllocateNodePagesForMdlEx(minaddress, maxaddress, skip, size, type, prefer, flags)
28- ( name = "LocalAlloc" and sizeArg = 1 ) or // LocalAlloc(flags, size)
29- ( name = "GlobalAlloc" and sizeArg = 1 ) or // GlobalAlloc(flags, size)
30- ( name = "HeapAlloc" and sizeArg = 2 ) or // HeapAlloc(heap, flags, size)
31- ( name = "VirtualAlloc" and sizeArg = 1 ) or // VirtualAlloc(address, size, type, flag)
32- ( name = "CoTaskMemAlloc" and sizeArg = 0 ) // CoTaskMemAlloc(size)
33- )
34- )
35- }
36-
37- private predicate allocationFunctionWithSizeAndMult ( Function f , int sizeArg , int multArg ) {
38- exists ( string name |
39- f .hasGlobalOrStdName ( name ) and
40- ( name = "calloc" and sizeArg = 1 and multArg = 0 ) // calloc(num, size)
41- )
42- }
43-
44- private predicate allocationFunctionWithSizeRealloc ( Function f , int sizeArg , int reallocArg ) {
45- exists ( string name |
46- f .hasGlobalOrStdName ( name ) and
47- (
48- ( name = "realloc" and sizeArg = 1 and reallocArg = 0 ) // realloc(ptr, size)
49- )
50- or
51- f .hasGlobalName ( name ) and
52- (
53- ( name = "LocalReAlloc" and sizeArg = 1 and reallocArg = 0 ) or // LocalReAlloc(ptr, size, flags)
54- ( name = "GlobalReAlloc" and sizeArg = 1 and reallocArg = 0 ) or // GlobalReAlloc(ptr, size, flags)
55- ( name = "HeapReAlloc" and sizeArg = 3 and reallocArg = 2 ) or // HeapReAlloc(heap, flags, ptr, size)
56- ( name = "CoTaskMemRealloc" and sizeArg = 1 and reallocArg = 0 ) // CoTaskMemRealloc(ptr, size)
57- )
58- )
59- }
60-
61- private predicate allocationFunctionNoSize ( Function f ) {
62- exists ( string name |
63- f .hasGlobalOrStdName ( name ) and
64- (
65- name = "strdup" or // strdup(str)
66- name = "wcsdup" // wcsdup(str)
67- )
68- or
69- f .hasGlobalName ( name ) and
70- (
71- name = "_strdup" or // _strdup(str)
72- name = "_wcsdup" or // _wcsdup(str)
73- name = "_mbsdup" or // _mbsdup(str)
74- name = "ExAllocateFromLookasideListEx" or // ExAllocateFromLookasideListEx(list)
75- name = "ExAllocateFromPagedLookasideList" or // ExAllocateFromPagedLookasideList(list)
76- name = "ExAllocateFromNPagedLookasideList" or // ExAllocateFromNPagedLookasideList(list)
77- name = "ExAllocateTimer" or // ExAllocateTimer(callback, context, attributes)
78- name = "IoAllocateWorkItem" or // IoAllocateWorkItem(object)
79- name = "MmMapLockedPagesWithReservedMapping" or // MmMapLockedPagesWithReservedMapping(address, tag, list, type)
80- name = "MmMapLockedPages" or // MmMapLockedPages(list, mode)
81- name = "MmMapLockedPagesSpecifyCache" // MmMapLockedPagesSpecifyCache(list, mode, type, address, flag, flag)
82- )
83- )
84- }
85-
86- /**
87- * An allocation function such as `malloc`.
88- */
89- class MallocFunction extends Function {
90- MallocFunction ( ) {
91- allocationFunctionWithSize ( this , _) or
92- allocationFunctionWithSizeAndMult ( this , _, _) or
93- allocationFunctionWithSizeRealloc ( this , _, _) or
94- allocationFunctionNoSize ( this )
95- }
96-
97- /**
98- * Gets the index of the argument for the allocation size, if any. The actual
99- * allocation size is the value of this argument multiplied by the result of
100- * `getSizeMult()`, in bytes.
101- */
102- int getSizeArg ( ) {
103- allocationFunctionWithSize ( this , result ) or
104- allocationFunctionWithSizeAndMult ( this , result , _) or
105- allocationFunctionWithSizeRealloc ( this , result , _)
106- }
107-
108- /**
109- * Gets the index of an argument that multiplies the allocation size given by
110- * `getSizeArg`, if any.
111- */
112- int getSizeMult ( ) {
113- allocationFunctionWithSizeAndMult ( this , _, result )
114- }
115-
116- /**
117- * Gets the index of the input pointer argument to be reallocated, if this
118- * is a `realloc` function.
119- */
120- int getReallocPtrArg ( ) {
121- allocationFunctionWithSizeRealloc ( this , _, result )
122- }
123- }
124-
125- /**
126- * An allocation expression such as call to `malloc` or a `new` expression.
127- */
128- class AllocationExpr extends Expr {
129- AllocationExpr ( ) {
130- exists ( MallocFunction malloc |
131- // alloc call
132- this .( FunctionCall ) .getTarget ( ) = malloc and
133- // realloc(ptr, 0) only frees the pointer
134- not (
135- exists ( malloc .getReallocPtrArg ( ) ) and
136- this .( FunctionCall ) .getArgument ( malloc .getSizeArg ( ) ) .getValue ( ) .toInt ( ) = 0
137- )
138- ) or
139- this instanceof NewExpr or
140- this instanceof NewArrayExpr
141- }
142-
143- /**
144- * Gets an expression for the allocation size, if any. The actual allocation
145- * size is the value of this expression multiplied by the result of
146- * `getSizeMult()`, in bytes.
147- */
148- Expr getSizeExpr ( ) {
149- exists ( FunctionCall fc | fc = this |
150- result = fc .getArgument ( fc .getTarget ( ) .( MallocFunction ) .getSizeArg ( ) )
151- ) or
152- // new array expr with variable size
153- result = this .( NewArrayExpr ) .getExtent ( )
154- }
155-
156- /**
157- * Gets a constant multiplier for the allocation size given by `getSizeExpr`,
158- * in bytes.
159- */
160- int getSizeMult ( ) {
161- exists ( FunctionCall fc | fc = this |
162- // malloc with multiplier argument that is a constant
163- result = fc .getArgument ( fc .getTarget ( ) .( MallocFunction ) .getSizeMult ( ) ) .getValue ( ) .toInt ( )
164- or
165- // malloc with no multiplier argument
166- (
167- not exists ( fc .getTarget ( ) .( MallocFunction ) .getSizeMult ( ) ) and
168- result = 1
169- )
170- ) or
171- (
172- // new array expr with variable size
173- exists ( this .( NewArrayExpr ) .getExtent ( ) ) and
174- result = this .( NewArrayExpr ) .getAllocatedElementType ( ) .getSize ( )
175- )
176- }
177-
178- /**
179- * Gets the size of this allocation in bytes, if it is a fixed size and that
180- * size can be determined.
181- */
182- int getSizeBytes ( ) {
183- result = getSizeExpr ( ) .getValue ( ) .toInt ( ) * getSizeMult ( )
184- or
185- result = this .( NewExpr ) .getAllocatedType ( ) .getSize ( )
186- or
187- result = this .( NewArrayExpr ) .getAllocatedType ( ) .getSize ( )
188- }
189-
190- /**
191- * Gets the expression for the input pointer argument to be reallocated, if
192- * this is a `realloc` function.
193- */
194- Expr getReallocPtr ( ) {
195- exists ( FunctionCall fc | fc = this |
196- result = fc .getArgument ( fc .getTarget ( ) .( MallocFunction ) .getReallocPtrArg ( ) )
197- )
198- }
199- }
2+ import semmle.code.cpp.models.interfaces.Allocation
2003
2014/**
2025 * A library routine that allocates memory.
@@ -220,105 +23,7 @@ deprecated predicate allocationCall(FunctionCall fc) {
22023 * A library routine that frees memory.
22124 */
22225predicate freeFunction ( Function f , int argNum ) {
223- exists ( string name |
224- f .hasGlobalName ( name ) and
225- (
226- name = "free" and argNum = 0
227- or
228- name = "realloc" and argNum = 0
229- )
230- or
231- f .hasGlobalOrStdName ( name ) and
232- (
233- name = "ExFreePoolWithTag" and argNum = 0
234- or
235- name = "ExFreeToLookasideListEx" and argNum = 1
236- or
237- name = "ExFreeToPagedLookasideList" and argNum = 1
238- or
239- name = "ExFreeToNPagedLookasideList" and argNum = 1
240- or
241- name = "ExDeleteTimer" and argNum = 0
242- or
243- name = "IoFreeMdl" and argNum = 0
244- or
245- name = "IoFreeWorkItem" and argNum = 0
246- or
247- name = "IoFreeErrorLogEntry" and argNum = 0
248- or
249- name = "MmFreeContiguousMemory" and argNum = 0
250- or
251- name = "MmFreeContiguousMemorySpecifyCache" and argNum = 0
252- or
253- name = "MmFreeNonCachedMemory" and argNum = 0
254- or
255- name = "MmFreeMappingAddress" and argNum = 0
256- or
257- name = "MmFreePagesFromMdl" and argNum = 0
258- or
259- name = "MmUnmapReservedMapping" and argNum = 0
260- or
261- name = "MmUnmapLockedPages" and argNum = 0
262- or
263- name = "LocalFree" and argNum = 0
264- or
265- name = "GlobalFree" and argNum = 0
266- or
267- name = "HeapFree" and argNum = 2
268- or
269- name = "VirtualFree" and argNum = 0
270- or
271- name = "CoTaskMemFree" and argNum = 0
272- or
273- name = "SysFreeString" and argNum = 0
274- or
275- name = "LocalReAlloc" and argNum = 0
276- or
277- name = "GlobalReAlloc" and argNum = 0
278- or
279- name = "HeapReAlloc" and argNum = 2
280- or
281- name = "CoTaskMemRealloc" and argNum = 0
282- )
283- )
284- }
285-
286- /**
287- * A deallocation function such as `free`.
288- */
289- class FreeFunction extends Function {
290- FreeFunction ( ) {
291- freeFunction ( this , _)
292- }
293-
294- /**
295- * Gets the index of the argument that is freed by this function.
296- */
297- int getFreedArg ( ) {
298- freeFunction ( this , result )
299- }
300- }
301-
302- /**
303- * An deallocation expression such as call to `free` or a `delete` expression.
304- */
305- class DeallocationExpr extends Expr {
306- DeallocationExpr ( ) {
307- this .( FunctionCall ) .getTarget ( ) instanceof FreeFunction or
308- this instanceof DeleteExpr or
309- this instanceof DeleteArrayExpr
310- }
311-
312- /**
313- * Gets the expression that is freed by this function.
314- */
315- Expr getFreedExpr ( ) {
316- exists ( FunctionCall fc | fc = this |
317- result = fc .getArgument ( fc .getTarget ( ) .( FreeFunction ) .getFreedArg ( ) )
318- ) or
319- result = this .( DeleteExpr ) .getExpr ( ) or
320- result = this .( DeleteArrayExpr ) .getExpr ( )
321- }
26+ argNum = f .( FreeFunction ) .getFreedArg ( )
32227}
32328
32429/**
0 commit comments