Skip to content

Commit aab34fd

Browse files
authored
Merge branch 'main' into knewbury01/fix-193
2 parents eb55b38 + 3fb6ac2 commit aab34fd

File tree

83 files changed

+1193
-326
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1193
-326
lines changed

.github/workflows/bump-version.yml

-33
This file was deleted.

.github/workflows/code-scanning-pack-gen.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ jobs:
9999
run: |
100100
PATH=$PATH:$CODEQL_HOME/codeql
101101
102-
codeql query compile --threads 0 cpp
103-
codeql query compile --threads 0 c
102+
codeql query compile --precompile --threads 0 cpp
103+
codeql query compile --precompile --threads 0 c
104104
105105
cd ..
106106
zip -r codeql-coding-standards/code-scanning-cpp-query-pack.zip codeql-coding-standards/c/ codeql-coding-standards/cpp/ codeql-coding-standards/.codeqlmanifest.json codeql-coding-standards/supported_codeql_configs.json codeql-coding-standards/scripts/configuration codeql-coding-standards/scripts/reports codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/guideline_recategorization codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/schemas

.github/workflows/finalize-release.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,21 @@ jobs:
9999
next_version=$(python scripts/release/next-version.py --component minor --pre-release dev -- $version)
100100
echo "NEXT_VERSION=$next_version" >> "$GITHUB_ENV"
101101
working-directory: tooling
102+
103+
- name: Generate token
104+
if: env.HOTFIX_RELEASE == 'false'
105+
id: generate-token
106+
uses: actions/create-github-app-token@eaddb9eb7e4226c68cf4b39f167c83e5bd132b3e
107+
with:
108+
app-id: ${{ vars.AUTOMATION_APP_ID }}
109+
private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
110+
owner: ${{ github.repository_owner }}
111+
repositories: "codeql-coding-standards"
102112

103113
- name: Bump main version
114+
if: env.HOTFIX_RELEASE == 'false'
104115
env:
105-
GH_TOKEN: ${{ github.token }}
116+
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
106117
run: |
107118
echo "Bumping main version to $NEXT_VERSION"
108119

README.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ This repository contains CodeQL queries and libraries which support various Codi
1010

1111
The following coding standards are supported:
1212
- [AUTOSAR - Guidelines for the use of C++14 language in critical and safety-related systems (Releases R22-11, R20-11, R19-11 and R19-03)](https://www.autosar.org/fileadmin/standards/R22-11/AP/AUTOSAR_RS_CPP14Guidelines.pdf).
13-
- [MISRA C++:2008](https://www.misra.org.uk) (support limited to the rules specified in AUTOSAR).
1413
- [SEI CERT C++ Coding Standard: Rules for Developing Safe, Reliable, and Secure Systems (2016 Edition)](https://resources.sei.cmu.edu/library/asset-view.cfm?assetID=494932)
1514
- [SEI CERT C Coding Standard: Rules for Developing Safe, Reliable, and Secure Systems (2016 Edition)](https://resources.sei.cmu.edu/downloads/secure-coding/assets/sei-cert-c-coding-standard-2016-v01.pdf)
16-
- [MISRA C 2012](https://www.misra.org.uk/product/misra-c2012-third-edition-first-revision/).
15+
- [MISRA C 2012, 3rd Edition, 1st revision](https://www.misra.org.uk/product/misra-c2012-third-edition-first-revision/) (incoporating Amendment 1 & Technical Corrigendum 1). In addition, we support the following additional amendments and technical corrigendums:
16+
- [MISRA C 2012 Amendment 2](https://misra.org.uk/app/uploads/2021/06/MISRA-C-2012-AMD2.pdf)
17+
- [MISRA C 2012 Technical Corrigendum 2](https://misra.org.uk/app/uploads/2022/04/MISRA-C-2012-TC2.pdf)
18+
19+
## :construction: Standards under development :construction:
20+
21+
- [MISRA C++ 2023](https://misra.org.uk/product/misra-cpp2023/) - under development _scheduled for release 2024 Q4_.
1722

1823
## How do I use the CodeQL Coding Standards Queries?
1924

c/cert/src/qlpack.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cert-c-coding-standards
2-
version: 2.28.0-dev
2+
version: 2.32.0-dev
33
description: CERT C 2016
44
suites: codeql-suites
55
license: MIT

c/cert/src/rules/STR32-C/NonNullTerminatedToFunctionThatExpectsAString.ql

+81-22
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import codingstandards.c.cert
1717
import codingstandards.cpp.Naming
1818
import codingstandards.cpp.dataflow.TaintTracking
1919
import codingstandards.cpp.PossiblyUnsafeStringOperation
20+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
2021

2122
/**
2223
* Models a function that is part of the standard library that expects a
@@ -43,32 +44,90 @@ class ExpectsNullTerminatedStringAsArgumentFunctionCall extends FunctionCall {
4344
Expr getAnExpectingExpr() { result = e }
4445
}
4546

46-
from ExpectsNullTerminatedStringAsArgumentFunctionCall fc, Expr e, Expr target
47-
where
48-
target = fc.getAnExpectingExpr() and
49-
not isExcluded(fc, Strings1Package::nonNullTerminatedToFunctionThatExpectsAStringQuery()) and
50-
(
51-
exists(PossiblyUnsafeStringOperation op |
52-
// don't report violations of the same function call.
53-
not op = fc and
54-
e = op and
55-
TaintTracking::localTaint(DataFlow::exprNode(op.getAnArgument()), DataFlow::exprNode(target))
47+
class PossiblyUnsafeStringOperationSource extends Source {
48+
PossiblyUnsafeStringOperation op;
49+
50+
PossiblyUnsafeStringOperationSource() { this.asExpr() = op.getAnArgument() }
51+
52+
PossiblyUnsafeStringOperation getOp() { result = op }
53+
}
54+
55+
class CharArraySource extends Source {
56+
CharArrayInitializedWithStringLiteral op;
57+
58+
CharArraySource() {
59+
op.getContainerLength() <= op.getStringLiteralLength() and
60+
this.asExpr() = op
61+
}
62+
}
63+
64+
abstract class Source extends DataFlow::Node { }
65+
66+
class Sink extends DataFlow::Node {
67+
Sink() {
68+
exists(ExpectsNullTerminatedStringAsArgumentFunctionCall fc |
69+
fc.getAnExpectingExpr() = this.asExpr()
5670
)
57-
or
58-
exists(CharArrayInitializedWithStringLiteral op |
59-
e = op and
60-
op.getContainerLength() <= op.getStringLiteralLength() and
61-
TaintTracking::localTaint(DataFlow::exprNode(op), DataFlow::exprNode(target))
71+
}
72+
}
73+
74+
module MyFlowConfiguration implements DataFlow::ConfigSig {
75+
predicate isSink(DataFlow::Node sink) {
76+
sink instanceof Sink and
77+
//don't report violations of the same function call
78+
not sink instanceof Source
79+
}
80+
81+
predicate isSource(DataFlow::Node source) { source instanceof Source }
82+
83+
predicate isAdditionalFlowStep(DataFlow::Node innode, DataFlow::Node outnode) {
84+
exists(FunctionCall realloc, ReallocFunction fn |
85+
fn.getACallToThisFunction() = realloc and
86+
realloc.getArgument(0) = innode.asExpr() and
87+
realloc = outnode.asExpr()
6288
)
63-
) and
64-
// don't report cases flowing to this node where there is a flow from a
65-
// literal assignment of a null terminator
66-
not exists(AssignExpr aexp |
89+
}
90+
}
91+
92+
class ReallocFunction extends AllocationFunction {
93+
ReallocFunction() { exists(this.getReallocPtrArg()) }
94+
}
95+
96+
/**
97+
* Determines if the string is acceptably null terminated
98+
* The only condition we accept as a guarantee to null terminate is:
99+
* `str[size_expr] = '\0';`
100+
* where we do not check the value of the `size_expr` used
101+
*/
102+
predicate isGuarded(Expr guarded, Expr source) {
103+
exists(AssignExpr aexp |
67104
aexp.getLValue() instanceof ArrayExpr and
68105
aexp.getRValue() instanceof Zero and
69-
TaintTracking::localTaint(DataFlow::exprNode(aexp.getRValue()), DataFlow::exprNode(target)) and
70-
// this must be AFTER the operation causing the non-null termination to be valid.
71-
aexp.getAPredecessor*() = e
106+
// this must be AFTER the operation causing the non-null termination
107+
aexp.getAPredecessor+() = source and
108+
//this guards anything after it
109+
aexp.getASuccessor+() = guarded and
110+
// no reallocs exist after this because they will be conservatively assumed to make the buffer smaller and remove the likliehood of this properly terminating
111+
not exists(ReallocFunction realloc, FunctionCall fn |
112+
fn = realloc.getACallToThisFunction() and
113+
globalValueNumber(aexp.getLValue().(ArrayExpr).getArrayBase()) =
114+
globalValueNumber(fn.getArgument(0)) and
115+
aexp.getASuccessor+() = fn
116+
)
72117
)
118+
}
119+
120+
module MyFlow = TaintTracking::Global<MyFlowConfiguration>;
121+
122+
from
123+
DataFlow::Node source, DataFlow::Node sink, ExpectsNullTerminatedStringAsArgumentFunctionCall fc,
124+
Expr e
125+
where
126+
MyFlow::flow(source, sink) and
127+
sink.asExpr() = fc.getAnExpectingExpr() and
128+
not isGuarded(sink.asExpr(), source.asExpr()) and
129+
if source instanceof PossiblyUnsafeStringOperationSource
130+
then e = source.(PossiblyUnsafeStringOperationSource).getOp()
131+
else e = source.asExpr()
73132
select fc, "String modified by $@ is passed to function expecting a null-terminated string.", e,
74133
"this expression"

c/cert/test/qlpack.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cert-c-coding-standards-tests
2-
version: 2.28.0-dev
2+
version: 2.32.0-dev
33
extractor: cpp
44
license: MIT
55
dependencies:
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
| test.c:19:3:19:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:7:20:7:24 | Cod | this expression |
2-
| test.c:20:3:20:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:7:20:7:24 | Cod | this expression |
3-
| test.c:22:3:22:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:13:3:13:9 | call to strncpy | this expression |
4-
| test.c:23:3:23:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:13:3:13:9 | call to strncpy | this expression |
5-
| test.c:24:3:24:8 | call to strlen | String modified by $@ is passed to function expecting a null-terminated string. | test.c:13:3:13:9 | call to strncpy | this expression |
6-
| test.c:33:3:33:9 | call to wprintf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:30:24:30:29 | Cod | this expression |
7-
| test.c:46:3:46:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:41:3:41:10 | call to snprintf | this expression |
8-
| test.c:47:3:47:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:41:3:41:10 | call to snprintf | this expression |
9-
| test.c:55:3:55:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:53:3:53:9 | call to strncat | this expression |
10-
| test.c:56:3:56:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:53:3:53:9 | call to strncat | this expression |
11-
| test.c:62:3:62:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:60:20:60:24 | Cod | this expression |
12-
| test.c:63:3:63:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:60:20:60:24 | Cod | this expression |
13-
| test.c:75:3:75:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:72:20:72:24 | Cod | this expression |
14-
| test.c:76:3:76:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:72:20:72:24 | Cod | this expression |
15-
| test.c:85:3:85:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:83:3:83:9 | call to strncpy | this expression |
16-
| test.c:86:3:86:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:83:3:83:9 | call to strncpy | this expression |
1+
| test.c:20:3:20:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:8:20:8:24 | Cod | this expression |
2+
| test.c:21:3:21:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:8:20:8:24 | Cod | this expression |
3+
| test.c:23:3:23:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:14:3:14:9 | call to strncpy | this expression |
4+
| test.c:24:3:24:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:14:3:14:9 | call to strncpy | this expression |
5+
| test.c:25:3:25:8 | call to strlen | String modified by $@ is passed to function expecting a null-terminated string. | test.c:14:3:14:9 | call to strncpy | this expression |
6+
| test.c:34:3:34:9 | call to wprintf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:31:24:31:29 | Cod | this expression |
7+
| test.c:47:3:47:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:42:3:42:10 | call to snprintf | this expression |
8+
| test.c:48:3:48:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:42:3:42:10 | call to snprintf | this expression |
9+
| test.c:56:3:56:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:54:3:54:9 | call to strncat | this expression |
10+
| test.c:57:3:57:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:54:3:54:9 | call to strncat | this expression |
11+
| test.c:63:3:63:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:61:20:61:24 | Cod | this expression |
12+
| test.c:64:3:64:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:61:20:61:24 | Cod | this expression |
13+
| test.c:76:3:76:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:73:20:73:24 | Cod | this expression |
14+
| test.c:77:3:77:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:73:20:73:24 | Cod | this expression |
15+
| test.c:86:3:86:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:84:3:84:9 | call to strncpy | this expression |
16+
| test.c:87:3:87:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:84:3:84:9 | call to strncpy | this expression |
17+
| test.c:95:3:95:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:93:17:93:21 | Cod | this expression |
18+
| test.c:95:3:95:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:94:3:94:9 | call to strncpy | this expression |
19+
| test.c:98:3:98:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:93:17:93:21 | Cod | this expression |
20+
| test.c:98:3:98:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:94:3:94:9 | call to strncpy | this expression |
21+
| test.c:122:3:122:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:117:17:117:21 | Cod | this expression |
22+
| test.c:122:3:122:8 | call to printf | String modified by $@ is passed to function expecting a null-terminated string. | test.c:118:3:118:9 | call to strncpy | this expression |

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

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <stdio.h>
2+
#include <stdlib.h>
23
#include <string.h>
34
#include <wchar.h>
45

@@ -84,4 +85,39 @@ f5() {
8485

8586
printf("%s", a1_nnt); // NON_COMPLIANT
8687
printf(a1_nnt); // NON_COMPLIANT
87-
}
88+
}
89+
90+
void test_fn_reported_in_31_simple() {
91+
char *str;
92+
str = (char *)malloc(3);
93+
char a31[3] = "Cod"; // is NOT null terminated
94+
strncpy(str, a31, 3);
95+
printf(str); // NON_COMPLIANT
96+
size_t cur_msg_size = 1024;
97+
str = realloc(str, (cur_msg_size / 2 + 1) * sizeof(char));
98+
printf(str); // NON_COMPLIANT
99+
}
100+
101+
void test_fn_reported_in_31_simple_safe() {
102+
char *str;
103+
str = (char *)malloc(3);
104+
char a31[3] = "Cod"; // is NOT null terminated
105+
strncpy(str, a31, 3);
106+
size_t cur_msg_size = 1024;
107+
size_t temp_size = cur_msg_size / 2 + 1;
108+
str = realloc(str, temp_size * sizeof(char));
109+
str[temp_size - 1] = L'\0'; // Properly null-terminate str
110+
printf(str); // COMPLIANT
111+
}
112+
113+
void test_fn_reported_in_31_simple_relloc() {
114+
char *str;
115+
size_t cur_msg_size = 1024;
116+
str = (char *)malloc(cur_msg_size);
117+
char a31[3] = "Cod"; // is NOT null terminated
118+
strncpy(str, a31, 3);
119+
str[cur_msg_size - 1] = L'\0'; // Properly null-terminate str
120+
size_t temp_size = cur_msg_size / 2 + 1;
121+
str = realloc(str, temp_size * sizeof(char));
122+
printf(str); // NON_COMPLIANT
123+
}

c/common/src/qlpack.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/common-c-coding-standards
2-
version: 2.28.0-dev
2+
version: 2.32.0-dev
33
license: MIT
44
dependencies:
55
codeql/common-cpp-coding-standards: '*'

c/common/test/qlpack.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/common-c-coding-standards-tests
2-
version: 2.28.0-dev
2+
version: 2.32.0-dev
33
extractor: cpp
44
license: MIT
55
dependencies:

c/misra/src/qlpack.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/misra-c-coding-standards
2-
version: 2.28.0-dev
2+
version: 2.32.0-dev
33
description: MISRA C 2012
44
suites: codeql-suites
55
license: MIT

c/misra/src/rules/RULE-8-3/DeclarationsOfAnObjectSameNameAndType.ql

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ where
2020
not isExcluded(decl1, Declarations4Package::declarationsOfAnObjectSameNameAndTypeQuery()) and
2121
not isExcluded(decl2, Declarations4Package::declarationsOfAnObjectSameNameAndTypeQuery()) and
2222
not decl1 = decl2 and
23+
not decl1.getVariable().getDeclaringType().isAnonymous() and
2324
decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and
2425
not typesCompatible(decl1.getType(), decl2.getType())
2526
select decl1,

c/misra/test/qlpack.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/misra-c-coding-standards-tests
2-
version: 2.28.0-dev
2+
version: 2.32.0-dev
33
extractor: cpp
44
license: MIT
55
dependencies:

0 commit comments

Comments
 (0)