Skip to content

Commit 58c7043

Browse files
committed
Declarations8: add rule DCL30-C
1 parent b18a89e commit 58c7043

File tree

10 files changed

+172
-1
lines changed

10 files changed

+172
-1
lines changed

.vscode/tasks.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@
211211
"Declarations5",
212212
"Declarations6",
213213
"Declarations7",
214+
"Declarations8",
214215
"Exceptions1",
215216
"Exceptions2",
216217
"Expressions",
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# DCL30-C: Declare objects with appropriate storage durations
2+
3+
This query implements the CERT-C rule DCL30-C:
4+
5+
> Declare objects with appropriate storage durations
6+
7+
8+
## CERT
9+
10+
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` **
11+
12+
## Implementation notes
13+
14+
The rule checks specifically for pointers to objects with automatic storage duration with respect to the following cases: returned by functions, assigned to function output parameters and assigned to static storage duration variables.
15+
16+
## References
17+
18+
* CERT-C: [DCL30-C: Declare objects with appropriate storage durations](https://wiki.sei.cmu.edu/confluence/display/c)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @id c/cert/declare-objects-with-appropriate-storage-durations
3+
* @name DCL30-C: Declare objects with appropriate storage durations
4+
* @description When storage durations are not compatible between assigned pointers it can lead to
5+
* referring to objects outside of their lifetime, which is undefined behaviour.
6+
* @kind problem
7+
* @precision high
8+
* @problem.severity error
9+
* @tags external/cert/id/dcl30-c
10+
* correctness
11+
* external/cert/obligation/rule
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.cert
16+
import codingstandards.cpp.FunctionParameter
17+
import semmle.code.cpp.dataflow.DataFlow
18+
19+
class Source extends StackVariable {
20+
Source() { not this instanceof FunctionParameter }
21+
}
22+
23+
abstract class Sink extends DataFlow::Node { }
24+
25+
class FunctionSink extends Sink {
26+
FunctionSink() {
27+
//output parameter
28+
exists(FunctionParameter f |
29+
f.getAnAccess() = this.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() and
30+
f.getUnderlyingType() instanceof PointerType
31+
)
32+
or
33+
//function returns pointer
34+
exists(Function f, ReturnStmt r |
35+
f.getType() instanceof PointerType and
36+
r.getEnclosingFunction() = f and
37+
r.getExpr() = this.asExpr()
38+
)
39+
}
40+
}
41+
42+
class StaticSink extends Sink {
43+
StaticSink() {
44+
exists(StaticStorageDurationVariable s |
45+
this.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = s.getAnAccess() and
46+
s.getUnderlyingType() instanceof PointerType
47+
)
48+
}
49+
}
50+
51+
from DataFlow::Node src, DataFlow::Node sink
52+
where
53+
not isExcluded(sink.asExpr(),
54+
Declarations8Package::declareObjectsWithAppropriateStorageDurationsQuery()) and
55+
exists(Source s | src.asExpr() = s.getAnAccess()) and
56+
sink instanceof Sink and
57+
DataFlow::localFlow(src, sink)
58+
select sink, "$@ with automatic storage may be accessible outside of its lifetime.", src, src.toString()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:3:10:3:10 | a | $@ with automatic storage may be accessible outside of its lifetime. | test.c:3:10:3:10 | a | a |
2+
| test.c:15:4:15:8 | param [inner post update] | $@ with automatic storage may be accessible outside of its lifetime. | test.c:15:12:15:13 | a2 | a2 |
3+
| test.c:21:3:21:3 | g [post update] | $@ with automatic storage may be accessible outside of its lifetime. | test.c:21:7:21:8 | a3 | a3 |
4+
| test.c:32:3:32:3 | g [post update] | $@ with automatic storage may be accessible outside of its lifetime. | test.c:32:7:32:8 | a5 | a5 |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/DCL30-C/DeclareObjectsWithAppropriateStorageDurations.ql

c/cert/test/rules/DCL30-C/test.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
char *f(void) {
2+
char a[1];
3+
return a; // NON_COMPLIANT
4+
}
5+
6+
char f1(void) {
7+
char a1[1];
8+
a1[0] = 'a';
9+
return a1[0]; // COMPLIANT
10+
}
11+
12+
void f2(char **param) {
13+
char a2[1];
14+
a2[0] = 'a';
15+
*param = a2; // NON_COMPLIANT
16+
}
17+
18+
const char *g;
19+
void f3(void) {
20+
const char a3[] = "test";
21+
g = a3; // NON_COMPLIANT
22+
}
23+
24+
void f4(void) {
25+
const char a4[] = "test";
26+
const char *p = a4; // COMPLIANT
27+
}
28+
29+
#include <stdlib.h>
30+
void f5(void) {
31+
const char a5[] = "test";
32+
g = a5; // COMPLIANT[FALSE_POSITIVE]
33+
g = NULL;
34+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtype Declarations8Query = TDeclareObjectsWithAppropriateStorageDurationsQuery()
7+
8+
predicate isDeclarations8QueryMetadata(Query query, string queryId, string ruleId, string category) {
9+
query =
10+
// `Query` instance for the `declareObjectsWithAppropriateStorageDurations` query
11+
Declarations8Package::declareObjectsWithAppropriateStorageDurationsQuery() and
12+
queryId =
13+
// `@id` for the `declareObjectsWithAppropriateStorageDurations` query
14+
"c/cert/declare-objects-with-appropriate-storage-durations" and
15+
ruleId = "DCL30-C" and
16+
category = "rule"
17+
}
18+
19+
module Declarations8Package {
20+
Query declareObjectsWithAppropriateStorageDurationsQuery() {
21+
//autogenerate `Query` type
22+
result =
23+
// `Query` type for `declareObjectsWithAppropriateStorageDurations` query
24+
TQueryC(TDeclarations8PackageQuery(TDeclareObjectsWithAppropriateStorageDurationsQuery()))
25+
}
26+
}

cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import Declarations4
2222
import Declarations5
2323
import Declarations6
2424
import Declarations7
25+
import Declarations8
2526
import Expressions
2627
import IO1
2728
import IO2
@@ -67,6 +68,7 @@ newtype TCQuery =
6768
TDeclarations5PackageQuery(Declarations5Query q) or
6869
TDeclarations6PackageQuery(Declarations6Query q) or
6970
TDeclarations7PackageQuery(Declarations7Query q) or
71+
TDeclarations8PackageQuery(Declarations8Query q) or
7072
TExpressionsPackageQuery(ExpressionsQuery q) or
7173
TIO1PackageQuery(IO1Query q) or
7274
TIO2PackageQuery(IO2Query q) or
@@ -112,6 +114,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
112114
isDeclarations5QueryMetadata(query, queryId, ruleId, category) or
113115
isDeclarations6QueryMetadata(query, queryId, ruleId, category) or
114116
isDeclarations7QueryMetadata(query, queryId, ruleId, category) or
117+
isDeclarations8QueryMetadata(query, queryId, ruleId, category) or
115118
isExpressionsQueryMetadata(query, queryId, ruleId, category) or
116119
isIO1QueryMetadata(query, queryId, ruleId, category) or
117120
isIO2QueryMetadata(query, queryId, ruleId, category) or

rule_packages/c/Declarations8.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"CERT-C": {
3+
"DCL30-C": {
4+
"properties": {
5+
"obligation": "rule"
6+
},
7+
"queries": [
8+
{
9+
"description": "When storage durations are not compatible between assigned pointers it can lead to referring to objects outside of their lifetime, which is undefined behaviour.",
10+
"kind": "problem",
11+
"name": "Declare objects with appropriate storage durations",
12+
"precision": "high",
13+
"severity": "error",
14+
"short_name": "DeclareObjectsWithAppropriateStorageDurations",
15+
"tags": [
16+
"correctness"
17+
],
18+
"implementation_scope": {
19+
"description": "The rule checks specifically for pointers to objects with automatic storage duration with respect to the following cases: returned by functions, assigned to function output parameters and assigned to static storage duration variables."
20+
}
21+
}
22+
],
23+
"title": "Declare objects with appropriate storage durations"
24+
}
25+
}
26+
}

rules.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ c,CERT-C,CON39-C,Yes,Rule,,,Do not join or detach a thread that was previously j
498498
c,CERT-C,CON40-C,Yes,Rule,,,Do not refer to an atomic variable twice in an expression,,Concurrency5,Medium,
499499
c,CERT-C,CON41-C,Yes,Rule,,,Wrap functions that can fail spuriously in a loop,CON53-CPP,Concurrency3,Medium,
500500
c,CERT-C,CON43-C,OutOfScope,Rule,,,Do not allow data races in multithreaded code,,,,
501-
c,CERT-C,DCL30-C,Yes,Rule,,,Declare objects with appropriate storage durations,,Declarations,Hard,
501+
c,CERT-C,DCL30-C,Yes,Rule,,,Declare objects with appropriate storage durations,,Declarations8,Hard,
502502
c,CERT-C,DCL31-C,Yes,Rule,,,Declare identifiers before using them,,Declarations1,Medium,
503503
c,CERT-C,DCL36-C,No,Rule,,,Do not declare an identifier with conflicting linkage classifications,,,,
504504
c,CERT-C,DCL37-C,Yes,Rule,,,Do not declare or define a reserved identifier,,Declarations1,Easy,

0 commit comments

Comments
 (0)