Skip to content

Commit 2c5dd88

Browse files
Nick Childgregkh
authored andcommitted
ibmvnic: Enforce stronger sanity checks on login response
commit db17ba7 upstream. Ensure that all offsets in a login response buffer are within the size of the allocated response buffer. Any offsets or lengths that surpass the allocation are likely the result of an incomplete response buffer. In these cases, a full reset is necessary. When attempting to login, the ibmvnic device will allocate a response buffer and pass a reference to the VIOS. The VIOS will then send the ibmvnic device a LOGIN_RSP CRQ to signal that the buffer has been filled with data. If the ibmvnic device does not get a response in 20 seconds, the old buffer is freed and a new login request is sent. With 2 outstanding requests, any LOGIN_RSP CRQ's could be for the older login request. If this is the case then the login response buffer (which is for the newer login request) could be incomplete and contain invalid data. Therefore, we must enforce strict sanity checks on the response buffer values. Testing has shown that the `off_rxadd_buff_size` value is filled in last by the VIOS and will be the smoking gun for these circumstances. Until VIOS can implement a mechanism for tracking outstanding response buffers and a method for mapping a LOGIN_RSP CRQ to a particular login response buffer, the best ibmvnic can do in this situation is perform a full reset. Fixes: dff515a ("ibmvnic: Harden device login requests") Signed-off-by: Nick Child <nnac123@linux.ibm.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://lore.kernel.org/r/20230809221038.51296-1-nnac123@linux.ibm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent ad0f73c commit 2c5dd88

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

drivers/net/ethernet/ibm/ibmvnic.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5192,6 +5192,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
51925192
int num_tx_pools;
51935193
int num_rx_pools;
51945194
u64 *size_array;
5195+
u32 rsp_len;
51955196
int i;
51965197

51975198
/* CHECK: Test/set of login_pending does not need to be atomic
@@ -5243,6 +5244,23 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
52435244
ibmvnic_reset(adapter, VNIC_RESET_FATAL);
52445245
return -EIO;
52455246
}
5247+
5248+
rsp_len = be32_to_cpu(login_rsp->len);
5249+
if (be32_to_cpu(login->login_rsp_len) < rsp_len ||
5250+
rsp_len <= be32_to_cpu(login_rsp->off_txsubm_subcrqs) ||
5251+
rsp_len <= be32_to_cpu(login_rsp->off_rxadd_subcrqs) ||
5252+
rsp_len <= be32_to_cpu(login_rsp->off_rxadd_buff_size) ||
5253+
rsp_len <= be32_to_cpu(login_rsp->off_supp_tx_desc)) {
5254+
/* This can happen if a login request times out and there are
5255+
* 2 outstanding login requests sent, the LOGIN_RSP crq
5256+
* could have been for the older login request. So we are
5257+
* parsing the newer response buffer which may be incomplete
5258+
*/
5259+
dev_err(dev, "FATAL: Login rsp offsets/lengths invalid\n");
5260+
ibmvnic_reset(adapter, VNIC_RESET_FATAL);
5261+
return -EIO;
5262+
}
5263+
52465264
size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
52475265
be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size));
52485266
/* variable buffer sizes are not supported, so just read the

0 commit comments

Comments
 (0)