Skip to content

Storage panic from oss-fuzz#385

Merged
kaczmarczyck merged 2 commits intogoogle:developfrom
kaczmarczyck:storage-fuzz-test
Sep 24, 2021
Merged

Storage panic from oss-fuzz#385
kaczmarczyck merged 2 commits intogoogle:developfrom
kaczmarczyck:storage-fuzz-test

Conversation

@kaczmarczyck
Copy link
Copy Markdown
Collaborator

oss-fuzz found a panic (bug report is private until fixed).

Fixed and added tests for this issue, on more coverage.

@kaczmarczyck kaczmarczyck requested a review from ia0 September 24, 2021 13:56
@kaczmarczyck kaczmarczyck self-assigned this Sep 24, 2021
@google-cla google-cla Bot added the cla: yes label Sep 24, 2021
@coveralls
Copy link
Copy Markdown

coveralls commented Sep 24, 2021

Coverage Status

Coverage increased (+0.3%) to 42.628% when pulling 508c09c on kaczmarczyck:storage-fuzz-test into 930a44c on google:develop.


impl UpgradeStorage for SyscallUpgradeStorage {
fn read_partition(&self, offset: usize, length: usize) -> StorageResult<&[u8]> {
if length == 0 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shouldn't we check that the offset is valid (essentially offset <= partition.len())? And then wouldn't the rest of the code just work by itself?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I was wondering if I should ignore empty slices (my current choice) or treat them as being present at offset. The rest of the code just works after that initial check in both cases, right?
To be honest, both choices should do the job. I don't see why a client would read or write empty slices. The fail outside of range could be a hacky partition check, but that's harder than just asking directly.
Any advantages of one over the other?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The rest of the code just works after that initial check in both cases, right?

I don't know. In the current case it's not executed so it doesn't matter. But if it works it makes it possible to just check the offset and still run the code.

I don't see why a client would read or write empty slices.

Then why not return an error instead of an empty slice?

The fail outside of range could be a hacky partition check, but that's harder than just asking directly.

I don't understand what you want to say.

Any advantages of one over the other?

From the 3 options:

  • Early exit with error
  • Early exit with empty slice (no validity check)
  • Check offset validity

I think "early exit with empty slice" should not be an option because it can hide bad behaviors (invalid offset returning correct result). Between the 2 other options it's a matter of whether it's valid to read an empty slice or not.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Okay, then I'll just disallow empty slices in general, for read and write.

}

fn write_partition(&mut self, offset: usize, data: &[u8]) -> StorageResult<()> {
if data.is_empty() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Changed to error.

@kaczmarczyck kaczmarczyck merged commit 0f88d65 into google:develop Sep 24, 2021
@kaczmarczyck kaczmarczyck deleted the storage-fuzz-test branch September 24, 2021 15:46
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.

3 participants