fix: ipmi rmcptag and cbcpad#7555
Merged
Obihoernchen merged 4 commits intoMay 6, 2026
Merged
Conversation
cbc_pad in decrypt mode reads the last byte as the pad count, then calls splice(@block, 0 - $count). If decrypted data is corrupt, the pad count can exceed the array size, crashing with "Modification of non-creatable array value attempted, subscript -16". Return empty string on invalid padding so the caller treats it as a decryption failure rather than accepting corrupted data as a valid IPMI response. Ref: xcat2#7511
OpenBMC-based BMCs return message tag 0 in RAKP2/RAKP4 instead of echoing the tag from the request. xCAT rejected these as stale responses and retried indefinitely until timeout. Accept tag 0 but verify the remote console session ID in the response matches our current sidm. This prevents stale retries from corrupting session state while allowing OpenBMC responses through. Applied to got_rmcp_response, got_rakp2, and got_rakp4. Ref: xcat2#7511
Set bit 4 (0x10) of the requested privilege byte in RAKP Message 1 for name-only user lookup, matching ipmitool behavior. Use the same value consistently in all HMAC calculations (RAKP2 verification, RAKP3 auth code, SIK derivation). Without this, some BMCs fail user lookup with "Unauthorized name" even though the credentials are correct. Ref: xcat2#7511
Extend the existing sha256-to-sha1 fallback (already present in got_rmcp_response for Open Session errors) to also cover RAKP2 rejections with "Unauthorized name" (0x0d) or "Invalid role" (0x09). Ref: xcat2#7511
Obihoernchen
approved these changes
May 6, 2026
Member
Obihoernchen
left a comment
There was a problem hiding this comment.
Tested on Intel/Mitac as well. Works fine.
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.
@Obihoernchen this one was only possible with the help of AI assisted tools, so the explanation is also up to them:
Problem
xCAT's IPMI implementation can't talk to OpenBMC-based BMCs. All commands (rpower, rsetboot, rinv, rvitals) either timeout or crash with the
spliceerror from #7511. Meanwhile, ipmitool works fine on the same hardware with the same credentials.Reported on Lenovo XCC3 (#7511). We reproduced it on an IBM POWER9 AC922 (also OpenBMC-based). @Obihoernchen has seen the same class of failure on Intel/Mitac BMCs.
What we found
We instrumented IPMI.pm with syslog traces and did packet captures against a POWER9 BMC to compare xCAT's RMCP+ handshake with ipmitool's. Three things were wrong:
1. OpenBMC returns message tag 0 in RAKP2
The IPMI spec says RAKP Message 2 should echo the tag from RAKP Message 1. OpenBMC returns 0 instead. xCAT rejected every RAKP2 as stale and retried until timeout:
The same check exists in
got_rmcp_responseandgot_rakp4.2. xCAT doesn't set the name-only lookup bit in RAKP1
After fixing the tag, sessions got through but failed with "Unauthorized name". Packet capture showed the difference: ipmitool sends the RAKP1 privilege byte as
0x14(admin + name-only lookup), while xCAT sent0x04.The name-only lookup bit (bit 4, IPMI spec Table 13-17) tells the BMC to find the user by name alone rather than by name+privilege. Without it, some BMCs reject valid credentials.
This byte is also part of the HMAC input for RAKP2 verification, RAKP3 auth code, and SIK derivation, so all three had to use the updated value to keep the hashes correct.
3. cbc_pad crashes on bad padding (the original #7511)
cbc_padin decrypt mode reads the last byte as a pad count and doessplice(@block, 0 - $count). If decryption produced garbage, the count could exceed the array length, crashing with "Modification of non-creatable array value attempted, subscript -16".What this PR does
Four commits:
Return empty string from
cbc_padwhen padding is invalid, so corrupted decryption is treated as a packet failure instead of crashing.Accept message tag 0 in
got_rmcp_response,got_rakp2, andgot_rakp4, but only after verifying the remote console session ID matches our current sidm. This keeps the stale-response protection while letting OpenBMC responses through.Set the name-only lookup bit in RAKP1 and use the same privilege byte in all HMAC calculations (RAKP2 check, RAKP3 auth code, SIK). Matches what ipmitool does.
Extend the sha256-to-sha1 fallback (already in
got_rmcp_response) to also cover RAKP2 auth rejections.Tested on
* SDR reservation is an OpenBMC limitation, unrelated to this fix.
Before this PR, the POWER9 BMC timed out on every xCAT IPMI command. After, all four BMC types work. We don't have a Lenovo XCC3 or Intel/Mitac to test, so those need the reporter @nuttapongc or @Obihoernchen to verify.
Fixes #7511