Skip to content

Conversation

@ioanachirca
Copy link
Contributor

@ioanachirca ioanachirca commented Jul 3, 2020

Signed-off-by: Ioana Chirca chioana@amazon.com

Reason for This PR

Part of #2003
This PR adds checks/comments for the micro_http operations that are not fixed in #1985

Description of Changes

[Author TODO: add description of changes.]

  • This functionality can be added in rust-vmm.

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license.

PR Checklist

[Author TODO: Meet these criteria.]
[Reviewer TODO: Verify that these criteria are met. Request changes if not]

  • All commits in this PR are signed (git commit -s).
  • The reason for this PR is clearly provided (issue no. or explanation).
  • The description of changes is clear and encompassing.
  • Any required documentation changes (code and docs) are included in this PR.
  • Any newly added unsafe code is properly documented.
  • Any API changes are reflected in firecracker/swagger.yaml.
  • Any user-facing changes are mentioned in CHANGELOG.md.

@ioanachirca ioanachirca self-assigned this Jul 3, 2020
let uri_and_version = &request_line[(method_end + 1)..];
let uri_start = method_end.checked_add(1).ok_or(RequestError::Overflow)?;

// Slice access is safe because `uri_start` <= `request_line` size.
Copy link
Contributor

Choose a reason for hiding this comment

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

Who validates that uri_start is <= request_line? The above check seem to only check that the integer does not overflow.

Copy link

Choose a reason for hiding this comment

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

+1 on this. The comments in this function should be clearer and point to the exact place where the check is assured (in this case, find call).

Also, it looks like, in the following scenario:

let request_line = b"GET";
        assert_eq!(
            RequestLine::try_from(request_line).unwrap_err(),
            RequestError::InvalidHttpMethod("Unsupported HTTP method.")
        );

the returned error is Unsupported HTTP method, but I don't know/think that this error is the best one, seems really confusing, would it be better to return something else?
Maybe parse_request_line() could return an error if SP is not found, what do you think?

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 added more comments, hope it got a littler clearer.
Also modified parse_request_line to return an error if there is no SP.

let version = &uri_and_version[(uri_end + 1)..];
let version_start = uri_end.checked_add(1).ok_or(RequestError::Overflow)?;

// Slice access is safe because `version_start` <= `uri_and_version` size.
Copy link
Contributor

Choose a reason for hiding this comment

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

Same question as above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tried to add comments. 😅

let uri_and_version = &request_line[(method_end + 1)..];
let uri_start = method_end.checked_add(1).ok_or(RequestError::Overflow)?;

// Slice access is safe because `uri_start` <= `request_line` size.
Copy link

Choose a reason for hiding this comment

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

+1 on this. The comments in this function should be clearer and point to the exact place where the check is assured (in this case, find call).

Also, it looks like, in the following scenario:

let request_line = b"GET";
        assert_eq!(
            RequestLine::try_from(request_line).unwrap_err(),
            RequestError::InvalidHttpMethod("Unsupported HTTP method.")
        );

the returned error is Unsupported HTTP method, but I don't know/think that this error is the best one, seems really confusing, would it be better to return something else?
Maybe parse_request_line() could return an error if SP is not found, what do you think?

let body_len = headers_and_body
.len()
.checked_sub(crlf_end)
.ok_or(RequestError::Underflow)?;
Copy link

Choose a reason for hiding this comment

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

Is it possible to have tests for at least some of the Underflow, Overflow scenarios that are handled in 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.

The underflows don't seem possible so I removed them and added comments. for overflows it's a little harder to test 😞

return Err(RequestError::InvalidRequest);
}
let body_as_bytes = &headers_and_body[(headers_end + 2 * CRLF_LEN)..];
let body_as_bytes = &headers_and_body[crlf_end..];
Copy link

Choose a reason for hiding this comment

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

This one might deserve a comment too.

@ioanachirca ioanachirca force-pushed the arithmetic_ops branch 2 times, most recently from c92bebf to 7bc15d8 Compare July 7, 2020 08:19
lauralt
lauralt previously approved these changes Jul 13, 2020
Comment on lines 324 to 328
RequestError::Underflow => build_response(
Version::default(),
StatusCode::BadRequest,
Body::new(e.to_string()),
),
Copy link

Choose a reason for hiding this comment

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

nit: since this seems unreachable now, I would move this arm at the end of this match, right before the UnsupportedHeader one (I wouldn't though replace build_response() with unreachable!()since maybe try_from() eventually will be able to return Underflow too and it would be pretty easy to forget updating here with 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.

}

(b"", b"", b"")
Err(RequestError::InvalidRequest)
Copy link

Choose a reason for hiding this comment

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

nit: maybe add a comment here that we now consider as invalid a request with no SPs.

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. Also removed the case when we return an Ok when there is no HTTP version.

Comment on lines 225 to 226
// Underflow is not possible here because `byte_stream[request_line_end..]` starts with CR LF,
// so `headers_end` can be either zero (first match arm) or >= 3.
Copy link

Choose a reason for hiding this comment

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

nit (to avoid any kind of confusion):

Suggested change
// Underflow is not possible here because `byte_stream[request_line_end..]` starts with CR LF,
// so `headers_end` can be either zero (first match arm) or >= 3.
// Underflow is not possible here because `byte_stream[request_line_end..]` starts with CR LF,
// so `headers_end` can be either zero (but this case is treated separately in the first match arm)
// or >= 3 (current case).

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.

@ioanachirca ioanachirca force-pushed the arithmetic_ops branch 2 times, most recently from 9b9bbdc to 5878780 Compare July 13, 2020 11:31
Signed-off-by: Ioana Chirca <chioana@amazon.com>
@ioanachirca ioanachirca merged commit c8e5bcc into firecracker-microvm:master Jul 14, 2020
@ioanachirca ioanachirca deleted the arithmetic_ops branch July 14, 2020 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants