| From foo@baz Sun 01 Mar 2020 10:24:06 AM CET |
| From: Rohit Maheshwari <rohitm@chelsio.com> |
| Date: Wed, 19 Feb 2020 09:40:22 +0530 |
| Subject: net/tls: Fix to avoid gettig invalid tls record |
| |
| From: Rohit Maheshwari <rohitm@chelsio.com> |
| |
| [ Upstream commit 06f5201c6392f998a49ca9c9173e2930c8eb51d8 ] |
| |
| Current code doesn't check if tcp sequence number is starting from (/after) |
| 1st record's start sequnce number. It only checks if seq number is before |
| 1st record's end sequnce number. This problem will always be a possibility |
| in re-transmit case. If a record which belongs to a requested seq number is |
| already deleted, tls_get_record will start looking into list and as per the |
| check it will look if seq number is before the end seq of 1st record, which |
| will always be true and will return 1st record always, it should in fact |
| return NULL. |
| As part of the fix, start looking each record only if the sequence number |
| lies in the list else return NULL. |
| There is one more check added, driver look for the start marker record to |
| handle tcp packets which are before the tls offload start sequence number, |
| hence return 1st record if the record is tls start marker and seq number is |
| before the 1st record's starting sequence number. |
| |
| Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure") |
| Signed-off-by: Rohit Maheshwari <rohitm@chelsio.com> |
| Reviewed-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/tls/tls_device.c | 20 +++++++++++++++++++- |
| 1 file changed, 19 insertions(+), 1 deletion(-) |
| |
| --- a/net/tls/tls_device.c |
| +++ b/net/tls/tls_device.c |
| @@ -592,7 +592,7 @@ struct tls_record_info *tls_get_record(s |
| u32 seq, u64 *p_record_sn) |
| { |
| u64 record_sn = context->hint_record_sn; |
| - struct tls_record_info *info; |
| + struct tls_record_info *info, *last; |
| |
| info = context->retransmit_hint; |
| if (!info || |
| @@ -604,6 +604,24 @@ struct tls_record_info *tls_get_record(s |
| struct tls_record_info, list); |
| if (!info) |
| return NULL; |
| + /* send the start_marker record if seq number is before the |
| + * tls offload start marker sequence number. This record is |
| + * required to handle TCP packets which are before TLS offload |
| + * started. |
| + * And if it's not start marker, look if this seq number |
| + * belongs to the list. |
| + */ |
| + if (likely(!tls_record_is_start_marker(info))) { |
| + /* we have the first record, get the last record to see |
| + * if this seq number belongs to the list. |
| + */ |
| + last = list_last_entry(&context->records_list, |
| + struct tls_record_info, list); |
| + |
| + if (!between(seq, tls_record_start_seq(info), |
| + last->end_seq)) |
| + return NULL; |
| + } |
| record_sn = context->unacked_record_sn; |
| } |
| |