Skip to content

Commit 2608509

Browse files
committed
Merge branch 'main' of github.com:github/codeql into SharedDataflow_SequenceFlow
2 parents e1343c7 + e2c6a01 commit 2608509

File tree

204 files changed

+14747
-649
lines changed

Some content is hidden

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

204 files changed

+14747
-649
lines changed

change-notes/1.26/analysis-cpp.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
1919

2020
## Changes to libraries
2121

22-
* The models library now models more taint flows through `std::string`.
22+
* The models library now models some taint flows through `std::array`, `std::vector`, `std::deque`, `std::list` and `std::forward_list`.
23+
* The models library now models many more taint flows through `std::string`.
2324
* The `SimpleRangeAnalysis` library now supports multiplications of the form
24-
`e1 * e2` when `e1` and `e2` are unsigned.
25+
`e1 * e2` and `x *= e2` when `e1` and `e2` are unsigned or constant.

change-notes/1.26/analysis-javascript.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
- [pretty-format](https://www.npmjs.com/package/pretty-format)
1515
- [stringify-object](https://www.npmjs.com/package/stringify-object)
1616

17+
* Analyzing files with the ".cjs" extension is now supported.
18+
1719
## New queries
1820

1921
| **Query** | **Tags** | **Purpose** |

cpp/ql/src/semmle/code/cpp/exprs/Expr.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,17 @@ class BinaryOperation extends Operation, @bin_op_expr {
539539
/** Gets the right operand of this binary operation. */
540540
Expr getRightOperand() { this.hasChild(result, 1) }
541541

542+
/**
543+
* Holds if `e1` and `e2` (in either order) are the two operands of this
544+
* binary operation.
545+
*/
546+
predicate hasOperands(Expr e1, Expr e2) {
547+
exists(int i | i in [0, 1] |
548+
this.hasChild(e1, i) and
549+
this.hasChild(e2, 1 - i)
550+
)
551+
}
552+
542553
override string toString() { result = "... " + this.getOperator() + " ..." }
543554

544555
override predicate mayBeImpure() {

cpp/ql/src/semmle/code/cpp/models/Models.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ private import implementations.Strcat
1313
private import implementations.Strcpy
1414
private import implementations.Strdup
1515
private import implementations.Strftime
16+
private import implementations.StdContainer
1617
private import implementations.StdString
1718
private import implementations.Swap
1819
private import implementations.GetDelim
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* Provides models for C++ containers `std::array`, `std::vector`, `std::deque`, `std::list` and `std::forward_list`.
3+
*/
4+
5+
import semmle.code.cpp.models.interfaces.Taint
6+
7+
/**
8+
* Additional model for standard container constructors that reference the
9+
* value type of the container (that is, the `T` in `std::vector<T>`). For
10+
* example the fill constructor:
11+
* ```
12+
* std::vector<std::string> v(100, potentially_tainted_string);
13+
* ```
14+
*/
15+
class StdSequenceContainerConstructor extends Constructor, TaintFunction {
16+
StdSequenceContainerConstructor() {
17+
this.getDeclaringType().hasQualifiedName("std", "vector") or
18+
this.getDeclaringType().hasQualifiedName("std", "deque") or
19+
this.getDeclaringType().hasQualifiedName("std", "list") or
20+
this.getDeclaringType().hasQualifiedName("std", "forward_list")
21+
}
22+
23+
/**
24+
* Gets the index of a parameter to this function that is a reference to the
25+
* value type of the container.
26+
*/
27+
int getAValueTypeParameterIndex() {
28+
getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
29+
getDeclaringType().getTemplateArgument(0) // i.e. the `T` of this `std::vector<T>`
30+
}
31+
32+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
33+
// taint flow from any parameter of the value type to the returned object
34+
input.isParameterDeref(getAValueTypeParameterIndex()) and
35+
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
36+
}
37+
}
38+
39+
/**
40+
* The standard container functions `push_back` and `push_front`.
41+
*/
42+
class StdSequenceContainerPush extends TaintFunction {
43+
StdSequenceContainerPush() {
44+
this.hasQualifiedName("std", "vector", "push_back") or
45+
this.hasQualifiedName("std", "deque", "push_back") or
46+
this.hasQualifiedName("std", "deque", "push_front") or
47+
this.hasQualifiedName("std", "list", "push_back") or
48+
this.hasQualifiedName("std", "list", "push_front") or
49+
this.hasQualifiedName("std", "forward_list", "push_front")
50+
}
51+
52+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
53+
// flow from parameter to qualifier
54+
input.isParameterDeref(0) and
55+
output.isQualifierObject()
56+
}
57+
}
58+
59+
/**
60+
* The standard container functions `front` and `back`.
61+
*/
62+
class StdSequenceContainerFrontBack extends TaintFunction {
63+
StdSequenceContainerFrontBack() {
64+
this.hasQualifiedName("std", "array", "front") or
65+
this.hasQualifiedName("std", "array", "back") or
66+
this.hasQualifiedName("std", "vector", "front") or
67+
this.hasQualifiedName("std", "vector", "back") or
68+
this.hasQualifiedName("std", "deque", "front") or
69+
this.hasQualifiedName("std", "deque", "back") or
70+
this.hasQualifiedName("std", "list", "front") or
71+
this.hasQualifiedName("std", "list", "back") or
72+
this.hasQualifiedName("std", "forward_list", "front")
73+
}
74+
75+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
76+
// flow from object to returned reference
77+
input.isQualifierObject() and
78+
output.isReturnValueDeref()
79+
}
80+
}
81+
82+
/**
83+
* The standard container `swap` functions.
84+
*/
85+
class StdSequenceContainerSwap extends TaintFunction {
86+
StdSequenceContainerSwap() {
87+
this.hasQualifiedName("std", "array", "swap") or
88+
this.hasQualifiedName("std", "vector", "swap") or
89+
this.hasQualifiedName("std", "deque", "swap") or
90+
this.hasQualifiedName("std", "list", "swap") or
91+
this.hasQualifiedName("std", "forward_list", "swap")
92+
}
93+
94+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
95+
// container1.swap(container2)
96+
input.isQualifierObject() and
97+
output.isParameterDeref(0)
98+
or
99+
input.isParameterDeref(0) and
100+
output.isQualifierObject()
101+
}
102+
}

cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ class StdBasicString extends TemplateClass {
88
}
99

1010
/**
11-
* The standard function `std::string.c_str`.
11+
* The `std::string` functions `c_str` and `data`.
1212
*/
1313
class StdStringCStr extends TaintFunction {
14-
StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") }
14+
StdStringCStr() {
15+
this.hasQualifiedName("std", "basic_string", "c_str") or
16+
this.hasQualifiedName("std", "basic_string", "data")
17+
}
1518

1619
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
1720
// flow from string itself (qualifier) to return value
@@ -40,12 +43,16 @@ class StdStringPlus extends TaintFunction {
4043
}
4144

4245
/**
43-
* The `std::string` functions `operator+=` and `append`.
46+
* The `std::string` functions `operator+=`, `append`, `insert` and
47+
* `replace`. All of these functions combine the existing string
48+
* with a new string (or character) from one of the arguments.
4449
*/
4550
class StdStringAppend extends TaintFunction {
4651
StdStringAppend() {
4752
this.hasQualifiedName("std", "basic_string", "operator+=") or
48-
this.hasQualifiedName("std", "basic_string", "append")
53+
this.hasQualifiedName("std", "basic_string", "append") or
54+
this.hasQualifiedName("std", "basic_string", "insert") or
55+
this.hasQualifiedName("std", "basic_string", "replace")
4956
}
5057

5158
/**
@@ -58,6 +65,35 @@ class StdStringAppend extends TaintFunction {
5865
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
5966
}
6067

68+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
69+
// flow from string and parameter to string (qualifier) and return value
70+
(
71+
input.isQualifierObject() or
72+
input.isParameterDeref(getAStringParameter())
73+
) and
74+
(
75+
output.isQualifierObject() or
76+
output.isReturnValueDeref()
77+
)
78+
}
79+
}
80+
81+
/**
82+
* The standard function `std::string.assign`.
83+
*/
84+
class StdStringAssign extends TaintFunction {
85+
StdStringAssign() { this.hasQualifiedName("std", "basic_string", "assign") }
86+
87+
/**
88+
* Gets the index of a parameter to this function that is a string (or
89+
* character).
90+
*/
91+
int getAStringParameter() {
92+
getParameter(result).getType() instanceof PointerType or
93+
getParameter(result).getType() instanceof ReferenceType or
94+
getParameter(result).getType() = getDeclaringType().getTemplateArgument(0) // i.e. `std::basic_string::CharT`
95+
}
96+
6197
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
6298
// flow from parameter to string itself (qualifier) and return value
6399
input.isParameterDeref(getAStringParameter()) and
@@ -67,3 +103,45 @@ class StdStringAppend extends TaintFunction {
67103
)
68104
}
69105
}
106+
107+
/**
108+
* The standard function `std::string.copy`.
109+
*/
110+
class StdStringCopy extends TaintFunction {
111+
StdStringCopy() { this.hasQualifiedName("std", "basic_string", "copy") }
112+
113+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
114+
// copy(dest, num, pos)
115+
input.isQualifierObject() and
116+
output.isParameterDeref(0)
117+
}
118+
}
119+
120+
/**
121+
* The standard function `std::string.substr`.
122+
*/
123+
class StdStringSubstr extends TaintFunction {
124+
StdStringSubstr() { this.hasQualifiedName("std", "basic_string", "substr") }
125+
126+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
127+
// substr(pos, num)
128+
input.isQualifierObject() and
129+
output.isReturnValue()
130+
}
131+
}
132+
133+
/**
134+
* The standard function `std::string.swap`.
135+
*/
136+
class StdStringSwap extends TaintFunction {
137+
StdStringSwap() { this.hasQualifiedName("std", "basic_string", "swap") }
138+
139+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
140+
// str1.swap(str2)
141+
input.isQualifierObject() and
142+
output.isParameterDeref(0)
143+
or
144+
input.isParameterDeref(0) and
145+
output.isQualifierObject()
146+
}
147+
}

0 commit comments

Comments
 (0)