Skip to content

Conversation

@connorkuehl
Copy link
Collaborator

@connorkuehl connorkuehl commented Dec 4, 2025

The NBD protocol states:

The data MUST lie within the bounds of the original offset and
length of the client's request

If a server did send a block outside of that range, I expect the
previous code would wrap around the unsigned integer for the
normalizedOffset calculation, which may still accidentally trigger
the previous code's error condition, albeit with a somewhat confusing
error message.

Hopefully these explicit bounds checks provide clearer error messages.

@connorkuehl connorkuehl requested a review from a team as a code owner December 4, 2025 00:57
@connorkuehl connorkuehl force-pushed the verify_read_reply_offsets branch 3 times, most recently from 7991ac1 to 4491db1 Compare December 4, 2025 02:25
Copy link

@sam-github sam-github left a comment

Choose a reason for hiding this comment

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

I think span could use some comments, even though the pkg is internal, but otherwise LGTM.


if int(normalizedOffset)+int(datalen) > len(buf) {
return n, errors.New("server chunk is too large for given buf")
if err := got.Check(); err != nil || !wantedBlocks.Contains(got) {

Choose a reason for hiding this comment

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

I read span first, it looks like this is only usage of Contains(), and the Check() is done here. Forcing all callers to check that spans are valid and making the methods assume they are is a classic optimization, makes sense if documented, but it might be prone to misuse.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Check() is used in two places where the input to the Span is untrusted. For example, wantedBlocks outside of the loop uses trusted input and inspection:

	wantedBlocks := span.Span[uint64]{
		Start: offset,
		End:   offset + uint64(len(buf)),
	}

The NBD protocol states:

> The data MUST lie within the bounds of the original offset and
> length of the client's request

If a server did send a block outside of that range, I expect the
previous code would wrap around the unsigned integer for the
normalizedOffset calculation, which may still accidentally trigger
the previous code's error condition, albeit with a somewhat confusing
error message.

Hopefully these explicit bounds checks provide clearer error messages.
@connorkuehl connorkuehl force-pushed the verify_read_reply_offsets branch from 4491db1 to b286f61 Compare December 4, 2025 22:28
@connorkuehl connorkuehl merged commit e34ed7c into main Dec 4, 2025
8 checks passed
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