Skip to content

Commit 07495b3

Browse files
author
Nikita Kraiouchkine
authored
Merge pull request #176 from kraiouchkine/InvalidMemory1
Implement InvalidMemory1 package
2 parents b18a89e + a92f73a commit 07495b3

33 files changed

+1440
-31
lines changed

.vscode/tasks.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@
223223
"Includes",
224224
"Initialization",
225225
"IntegerConversion",
226+
"InvalidMemory1",
227+
"InvalidMemory2",
226228
"Invariants",
227229
"Iterators",
228230
"Lambdas",
@@ -231,6 +233,8 @@
231233
"Literals",
232234
"Loops",
233235
"Macros",
236+
"Memory1",
237+
"Memory2",
234238
"Misc",
235239
"MoveForward",
236240
"Naming",

c/cert/src/rules/EXP33-C/DoNotReadUninitializedMemory.md

Lines changed: 417 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @id c/cert/do-not-read-uninitialized-memory
3+
* @name EXP33-C: Do not read uninitialized memory
4+
* @description Using the value of an object with automatic storage duration while it is
5+
* indeterminate is undefined behavior.
6+
* @kind problem
7+
* @precision medium
8+
* @problem.severity error
9+
* @tags external/cert/id/exp33-c
10+
* correctness
11+
* security
12+
* external/cert/obligation/rule
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.cert
17+
import codingstandards.cpp.rules.readofuninitializedmemory.ReadOfUninitializedMemory
18+
19+
class DoNotReadUninitializedMemoryQuery extends ReadOfUninitializedMemorySharedQuery {
20+
DoNotReadUninitializedMemoryQuery() {
21+
this = InvalidMemory1Package::doNotReadUninitializedMemoryQuery()
22+
}
23+
}

c/cert/src/rules/EXP34-C/DoNotDereferenceNullPointers.md

Lines changed: 219 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @id c/cert/do-not-dereference-null-pointers
3+
* @name EXP34-C: Do not dereference null pointers
4+
* @description Dereferencing a null pointer leads to undefined behavior.
5+
* @kind problem
6+
* @precision medium
7+
* @problem.severity error
8+
* @tags external/cert/id/exp34-c
9+
* correctness
10+
* external/cert/obligation/rule
11+
*/
12+
13+
import cpp
14+
import codingstandards.c.cert
15+
import codingstandards.cpp.rules.dereferenceofnullpointer.DereferenceOfNullPointer
16+
17+
class DoNotDereferenceNullPointersQuery extends DereferenceOfNullPointerSharedQuery {
18+
DoNotDereferenceNullPointersQuery() {
19+
this = InvalidMemory1Package::doNotDereferenceNullPointersQuery()
20+
}
21+
}

c/cert/src/rules/MEM30-C/DoNotAccessFreedMemory.md

Lines changed: 258 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* @id c/cert/do-not-access-freed-memory
3+
* @name MEM30-C: Do not access freed memory
4+
* @description Accessing memory that has been deallocated is undefined behavior.
5+
* @kind problem
6+
* @precision high
7+
* @problem.severity error
8+
* @tags external/cert/id/mem30-c
9+
* correctness
10+
* security
11+
* external/cert/obligation/rule
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.cert
16+
import codingstandards.cpp.Allocations
17+
import semmle.code.cpp.controlflow.StackVariableReachability
18+
19+
/** `e` is an expression that frees the memory pointed to by `v`. */
20+
predicate isFreeExpr(Expr e, StackVariable v) {
21+
exists(VariableAccess va | va.getTarget() = v and freeExprOrIndirect(e, va, _))
22+
}
23+
24+
/** `e` is an expression that accesses `v` but is not the lvalue of an assignment. */
25+
predicate isAccessExpr(Expr e, StackVariable v) {
26+
v.getAnAccess() = e and
27+
not exists(Assignment a | a.getLValue() = e)
28+
or
29+
isDerefByCallExpr(_, _, e, v)
30+
}
31+
32+
/**
33+
* `va` is passed by value as (part of) the `i`th argument in
34+
* call `c`. The target function is either a library function
35+
* or a source code function that dereferences the relevant
36+
* parameter.
37+
*/
38+
predicate isDerefByCallExpr(Call c, int i, VariableAccess va, StackVariable v) {
39+
v.getAnAccess() = va and
40+
va = c.getAnArgumentSubExpr(i) and
41+
not c.passesByReference(i, va) and
42+
(c.getTarget().hasEntryPoint() implies isAccessExpr(_, c.getTarget().getParameter(i)))
43+
}
44+
45+
class UseAfterFreeReachability extends StackVariableReachability {
46+
UseAfterFreeReachability() { this = "UseAfterFree" }
47+
48+
override predicate isSource(ControlFlowNode node, StackVariable v) { isFreeExpr(node, v) }
49+
50+
override predicate isSink(ControlFlowNode node, StackVariable v) { isAccessExpr(node, v) }
51+
52+
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
53+
definitionBarrier(v, node) or
54+
isFreeExpr(node, v)
55+
}
56+
}
57+
58+
// This query is a modified version of the `UseAfterFree.ql`
59+
// (cpp/use-after-free) query from the CodeQL standard library.
60+
from UseAfterFreeReachability r, StackVariable v, Expr free, Expr e
61+
where
62+
not isExcluded(e, InvalidMemory1Package::doNotAccessFreedMemoryQuery()) and
63+
r.reaches(free, v, e)
64+
select e,
65+
"Pointer '" + v.getName().toString() + "' accessed but may have been previously freed $@.", free,
66+
"here"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/readofuninitializedmemory/ReadOfUninitializedMemory.ql
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/dereferenceofnullpointer/DereferenceOfNullPointer.ql
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
| test.c:11:47:11:47 | p | Pointer 'p' accessed but may have been previously freed $@. | test.c:12:5:12:8 | call to free | here |
2+
| test.c:25:10:25:12 | buf | Pointer 'buf' accessed but may have been previously freed $@. | test.c:24:3:24:6 | call to free | here |
3+
| test.c:32:15:32:17 | buf | Pointer 'buf' accessed but may have been previously freed $@. | test.c:31:3:31:6 | call to free | here |
4+
| test.c:33:9:33:11 | buf | Pointer 'buf' accessed but may have been previously freed $@. | test.c:31:3:31:6 | call to free | here |
5+
| test.c:34:16:34:18 | buf | Pointer 'buf' accessed but may have been previously freed $@. | test.c:31:3:31:6 | call to free | here |

0 commit comments

Comments
 (0)