Skip to content

Conversation

@rdmarsh2
Copy link
Contributor

@rdmarsh2 rdmarsh2 commented Jul 8, 2019

No description provided.

@rdmarsh2 rdmarsh2 requested a review from a team as a code owner July 8, 2019 19:29
}

override predicate parameterEscapesOnlyViaReturn(int i) {
none()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The strstr family of functions return a pointer that's derived from (and may be equal to) their first parameter.

@jbj jbj added the C++ label Jul 9, 2019
or name = "strnlen"
or name = "strrchr"
or name = "strspn"
or name = "strstr"
Copy link
Contributor

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, and strrchr. Instead of enumerating them, you can consider matching them by signature: it's all the functions on this list that return a pointer type.

Copy link
Contributor

@jbj jbj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for torturing this PR so much. I've just been involved in fixing many hard-to-debug bugs that were caused by inaccurate modelling of standard-library functions. It looks like we'll be modelling many more of those functions in Q3, so I'd like the foundation to be robust.

) and
(
output.isOutReturnValue() or
output.isOutReturnPointer()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the previous version of this was right:

    ... and
    (
      (
        output.isOutReturnPointer() and
        getUnspecifiedType() instanceof PointerType
      ) or
      output.isOutReturnValue()
    )

The new version claims that taint flows to the return pointer even if the return value is int.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


override predicate parameterEscapesOnlyViaReturn(int i) {
i = 0 and
getType().getUnspecifiedType() instanceof PointerType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we get rid of getType().getUnspecifiedType() chains?

not (
i = 0 and
getType().getUnspecifiedType() instanceof PointerType
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can not ( ... ) be simplified to not parameterEscapesOnlyViaReturn(i)? That should make it more robust against future changes. Hard-coding i = 0 only once makes me only half as nervous about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

class PureFunction extends TaintFunction, SideEffectFunction {
PureFunction() {
exists(string name |
hasName(name) and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's independent of this PR, but this use of hasName has bitten us several times, and I don't want it to bite us again. It's just very likely that class member functions have short names like abs. See, for example, #1023.

Please switch to hasGlobalName here and in PureStrFunction. If you want to make sure that std::abs is also matched, then it's time to implement the hasGlobalOrStdName predicate we've been talking about.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll switch to hasGlobalName for now, and do hasGlobalOrStdName as a separate PR (since it should involve a pass through most of the library)

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
exists (ParameterIndex i |
input.isInParameter(i)
) and
Copy link
Contributor

Choose a reason for hiding this comment

The 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 abs flows to its return value. That seems wasteful and confusing.

I'd much prefer that we only define taint flow for parameters that actually exist. The same issue is in PureStrFunction.

To make this easier to detect in the future, we could make ParameterIndex private and put a bindingset annotation on isInParameter etc. But that's probably not for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've narrowed it to only report parameters that actually exist

int PureFunctions(char *str1, char *str2, int x) {
int ret = strcmp(str1, str2);
ret += abs(x);
return ret;
Copy link
Contributor

Choose a reason for hiding this comment

The 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 strlen, so shouldn't that be included in the test?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

@jbj jbj merged commit 23001d5 into github:master Jul 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants