Skip to content

Commit

Permalink
Merge branch 'main' into knewbury01/fix-193
Browse files Browse the repository at this point in the history
  • Loading branch information
knewbury01 authored Jul 11, 2024
2 parents eb55b38 + 3fb6ac2 commit aab34fd
Show file tree
Hide file tree
Showing 83 changed files with 1,193 additions and 326 deletions.
33 changes: 0 additions & 33 deletions .github/workflows/bump-version.yml

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/code-scanning-pack-gen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ jobs:
run: |
PATH=$PATH:$CODEQL_HOME/codeql
codeql query compile --threads 0 cpp
codeql query compile --threads 0 c
codeql query compile --precompile --threads 0 cpp
codeql query compile --precompile --threads 0 c
cd ..
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
Expand Down
13 changes: 12 additions & 1 deletion .github/workflows/finalize-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,21 @@ jobs:
next_version=$(python scripts/release/next-version.py --component minor --pre-release dev -- $version)
echo "NEXT_VERSION=$next_version" >> "$GITHUB_ENV"
working-directory: tooling

- name: Generate token
if: env.HOTFIX_RELEASE == 'false'
id: generate-token
uses: actions/create-github-app-token@eaddb9eb7e4226c68cf4b39f167c83e5bd132b3e
with:
app-id: ${{ vars.AUTOMATION_APP_ID }}
private-key: ${{ secrets.AUTOMATION_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: "codeql-coding-standards"

- name: Bump main version
if: env.HOTFIX_RELEASE == 'false'
env:
GH_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
echo "Bumping main version to $NEXT_VERSION"
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ This repository contains CodeQL queries and libraries which support various Codi

The following coding standards are supported:
- [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).
- [MISRA C++:2008](https://www.misra.org.uk) (support limited to the rules specified in AUTOSAR).
- [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)
- [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)
- [MISRA C 2012](https://www.misra.org.uk/product/misra-c2012-third-edition-first-revision/).
- [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:
- [MISRA C 2012 Amendment 2](https://misra.org.uk/app/uploads/2021/06/MISRA-C-2012-AMD2.pdf)
- [MISRA C 2012 Technical Corrigendum 2](https://misra.org.uk/app/uploads/2022/04/MISRA-C-2012-TC2.pdf)

## :construction: Standards under development :construction:

- [MISRA C++ 2023](https://misra.org.uk/product/misra-cpp2023/) - under development _scheduled for release 2024 Q4_.

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

Expand Down
2 changes: 1 addition & 1 deletion c/cert/src/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/cert-c-coding-standards
version: 2.28.0-dev
version: 2.32.0-dev
description: CERT C 2016
suites: codeql-suites
license: MIT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import codingstandards.c.cert
import codingstandards.cpp.Naming
import codingstandards.cpp.dataflow.TaintTracking
import codingstandards.cpp.PossiblyUnsafeStringOperation
import semmle.code.cpp.valuenumbering.GlobalValueNumbering

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

from ExpectsNullTerminatedStringAsArgumentFunctionCall fc, Expr e, Expr target
where
target = fc.getAnExpectingExpr() and
not isExcluded(fc, Strings1Package::nonNullTerminatedToFunctionThatExpectsAStringQuery()) and
(
exists(PossiblyUnsafeStringOperation op |
// don't report violations of the same function call.
not op = fc and
e = op and
TaintTracking::localTaint(DataFlow::exprNode(op.getAnArgument()), DataFlow::exprNode(target))
class PossiblyUnsafeStringOperationSource extends Source {
PossiblyUnsafeStringOperation op;

PossiblyUnsafeStringOperationSource() { this.asExpr() = op.getAnArgument() }

PossiblyUnsafeStringOperation getOp() { result = op }
}

class CharArraySource extends Source {
CharArrayInitializedWithStringLiteral op;

CharArraySource() {
op.getContainerLength() <= op.getStringLiteralLength() and
this.asExpr() = op
}
}

abstract class Source extends DataFlow::Node { }

class Sink extends DataFlow::Node {
Sink() {
exists(ExpectsNullTerminatedStringAsArgumentFunctionCall fc |
fc.getAnExpectingExpr() = this.asExpr()
)
or
exists(CharArrayInitializedWithStringLiteral op |
e = op and
op.getContainerLength() <= op.getStringLiteralLength() and
TaintTracking::localTaint(DataFlow::exprNode(op), DataFlow::exprNode(target))
}
}

module MyFlowConfiguration implements DataFlow::ConfigSig {
predicate isSink(DataFlow::Node sink) {
sink instanceof Sink and
//don't report violations of the same function call
not sink instanceof Source
}

predicate isSource(DataFlow::Node source) { source instanceof Source }

predicate isAdditionalFlowStep(DataFlow::Node innode, DataFlow::Node outnode) {
exists(FunctionCall realloc, ReallocFunction fn |
fn.getACallToThisFunction() = realloc and
realloc.getArgument(0) = innode.asExpr() and
realloc = outnode.asExpr()
)
) and
// don't report cases flowing to this node where there is a flow from a
// literal assignment of a null terminator
not exists(AssignExpr aexp |
}
}

class ReallocFunction extends AllocationFunction {
ReallocFunction() { exists(this.getReallocPtrArg()) }
}

/**
* Determines if the string is acceptably null terminated
* The only condition we accept as a guarantee to null terminate is:
* `str[size_expr] = '\0';`
* where we do not check the value of the `size_expr` used
*/
predicate isGuarded(Expr guarded, Expr source) {
exists(AssignExpr aexp |
aexp.getLValue() instanceof ArrayExpr and
aexp.getRValue() instanceof Zero and
TaintTracking::localTaint(DataFlow::exprNode(aexp.getRValue()), DataFlow::exprNode(target)) and
// this must be AFTER the operation causing the non-null termination to be valid.
aexp.getAPredecessor*() = e
// this must be AFTER the operation causing the non-null termination
aexp.getAPredecessor+() = source and
//this guards anything after it
aexp.getASuccessor+() = guarded and
// no reallocs exist after this because they will be conservatively assumed to make the buffer smaller and remove the likliehood of this properly terminating
not exists(ReallocFunction realloc, FunctionCall fn |
fn = realloc.getACallToThisFunction() and
globalValueNumber(aexp.getLValue().(ArrayExpr).getArrayBase()) =
globalValueNumber(fn.getArgument(0)) and
aexp.getASuccessor+() = fn
)
)
}

module MyFlow = TaintTracking::Global<MyFlowConfiguration>;

from
DataFlow::Node source, DataFlow::Node sink, ExpectsNullTerminatedStringAsArgumentFunctionCall fc,
Expr e
where
MyFlow::flow(source, sink) and
sink.asExpr() = fc.getAnExpectingExpr() and
not isGuarded(sink.asExpr(), source.asExpr()) and
if source instanceof PossiblyUnsafeStringOperationSource
then e = source.(PossiblyUnsafeStringOperationSource).getOp()
else e = source.asExpr()
select fc, "String modified by $@ is passed to function expecting a null-terminated string.", e,
"this expression"
2 changes: 1 addition & 1 deletion c/cert/test/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/cert-c-coding-standards-tests
version: 2.28.0-dev
version: 2.32.0-dev
extractor: cpp
license: MIT
dependencies:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
38 changes: 37 additions & 1 deletion c/cert/test/rules/STR32-C/test.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>

Expand Down Expand Up @@ -84,4 +85,39 @@ f5() {

printf("%s", a1_nnt); // NON_COMPLIANT
printf(a1_nnt); // NON_COMPLIANT
}
}

void test_fn_reported_in_31_simple() {
char *str;
str = (char *)malloc(3);
char a31[3] = "Cod"; // is NOT null terminated
strncpy(str, a31, 3);
printf(str); // NON_COMPLIANT
size_t cur_msg_size = 1024;
str = realloc(str, (cur_msg_size / 2 + 1) * sizeof(char));
printf(str); // NON_COMPLIANT
}

void test_fn_reported_in_31_simple_safe() {
char *str;
str = (char *)malloc(3);
char a31[3] = "Cod"; // is NOT null terminated
strncpy(str, a31, 3);
size_t cur_msg_size = 1024;
size_t temp_size = cur_msg_size / 2 + 1;
str = realloc(str, temp_size * sizeof(char));
str[temp_size - 1] = L'\0'; // Properly null-terminate str
printf(str); // COMPLIANT
}

void test_fn_reported_in_31_simple_relloc() {
char *str;
size_t cur_msg_size = 1024;
str = (char *)malloc(cur_msg_size);
char a31[3] = "Cod"; // is NOT null terminated
strncpy(str, a31, 3);
str[cur_msg_size - 1] = L'\0'; // Properly null-terminate str
size_t temp_size = cur_msg_size / 2 + 1;
str = realloc(str, temp_size * sizeof(char));
printf(str); // NON_COMPLIANT
}
2 changes: 1 addition & 1 deletion c/common/src/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/common-c-coding-standards
version: 2.28.0-dev
version: 2.32.0-dev
license: MIT
dependencies:
codeql/common-cpp-coding-standards: '*'
Expand Down
2 changes: 1 addition & 1 deletion c/common/test/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/common-c-coding-standards-tests
version: 2.28.0-dev
version: 2.32.0-dev
extractor: cpp
license: MIT
dependencies:
Expand Down
2 changes: 1 addition & 1 deletion c/misra/src/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/misra-c-coding-standards
version: 2.28.0-dev
version: 2.32.0-dev
description: MISRA C 2012
suites: codeql-suites
license: MIT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ where
not isExcluded(decl1, Declarations4Package::declarationsOfAnObjectSameNameAndTypeQuery()) and
not isExcluded(decl2, Declarations4Package::declarationsOfAnObjectSameNameAndTypeQuery()) and
not decl1 = decl2 and
not decl1.getVariable().getDeclaringType().isAnonymous() and
decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and
not typesCompatible(decl1.getType(), decl2.getType())
select decl1,
Expand Down
2 changes: 1 addition & 1 deletion c/misra/test/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/misra-c-coding-standards-tests
version: 2.28.0-dev
version: 2.32.0-dev
extractor: cpp
license: MIT
dependencies:
Expand Down
Loading

0 comments on commit aab34fd

Please sign in to comment.