Reject secured messages with invalid descriptor count#3587
Reject secured messages with invalid descriptor count#3587steven-bellock merged 1 commit intoDMTF:mainfrom
Conversation
9da2f2c to
2105a6d
Compare
|
Looked into the single failing windows job.
I built the similar native Windows test environment locally with the same toolchain and build config: confirmed it passes most of the time but caught another noisy failure (55/56 pass of test_crypt). Local Windows verificationBuilt and tested locally on native Windows with the same toolchain and build config as CI: Full test suite: test_crypt repeated: 55/56 PASS (1 flake at ~2% rate) Based on this - failure is likely unrelated to the PR. So will try pushing an empty commit to re-kick CI. |
|
The test failure is a known issue. @simons-hub please remove 10317df from the commit history. @twilfredo and @alistair23 for visibility. |
10317df to
2105a6d
Compare
Thanks for taking a look @steven-bellock Done - 10317df has been removed. |
|
good catch! but we should probably handle the num_descriptors == 0 case (iirc this is allowed)? so perhaps an early return with the message buffer offset into the correct place? Since |
|
Thanks @twilfredo, Taking another look at DSP0286 Table 8, it seems to rule out num_descriptors == 0 as a valid case:
Maybe we should distinguish this case as a true INVALID_MSG_FIELD error, while keeping UNSUPPORTED_CAP for > 1 case (which can go away in the future if > 1 becomes supported)? That said, happy to go with your suggestion of treating 0 as valid if you prefer (though probably needs an underflow check before *message_size -= 4). Let me know. |
@simons-hub Thanks for checking with the spec! Let's do it your way that seems better specially since the spec seems to rule out the 0 case. |
8b6e60a to
e3ca96e
Compare
|
Updated with the num_descriptors == 0 and num_descriptors > 1 cases handled separately. |
twilfredo
left a comment
There was a problem hiding this comment.
with @steven-bellock comment addressed, lgtm. Thanks for the patch!
In libspdm_storage_secured_message_decode(), the guard on num_descriptors only rejected values greater than 1 but allowed 0. When num_descriptors is 0, the for-loop never executes, leaving spdm_msg_offset uninitialized — undefined behavior on malformed input. Split the check into two distinct guards: - num_descriptors == 0: INVALID_MSG_FIELD (invalid message) - num_descriptors > 1: UNSUPPORTED_CAP (valid per spec but not yet implemented) Signed-off-by: Simon Ramage <simon.ramage@gmail.com>
e3ca96e to
1c2cf06
Compare


Summary
In
libspdm_storage_secured_message_decode(), the guard onnum_descriptorsonly rejected values greater than 1 but allowed 0. Whennum_descriptorsis 0, the for-loop never executes, leavingspdm_msg_offsetuninitialized. This uninitialized value is then used as a pointer offset to compute*message- undefined behavior on malformed input.Defense-in-depth hardening fix by changing
if (num_descriptors > 1)toif (num_descriptors != 1), which matches the existing code comments and the encode side (always writesnum_descriptors = 1).Detected using cppcheck with
--check-level=exhaustiveflaggeduninitvaronspdm_msg_offsetTest plan
uninitvarwarning eliminated after fix