Skip to content

Commit

Permalink
ipmi:ssif: Fix handling of multi-part return messages
Browse files Browse the repository at this point in the history
The block number was not being compared right, it was off by one
when checking the response.

Some statistics wouldn't be incremented properly in some cases.

Check to see if that middle-part messages always have 31 bytes of
data.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: stable@vger.kernel.org # 4.4
  • Loading branch information
Corey Minyard committed Jan 23, 2019
1 parent 7b55851 commit 7d6380c
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions drivers/char/ipmi/ipmi_ssif.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,

/* Remove the multi-part read marker. */
len -= 2;
data += 2;
for (i = 0; i < len; i++)
ssif_info->data[i] = data[i+2];
ssif_info->data[i] = data[i];
ssif_info->multi_len = len;
ssif_info->multi_pos = 1;

Expand Down Expand Up @@ -661,8 +662,19 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
}

blocknum = data[0];
len--;
data++;

if (blocknum != 0xff && len != 31) {
/* All blocks but the last must have 31 data bytes. */
result = -EIO;
if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
pr_info("Received middle message <31\n");

if (ssif_info->multi_len + len - 1 > IPMI_MAX_MSG_LENGTH) {
goto continue_op;
}

if (ssif_info->multi_len + len > IPMI_MAX_MSG_LENGTH) {
/* Received message too big, abort the operation. */
result = -E2BIG;
if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
Expand All @@ -671,16 +683,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
goto continue_op;
}

/* Remove the blocknum from the data. */
len--;
for (i = 0; i < len; i++)
ssif_info->data[i + ssif_info->multi_len] = data[i + 1];
ssif_info->data[i + ssif_info->multi_len] = data[i];
ssif_info->multi_len += len;
if (blocknum == 0xff) {
/* End of read */
len = ssif_info->multi_len;
data = ssif_info->data;
} else if (blocknum + 1 != ssif_info->multi_pos) {
} else if (blocknum != ssif_info->multi_pos) {
/*
* Out of sequence block, just abort. Block
* numbers start at zero for the second block,
Expand All @@ -707,15 +717,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
}
}

continue_op:
if (result < 0) {
ssif_inc_stat(ssif_info, receive_errors);
} else {
ssif_inc_stat(ssif_info, received_messages);
ssif_inc_stat(ssif_info, received_message_parts);
}


continue_op:
if (ssif_info->ssif_debug & SSIF_DEBUG_STATE)
pr_info("DONE 1: state = %d, result=%d\n",
ssif_info->ssif_state, result);
Expand Down

0 comments on commit 7d6380c

Please sign in to comment.