-
Notifications
You must be signed in to change notification settings - Fork 1.8k
C++: alias and side effect info for pure functions #1566
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
Changes from all commits
ea7602b
41e4d92
3804c1f
72f9add
c195420
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,29 +1,30 @@ | ||
| import semmle.code.cpp.models.interfaces.ArrayFunction | ||
| import semmle.code.cpp.models.interfaces.Taint | ||
| import semmle.code.cpp.models.interfaces.Alias | ||
| import semmle.code.cpp.models.interfaces.SideEffect | ||
|
|
||
| class PureFunction extends ArrayFunction, TaintFunction { | ||
| PureFunction() { | ||
| class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction { | ||
| PureStrFunction() { | ||
| exists(string name | | ||
| hasName(name) and | ||
| hasGlobalName(name) and | ||
| ( | ||
| name = "abs" | ||
| or name = "atof" | ||
| name = "atof" | ||
| or name = "atoi" | ||
| or name = "atol" | ||
| or name = "atoll" | ||
| or name = "labs" | ||
| or name = "strcasestr" | ||
| or name = "strchnul" | ||
| or name = "strchr" | ||
| or name = "strchrnul" | ||
| or name = "strstr" | ||
| or name = "strpbrk" | ||
| or name = "strcmp" | ||
| or name = "strcspn" | ||
| or name = "strlen" | ||
| or name = "strncmp" | ||
| or name = "strnlen" | ||
| or name = "strrchr" | ||
| or name = "strspn" | ||
| or name = "strstr" | ||
| or name = "strtod" | ||
| or name = "strtof" | ||
| or name = "strtol" | ||
|
|
@@ -40,18 +41,67 @@ class PureFunction extends ArrayFunction, TaintFunction { | |
|
|
||
| override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { | ||
| exists (ParameterIndex i | | ||
| input.isInParameter(i) or | ||
| ( | ||
| input.isInParameterPointer(i) and | ||
| getParameter(i).getUnspecifiedType() instanceof PointerType | ||
| ) | ||
| input.isInParameter(i) and | ||
| exists(getParameter(i)) | ||
| or | ||
| input.isInParameterPointer(i) and | ||
| getParameter(i).getUnspecifiedType() instanceof PointerType | ||
| ) and | ||
| ( | ||
| ( | ||
| output.isOutReturnPointer() and | ||
| getUnspecifiedType() instanceof PointerType | ||
| ) or | ||
| output.isOutReturnPointer() and | ||
| getUnspecifiedType() instanceof PointerType | ||
| or | ||
| output.isOutReturnValue() | ||
| ) | ||
| } | ||
|
|
||
| override predicate parameterNeverEscapes(int i) { | ||
| getParameter(i).getUnspecifiedType() instanceof PointerType and | ||
| not parameterEscapesOnlyViaReturn(i) | ||
| } | ||
|
|
||
| override predicate parameterEscapesOnlyViaReturn(int i) { | ||
| i = 0 and | ||
| getUnspecifiedType() instanceof PointerType | ||
| } | ||
|
|
||
| override predicate parameterIsAlwaysReturned(int i) { | ||
| none() | ||
| } | ||
|
|
||
| override predicate neverReadsMemory() { | ||
| none() | ||
| } | ||
|
|
||
| override predicate neverWritesMemory() { | ||
| any() | ||
| } | ||
| } | ||
|
|
||
| class PureFunction extends TaintFunction, SideEffectFunction { | ||
| PureFunction() { | ||
| exists(string name | | ||
| hasGlobalName(name) and | ||
| ( | ||
| name = "abs" or | ||
| name = "labs" | ||
| ) | ||
| ) | ||
| } | ||
|
|
||
| override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { | ||
| exists (ParameterIndex i | | ||
| input.isInParameter(i) and | ||
| exists(getParameter(i)) | ||
| ) and | ||
|
Contributor
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. If there's a function in the snapshot with 20 parameters, then this predicate claims that parameter 19 of I'd much prefer that we only define taint flow for parameters that actually exist. The same issue is in To make this easier to detect in the future, we could make
Contributor
Author
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. I've narrowed it to only report parameters that actually exist |
||
| output.isOutReturnValue() | ||
| } | ||
|
|
||
| override predicate neverReadsMemory() { | ||
| any() | ||
| } | ||
|
|
||
| override predicate neverWritesMemory() { | ||
| any() | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -189,4 +189,15 @@ static void AsmStmtWithOutputs(unsigned int& a, unsigned int& b, unsigned int& c | |
| : "+a" (a), "+b" (b) | ||
| : "c" (c), "d" (d) | ||
| ); | ||
| } | ||
|
|
||
| int strcmp(const char *, const char *); | ||
| int strlen(const char *); | ||
| int abs(int); | ||
|
|
||
| int PureFunctions(char *str1, char *str2, int x) { | ||
| int ret = strcmp(str1, str2); | ||
| ret += strlen(str1); | ||
| ret += abs(x); | ||
| return ret; | ||
|
Contributor
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. You wrote in #1542 (comment) that this PR was about the side effects of
Contributor
Author
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. Added. |
||
| } | ||
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.
By strstr family I meant also
strcasestr,strchr,strchrnul, andstrrchr. Instead of enumerating them, you can consider matching them by signature: it's all the functions on this list that return a pointer type.