]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ipmi: fix IPMI_SMI_MSG_TYPE_IPMB_DIRECT response length checking
authorCorey Minyard <cminyard@mvista.com>
Thu, 25 Nov 2021 14:47:27 +0000 (08:47 -0600)
committerCorey Minyard <cminyard@mvista.com>
Fri, 26 Nov 2021 03:17:55 +0000 (21:17 -0600)
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>
drivers/char/ipmi/ipmi_msghandler.c

index 7d7df17d8b3d13bb4fee00e46574361111f904df..99ea6d9b3716dd5be117655e69f95b947d76a952 100644 (file)
@@ -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)