Conversation
The version-string length fields are u8 values taken off the wire (0..=255), but they index a fixed PLDM_FWUP_IMAGE_SET_VER_STR_MAX_LEN (32) byte destination. Each decode site validated only the source buffer, never the destination, so a peer reporting a length above 32 with a long enough payload panicked the decoder. This is remotely reachable on the firmware update path. Reject an out-of-range length with PldmCodecError::InvalidData at each decode site: RequestUpdateRequest, PassComponentTableRequest, FirmwareParameters (both the active and the pending string) and PldmFirmwareString. RequestUpdateRequest::get_comp_image_set_ver_str is a separate case. It called copy_from_slice on the whole 32-byte destination from a source of str_len bytes, and copy_from_slice requires equal lengths, so it panicked for every version string that was not exactly 32 bytes long. The crate's own test uses a 9-byte string but never calls the getter, so this stayed green. Copy only the prefix, clamped to the destination. Where the destination bound now precedes the copy, the redundant [..str_len] reslice of the already-sliced source is dropped. Add tests/ver_str_bounds.rs covering all six sites. Each new test panics against the unpatched code at the reported line and passes after the fix; round-trip tests over every length from 0 to 32 guard against regressing the valid path. Fixes: OpenPRoT#11 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
alanhc
force-pushed
the
fix/ver-str-length-bounds
branch
from
September 10, 2026 16:21
a80d82f to
cf17335
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11.
What
The version-string length fields are
u8values taken off the wire (0..=255),but they index a fixed
PLDM_FWUP_IMAGE_SET_VER_STR_MAX_LEN(32) bytedestination. Each decode site validated only the source buffer, never the
destination, so a peer reporting a length above 32 with a long enough
payload panics the decoder. This is remotely reachable on the firmware update
path.
Each decode site now rejects an out-of-range length with
PldmCodecError::InvalidData, leavingBufferTooShortto mean what it says:the buffer really was too short.
Six sites, not four
The issue lists four. Sweeping every
copy_from_slicein the crate turned uptwo more with the identical shape, both of which panic on
main:RequestUpdateRequest::decode(request_update.rs:129)RequestUpdateRequest::get_comp_image_set_ver_str(request_update.rs:83)FirmwareParameters::decode, active string (get_fw_params.rs:178)FirmwareParameters::decode, pending string (get_fw_params.rs:190)PldmFirmwareString::decode(protocol/firmware_update.rs:627)PassComponentTableRequest::decode(pass_component.rs:122)Site 2 is a different bug and takes a different fix. It called
copy_from_sliceon the whole 32-byte destination from a source ofstr_lenbytes, and
copy_from_slicerequires equal lengths, so it panicked for everyversion string that was not exactly 32 bytes. The crate's own test uses a 9-byte
string but never calls the getter, so this stayed green. It now copies only the
prefix, clamped to the destination.
The
new()constructors use the same call but are safe as written, becausestr_datais always exactly 32 bytes. They are left alone.Where the destination bound now precedes the copy, the redundant
[..str_len]reslice of the already-sliced source is dropped.
Tests
pldm-common/tests/ver_str_bounds.rs, 10 tests covering all six sites.Tests that pass on patched code prove nothing on their own, so each one was run
against the reverted source. Seven fail there, at exactly the reported lines:
The remaining three pass both before and after by design; they are the
no-regression guards, including a round trip over every length from 0 to 32.
Clean build:
cargo fmt --checkclean,cargo clippy --all-targets --all-features -- -D warningsclean, 103 tests pass.One open question
The issue does not say which error variant an over-long length should produce.
I chose
InvalidDataon the grounds that it is malformed input rather than atruncated buffer. If you prefer
BufferTooShort, it is a one-word change in sixplaces, happy to switch.
AI disclosure
Written with Claude Code. I directed the work, and reviewed every line of the
diff and the tests. The six sites were confirmed by executing the reproductions,
and the regression tests were verified to fail against the unpatched source
before being accepted. I did not find an AI policy in this repo; disclosing by
default in case you want one.