Skip to content

Commit cd2154d

Browse files
authored
Merge branch 'main' into knewbury01/more-FP-fix
2 parents e1190d8 + 9de7232 commit cd2154d

File tree

127 files changed

+5254
-323
lines changed

Some content is hidden

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

127 files changed

+5254
-323
lines changed

.github/workflows/dispatch-matrix-test-on-comment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
token: ${{ secrets.RELEASE_ENGINEERING_TOKEN }}
3636
repository: github/codeql-coding-standards-release-engineering
3737
event-type: matrix-test
38-
client-payload: '{"pr": "${{ github.event.number }}"}'
38+
client-payload: '{"pr": "${{ github.event.issue.number }}"}'
3939

4040
- uses: actions/github-script@v6
4141
if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/test-matrix') }}

.vscode/tasks.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@
249249
"Null",
250250
"OperatorInvariants",
251251
"Operators",
252+
"OutOfBounds",
252253
"Pointers",
253254
"Pointers1",
254255
"Pointers2",

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,5 @@ All header files in [c/common/test/includes/standard-library](./c/common/test/in
5050
---
5151

5252
<sup>1</sup>This repository incorporates portions of the SEI CERT® Coding Standards available at https://wiki.sei.cmu.edu/confluence/display/seccode/SEI+CERT+Coding+Standards; however, such use does not necessarily constitute or imply an endorsement, recommendation, or favoring by Carnegie Mellon University or its Software Engineering Institute.
53+
54+

c/cert/src/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cert-c-coding-standards
2-
version: 2.15.0-dev
2+
version: 2.18.0-dev
33
description: CERT C 2016
44
suites: codeql-suites
55
license: MIT

c/cert/src/rules/ARR30-C/DoNotFormOutOfBoundsPointersOrArraySubscripts.md

Lines changed: 485 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @id c/cert/do-not-form-out-of-bounds-pointers-or-array-subscripts
3+
* @name ARR30-C: Do not form or use out-of-bounds pointers or array subscripts
4+
* @description Forming or using an out-of-bounds pointer is undefined behavior and can result in
5+
* invalid memory accesses.
6+
* @kind problem
7+
* @precision medium
8+
* @problem.severity error
9+
* @tags external/cert/id/arr30-c
10+
* correctness
11+
* security
12+
* external/cert/obligation/rule
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.cert
17+
import codingstandards.c.OutOfBounds
18+
19+
from
20+
OOB::BufferAccess ba, Expr bufferArg, Expr sizeArg, OOB::PointerToObjectSource bufferSource,
21+
string message
22+
where
23+
not isExcluded(ba, OutOfBoundsPackage::doNotFormOutOfBoundsPointersOrArraySubscriptsQuery()) and
24+
// exclude loops
25+
not exists(Loop loop | loop.getStmt().getChildStmt*() = ba.getEnclosingStmt()) and
26+
// exclude size arguments that are of type ssize_t
27+
not sizeArg.getAChild*().(VariableAccess).getTarget().getType() instanceof Ssize_t and
28+
// exclude size arguments that are assigned the result of a function call e.g. ftell
29+
not sizeArg.getAChild*().(VariableAccess).getTarget().getAnAssignedValue() instanceof FunctionCall and
30+
// exclude field or array accesses for the size arguments
31+
not sizeArg.getAChild*() instanceof FieldAccess and
32+
not sizeArg.getAChild*() instanceof ArrayExpr and
33+
(
34+
exists(int sizeArgValue, int bufferArgSize |
35+
OOB::isSizeArgGreaterThanBufferSize(bufferArg, sizeArg, bufferSource, bufferArgSize, sizeArgValue, ba) and
36+
message =
37+
"Buffer accesses offset " + sizeArgValue +
38+
" which is greater than the fixed size " + bufferArgSize + " of the $@."
39+
)
40+
or
41+
exists(int sizeArgUpperBound, int sizeMult, int bufferArgSize |
42+
OOB::isSizeArgNotCheckedLessThanFixedBufferSize(bufferArg, sizeArg, bufferSource,
43+
bufferArgSize, ba, sizeArgUpperBound, sizeMult) and
44+
message =
45+
"Buffer may access up to offset " + sizeArgUpperBound + "*" + sizeMult +
46+
" which is greater than the fixed size " + bufferArgSize + " of the $@."
47+
)
48+
or
49+
OOB::isSizeArgNotCheckedGreaterThanZero(bufferArg, sizeArg, bufferSource, ba) and
50+
message = "Buffer access may be to a negative index in the buffer."
51+
)
52+
select ba, message, bufferSource, "buffer"

c/cert/src/rules/ARR38-C/LibraryFunctionArgumentOutOfBounds.md

Lines changed: 486 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @id c/cert/library-function-argument-out-of-bounds
3+
* @name ARR38-C: Guarantee that library functions do not form invalid pointers
4+
* @description Passing out-of-bounds pointers or erroneous size arguments to standard library
5+
* functions can result in out-of-bounds accesses and other undefined behavior.
6+
* @kind problem
7+
* @precision high
8+
* @problem.severity error
9+
* @tags external/cert/id/arr38-c
10+
* correctness
11+
* security
12+
* external/cert/obligation/rule
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.cert
17+
import codingstandards.c.OutOfBounds
18+
19+
from
20+
OOB::BufferAccessLibraryFunctionCall fc, string message, Expr bufferArg, string bufferArgStr,
21+
Expr sizeOrOtherBufferArg, string otherStr
22+
where
23+
not isExcluded(fc, OutOfBoundsPackage::libraryFunctionArgumentOutOfBoundsQuery()) and
24+
OOB::problems(fc, message, bufferArg, bufferArgStr, sizeOrOtherBufferArg, otherStr)
25+
select fc, message, bufferArg, bufferArgStr, sizeOrOtherBufferArg, otherStr

c/cert/src/rules/ENV32-C/ExitHandlersMustReturnNormally.ql

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,26 @@
1414
import cpp
1515
import codingstandards.c.cert
1616

17-
class ExitFunction extends Function {
18-
ExitFunction() { this.hasGlobalName(["_Exit", "exit", "quick_exit", "longjmp"]) }
17+
/**
18+
* Exit function or macro.
19+
*/
20+
class Exit extends Locatable {
21+
Exit() {
22+
["_Exit", "exit", "quick_exit", "longjmp"] = [this.(Function).getName(), this.(Macro).getName()]
23+
}
1924
}
2025

21-
class ExitFunctionCall extends FunctionCall {
22-
ExitFunctionCall() { this.getTarget() instanceof ExitFunction }
26+
class ExitExpr extends Expr {
27+
ExitExpr() {
28+
this.(FunctionCall).getTarget() instanceof Exit
29+
or
30+
any(MacroInvocation m | this = m.getExpr()).getMacro() instanceof Exit
31+
}
2332
}
2433

34+
/**
35+
* Functions that are registered as exit handlers.
36+
*/
2537
class RegisteredAtexit extends FunctionAccess {
2638
RegisteredAtexit() {
2739
exists(FunctionCall ae |
@@ -32,24 +44,26 @@ class RegisteredAtexit extends FunctionAccess {
3244
}
3345

3446
/**
35-
* Nodes of type Function, FunctionCall or FunctionAccess that \
36-
* are reachable from a redistered atexit handler and
47+
* Nodes of type Function, FunctionCall, FunctionAccess or ExitExpr
48+
* that are reachable from a registered atexit handler and
3749
* can reach an exit function.
3850
*/
3951
class InterestingNode extends ControlFlowNode {
4052
InterestingNode() {
4153
exists(Function f |
4254
(
4355
this = f and
44-
// exit functions are not part of edges
45-
not this = any(ExitFunction ec)
56+
// exit is not part of edges
57+
not this instanceof Exit
4658
or
4759
this.(FunctionCall).getTarget() = f
4860
or
4961
this.(FunctionAccess).getTarget() = f
62+
or
63+
this.(ExitExpr).getEnclosingFunction() = f
5064
) and
51-
// reaches an exit function
52-
f.calls*(any(ExitFunction e)) and
65+
// reaches an `ExitExpr`
66+
f.calls*(any(ExitExpr ee).getEnclosingFunction()) and
5367
// is reachable from a registered atexit function
5468
exists(RegisteredAtexit re | re.getTarget().calls*(f))
5569
)
@@ -62,14 +76,12 @@ class InterestingNode extends ControlFlowNode {
6276
* `Function` and `FunctionCall` in their body.
6377
*/
6478
query predicate edges(InterestingNode a, InterestingNode b) {
65-
a.(FunctionAccess).getTarget() = b
66-
or
67-
a.(FunctionCall).getTarget() = b
68-
or
79+
a.(FunctionAccess).getTarget() = b or
80+
a.(FunctionCall).getTarget() = b or
6981
a.(Function).calls(_, b)
7082
}
7183

72-
from RegisteredAtexit hr, Function f, ExitFunctionCall e
84+
from RegisteredAtexit hr, Function f, ExitExpr e
7385
where edges(hr, f) and edges+(f, e)
7486
select f, hr, e, "The function is $@ and $@. It must instead terminate by returning.", hr,
7587
"registered as `exit handler`", e, "calls an `exit function`"

c/cert/src/rules/ERR33-C/DetectAndHandleStandardLibraryErrors.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ ControlFlowNode ferrorNotchecked(FileWriteFunctionCall write) {
441441
not isShortCircuitedEdge(mid, result) and
442442
result = mid.getASuccessor() and
443443
//Stop recursion on call to ferror on the correct file
444-
not accessSameTarget(result.(FerrorCall).getArgument(0), write.getFileExpr())
444+
not sameFileSource(result.(FerrorCall), write)
445445
)
446446
}
447447

0 commit comments

Comments
 (0)