-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++: Remove pointer/pointee conflation from models of "pure" functions #18556
Changes from 3 commits
503f018
1266684
a1449bf
e0f2f1d
2cdb52c
fb12847
67e3b69
7792839
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import semmle.code.cpp.models.interfaces.ArrayFunction | ||
import semmle.code.cpp.models.interfaces.Taint | ||
import semmle.code.cpp.models.interfaces.DataFlow | ||
import semmle.code.cpp.models.interfaces.Alias | ||
import semmle.code.cpp.models.interfaces.SideEffect | ||
|
||
|
@@ -8,7 +9,7 @@ import semmle.code.cpp.models.interfaces.SideEffect | |
* guaranteed to be side-effect free. | ||
*/ | ||
private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, | ||
SideEffectFunction | ||
SideEffectFunction, DataFlowFunction | ||
{ | ||
PureStrFunction() { | ||
this.hasGlobalOrStdOrBslName([ | ||
|
@@ -26,22 +27,43 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio | |
} | ||
|
||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { | ||
exists(ParameterIndex i | | ||
exists(ParameterIndex i | exists(this.getParameter(i)) | | ||
// For these functions we add taint flow according to the following rules: | ||
// 1. If the parameter is of a pointer type then there is taint from the | ||
// indirection of the parameter. Otherwise, there is taint from the | ||
// parameter. | ||
// 2. If the return value is of a pointer type then there is taint to the | ||
// indirection of the return. Otherwise, there is taint to the return. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense to move this comment up before the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. Fixed in 67e3b69 |
||
( | ||
input.isParameter(i) and | ||
exists(this.getParameter(i)) | ||
or | ||
input.isParameterDeref(i) and | ||
this.getParameter(i).getUnspecifiedType() instanceof PointerType | ||
if this.getParameter(i).getUnspecifiedType() instanceof PointerType | ||
then input.isParameterDeref(i) | ||
else input.isParameter(i) | ||
) and | ||
// Functions that end with _l also take a locale argument (always as the last argument), | ||
// and we don't want taint from those arguments. | ||
(not this.getName().matches("%\\_l") or exists(this.getParameter(i + 1))) | ||
) and | ||
( | ||
output.isReturnValueDeref() and | ||
this.getUnspecifiedType() instanceof PointerType | ||
or | ||
if this.getUnspecifiedType() instanceof PointerType | ||
then output.isReturnValueDeref() | ||
else output.isReturnValue() | ||
) | ||
or | ||
// If there is taint flow from *input to *output then there is also taint | ||
// flow from input to output. | ||
this.hasTaintFlow(input.getIndirectionInput(), output.getIndirectionOutput()) and | ||
// no need to add taint-flow if we already have dataflow | ||
MathiasVP marked this conversation as resolved.
Show resolved
Hide resolved
|
||
not this.hasDataFlow(input, output) | ||
} | ||
|
||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { | ||
exists(int i | | ||
input.isParameter(i) and | ||
// see the comment in `hasTaintFlow` for an explanation | ||
(not this.getName().matches("%\\_l") or exists(this.getParameter(i + 1))) and | ||
// These functions always return the same pointer as they are given | ||
this.hasGlobalOrStdOrBslName([strrev(), strlwr(), strupr()]) and | ||
this.getParameter(i).getUnspecifiedType() instanceof PointerType and | ||
output.isReturnValue() | ||
) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add a helper predicate for the locale argument check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea! Fixed in 7792839