diff options
author | Corey Minyard <cminyard@mvista.com> | 2021-11-25 15:47:27 +0100 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2021-11-26 04:17:55 +0100 |
commit | d2c12f56fa97df216e71437b218ffbeeb4dd46aa (patch) | |
tree | bf9f97d08f841a395cb62f70cdbd6a785d8ad386 /drivers/char | |
parent | ipmi: fix oob access due to uninit smi_msg type (diff) | |
download | linux-d2c12f56fa97df216e71437b218ffbeeb4dd46aa.tar.xz linux-d2c12f56fa97df216e71437b218ffbeeb4dd46aa.zip |
ipmi: fix IPMI_SMI_MSG_TYPE_IPMB_DIRECT response length checking
A couple of issues:
The tested data sizes are wrong; during the design that changed and this
got missed.
The formatting of the reponse couldn't use the normal one, it has to be
an IPMB formatted response.
Reported-by: Jakub Kicinski <kuba@kernel.org>
Fixes: 059747c245f0 ("ipmi: Add support for IPMB direct messages")
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_msghandler.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 7d7df17d8b3d..99ea6d9b3716 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -4457,13 +4457,24 @@ return_unspecified: msg->rsp[2] = IPMI_ERR_UNSPECIFIED; msg->rsp_size = 3; } else if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) { - /* commands must have at least 3 bytes, responses 4. */ - if (is_cmd && (msg->rsp_size < 3)) { + /* commands must have at least 4 bytes, responses 5. */ + if (is_cmd && (msg->rsp_size < 4)) { ipmi_inc_stat(intf, invalid_commands); goto out; } - if (!is_cmd && (msg->rsp_size < 4)) - goto return_unspecified; + if (!is_cmd && (msg->rsp_size < 5)) { + ipmi_inc_stat(intf, invalid_ipmb_responses); + /* Construct a valid error response. */ + msg->rsp[0] = msg->data[0] & 0xfc; /* NetFN */ + msg->rsp[0] |= (1 << 2); /* Make it a response */ + msg->rsp[0] |= msg->data[2] & 3; /* rqLUN */ + msg->rsp[1] = msg->data[1]; /* Addr */ + msg->rsp[2] = msg->data[2] & 0xfc; /* rqSeq */ + msg->rsp[2] |= msg->data[0] & 0x3; /* rsLUN */ + msg->rsp[3] = msg->data[3]; /* Cmd */ + msg->rsp[4] = IPMI_ERR_UNSPECIFIED; + msg->rsp_size = 5; + } } else if ((msg->data_size >= 2) && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) && (msg->data[1] == IPMI_SEND_MSG_CMD) |