net: qrtr: Update data_len when padding large skbs

When the skb is greater than 16kb and needs to by padded, qrtr attempts
to manually pad the trailing bytes to be zeroed out and word aligned.

The padding of the page was happening correctly, but the bookkeeping on
the skb was not accurate. When skb->len was updated to account for the
new padding but skb->data_len was not, this made all skb functions
think the linear portion (skb->len - skb_data_len) was longer than it
actually was. This caused a pattern where skb_copy_bits() would copy
out of bounds on the linear section and shift the trailing bits into
the padded section.

Before padding without updating data_len.
 [  104.825620] qrtr: 00003e80: 66 d3 a0 e1 b6 04 e4 43 b7 aa f0 40 fb eb 38 dc
 [  104.825622] qrtr: 00003e90: f1 91 85 e5 17 26 2a a2 11 49 bc cc bd f3 d3 23
 [  104.825624] qrtr: 00003ea0: c6.

Adter padding without updating data_len.
 [  104.860041] qrtr: 00003e80: 66 d3 a0 e1 b6 04 e4 43 b7 aa f0 40 fb eb 38 dc
 [  104.860042] qrtr: 00003e90: f1 91 85 e5 17 26 2a a2 11 49 bc cc bd 00 00 00
 [  104.860043] qrtr: 00003ea0: f3 d3 23 c6.

Change-Id: I6c1c944ecf696360ada263046b0e0af1bfdeb505
Signed-off-by: Chris Lew <quic_clew@quicinc.com>
This commit is contained in:
Chris Lew 2022-07-06 20:46:02 -07:00
parent ecaafddf5e
commit 482c42cf37

View File

@ -688,6 +688,7 @@ static int qrtr_pad_word_pskb(struct sk_buff *skb)
kunmap_atomic(vaddr);
count += d_off + padding_len;
skb->len = padto;
skb->data_len += padding_len;
break;
}
} else {
@ -711,6 +712,7 @@ static int qrtr_pad_word_pskb(struct sk_buff *skb)
count += p_len;
padding_len -= d_len;
skb->len += d_len;
skb->data_len += padding_len;
continue;
}
@ -720,6 +722,7 @@ static int qrtr_pad_word_pskb(struct sk_buff *skb)
kunmap_atomic(vaddr);
count += d_off + padding_len;
skb->len += padding_len;
skb->data_len += padding_len;
}
}