From db5d9b04543dea74b81b97fbed4a680fc3adc171 Mon Sep 17 00:00:00 2001 From: Kirill Pakhomov Date: Tue, 6 Nov 2018 19:17:51 +0300 Subject: dcmihandler: Fix Get DCMI Capabilities command Get DCMI Capabilities (Discover) command returned wrong values for parameters exceeding 1 byte length. Also added the check for SEL entries number range per DCMI specification. Tested: the condition for value limit check works properly. Change-Id: Iee0d75594067630bb6094d05533c87e3ad82807e Signed-off-by: Kirill Pakhomov --- dcmihandler.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'dcmihandler.cpp') diff --git a/dcmihandler.cpp b/dcmihandler.cpp index e858416..cb14005 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -784,16 +784,23 @@ ipmi_ret_t getDCMICapabilities(ipmi_netfn_t netfn, ipmi_cmd_t cmd, // If the data is beyond first byte boundary, insert in a // 16bit pattern for example number of SEL entries are represented // in 12bits. - if ((cap.length + cap.position) > 8) + if ((cap.length + cap.position) > dcmi::gByteBitSize) { - // Read the value corresponding to capability name and assign to - // 16bit bitset. - std::bitset<16> val(data.value(cap.name.c_str(), 0)); + uint16_t val = data.value(cap.name.c_str(), 0); + // According to DCMI spec v1.5, max number of SEL entries is + // 4096, but bit 12b of DCMI capabilities Mandatory Platform + // Attributes field is reserved and therefore we can use only + // the provided 12 bits with maximum value of 4095. + // We're playing safe here by applying the mask + // to ensure that provided value will fit into 12 bits. + if (cap.length > dcmi::gByteBitSize) + { + val &= dcmi::gMaxSELEntriesMask; + } val <<= cap.position; - reinterpret_cast( - responseData - ->data)[(cap.bytePosition - 1) / sizeof(uint16_t)] |= - val.to_ulong(); + responseData->data[cap.bytePosition - 1] |= + static_cast(val); + responseData->data[cap.bytePosition] |= val >> dcmi::gByteBitSize; } else { -- cgit v1.2.1