Restrict ME bridging commands
Restrict sensitive ME commands sent via BMC bridging
commands, and return invalid field in request as response
for those.
Tested:
Verified response invalid field in request for the following
ipmitool -t 0x2C -b 0x1 raw 0x6 0x52 0x57 0x0 0x20 0x1 0x0
and got proper response for
ipmitool -t 0x2C -b 0x1 raw 6 1
Change-Id: I53fae25ae27e7d1c257871d2cbadfea6f4c4ba17
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
diff --git a/src/bridgingcommands.cpp b/src/bridgingcommands.cpp
index 88d29b4..b4f0264 100644
--- a/src/bridgingcommands.cpp
+++ b/src/bridgingcommands.cpp
@@ -186,6 +186,48 @@
mesg.append(ipmbMeChannelNum, netFn, rqLun, cmd, data);
}
+static constexpr unsigned int makeCmdKey(unsigned int netFn, unsigned int cmd)
+{
+ return (netFn << 8) | cmd;
+}
+
+static constexpr bool isMeCmdAllowed(uint8_t netFn, uint8_t cmd)
+{
+ constexpr uint8_t netFnMeOEM = 0x2E;
+ constexpr uint8_t cmdMeOemSendRawPeci = 0x40;
+ constexpr uint8_t cmdMeOemAggSendRawPeci = 0x41;
+ constexpr uint8_t cmdMeOemCpuPkgConfWrite = 0x43;
+ constexpr uint8_t cmdMeOemCpuPciConfWrite = 0x45;
+ constexpr uint8_t cmdMeOemReadMemSmbus = 0x47;
+ constexpr uint8_t cmdMeOemWriteMemSmbus = 0x48;
+ constexpr uint8_t cmdMeOemSlotIpmb = 0x51;
+ constexpr uint8_t cmdMeOemSlotI2cMasterWriteRead = 0x52;
+ constexpr uint8_t cmdMeOemSendRawPmbus = 0xD9;
+ constexpr uint8_t cmdMeOemUnlockMeRegion = 0xE7;
+ constexpr uint8_t cmdMeOemAggSendRawPmbus = 0xEC;
+
+ switch (makeCmdKey(netFn, cmd))
+ {
+ // Restrict ME Master write command
+ case makeCmdKey(ipmi::netFnApp, ipmi::app::cmdMasterWriteRead):
+ // Restrict ME OEM commands
+ case makeCmdKey(netFnMeOEM, cmdMeOemSendRawPeci):
+ case makeCmdKey(netFnMeOEM, cmdMeOemAggSendRawPeci):
+ case makeCmdKey(netFnMeOEM, cmdMeOemCpuPkgConfWrite):
+ case makeCmdKey(netFnMeOEM, cmdMeOemCpuPciConfWrite):
+ case makeCmdKey(netFnMeOEM, cmdMeOemReadMemSmbus):
+ case makeCmdKey(netFnMeOEM, cmdMeOemWriteMemSmbus):
+ case makeCmdKey(netFnMeOEM, cmdMeOemSlotIpmb):
+ case makeCmdKey(netFnMeOEM, cmdMeOemSlotI2cMasterWriteRead):
+ case makeCmdKey(netFnMeOEM, cmdMeOemSendRawPmbus):
+ case makeCmdKey(netFnMeOEM, cmdMeOemUnlockMeRegion):
+ case makeCmdKey(netFnMeOEM, cmdMeOemAggSendRawPmbus):
+ return false;
+ default:
+ return true;
+ }
+}
+
ipmi_return_codes Bridging::handleIpmbChannel(sSendMessageReq *sendMsgReq,
ipmi_response_t response,
ipmi_data_len_t dataLen)
@@ -210,6 +252,13 @@
return IPMI_CC_PARM_OUT_OF_RANGE;
}
+ constexpr uint8_t shiftLUN = 2;
+ if (!isMeCmdAllowed((sendMsgReqData->Header.Req.rsNetFnLUN >> shiftLUN),
+ sendMsgReqData->Header.Req.cmd))
+ {
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
// check allowed modes
if (sendMsgReq->modeGet() != modeNoTracking &&
sendMsgReq->modeGet() != modeTrackRequest)