Skip to content

Commit 5e21a5d

Browse files
committed
C++: Fix flow for return values of strlcat and strlcpy
1 parent e4c8406 commit 5e21a5d

File tree

2 files changed

+12
-10
lines changed

2 files changed

+12
-10
lines changed

cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
9696
/**
9797
* The `strlcat` function.
9898
*/
99-
class StrlcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction {
99+
class StrlcatFunction extends TaintFunction, ArrayFunction, SideEffectFunction {
100100
StrlcatFunction() {
101101
this.hasGlobalName("strlcat") // strlcat(dst, src, dst_size)
102102
}
@@ -116,11 +116,6 @@ class StrlcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Si
116116
*/
117117
int getParamDest() { result = 0 }
118118

119-
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
120-
input.isParameter(0) and
121-
output.isReturnValue()
122-
}
123-
124119
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
125120
(
126121
input.isParameter(2)
@@ -129,7 +124,7 @@ class StrlcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Si
129124
or
130125
input.isParameterDeref(1)
131126
) and
132-
(output.isParameterDeref(0) or output.isReturnValueDeref())
127+
(output.isParameterDeref(0) or output.isReturnValue())
133128
}
134129

135130
override predicate hasArrayInput(int param) {

cpp/ql/lib/semmle/code/cpp/models/implementations/Strcpy.qll

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,19 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
5454
*/
5555
private predicate isSVariant() { this.getName().matches("%\\_s") }
5656

57+
/**
58+
* Holds if the function returns the total length the string would have had if the size was unlimited.
59+
*/
60+
private predicate returnsTotalLength() { this.getName() = "strlcpy" }
61+
5762
/**
5863
* Gets the index of the parameter that is the maximum size of the copy (in characters).
5964
*/
6065
int getParamSize() {
6166
if this.isSVariant()
6267
then result = 1
6368
else (
64-
this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%", "%lcpy%"]) and
69+
this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%", "strlcpy"]) and
6570
result = 2
6671
)
6772
}
@@ -101,6 +106,7 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
101106
input.isParameterDeref(this.getParamSrc()) and
102107
output.isReturnValueDeref()
103108
or
109+
not this.returnsTotalLength() and
104110
input.isParameter(this.getParamDest()) and
105111
output.isReturnValue()
106112
}
@@ -111,8 +117,9 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
111117
exists(this.getParamSize()) and
112118
input.isParameterDeref(this.getParamSrc()) and
113119
(
114-
output.isParameterDeref(this.getParamDest()) or
115-
output.isReturnValueDeref()
120+
output.isParameterDeref(this.getParamDest())
121+
or
122+
not this.returnsTotalLength() and output.isReturnValueDeref()
116123
)
117124
}
118125

0 commit comments

Comments
 (0)