Skip to content
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

Spec cleanup: Should fixup behavior when repeat1-1==0 be specified or changed to an error? #3823

Closed
elasota opened this issue Nov 17, 2023 · 3 comments
Assignees

Comments

@elasota
Copy link
Contributor

elasota commented Nov 17, 2023

Doing some more edge case checks on the specification...

In ZSTD_decodeSequence there is this code:

size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
temp += !temp;   /* 0 is not valid; input is corrupted; force offset to 1 */

In the case where literals_length==0 and offset_value==3 and Repeated_Offset1==1 this will insert 1 at the start of the repeated offset list and move the rest down.

Right now the comment says it is invalid, but it is silently processed as if it is valid. So, should this behavior be put in the spec? If not, should the code be rejecting this data?

@Cyan4973 Cyan4973 self-assigned this Nov 17, 2023
@Cyan4973
Copy link
Contributor

This is invalid.
If the code reaches that part, it means data is corrupted, because it's trying to generate an offset = 0.

This is considered a potential attack vector, that's why the offset is converted into a 1: it ensures that the underlying memory content of the destination buffer is overwritten, hence it prevents scenario where such content could be accessed afterwards.

Detecting this issue is good ground to generate an error.
Problem is, inserting an error detection signal at this place in the code results (or at least used to result) in substantial performance drawbacks, because it's an extremely hot section of the decoding loop.
Therefore, we rather rely on the checksum to tell us so (assuming the issue is accidental, following a transmission or storage error).

@terrelln
Copy link
Contributor

This is one of the cases where we don't guarantee that we reject all possible invalid frames. Since we guarantee safety on invalid frames, we must not actually copy from offset 0. In this case we decide to copy from offset 1. So given this invalid frame, for performance reasons, we decide to ignore the corruption.

Other implementations are allowed to reject this frame.

@Cyan4973
Copy link
Contributor

spec updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants