|
@@ -4452,14 +4452,16 @@ EXPORT_SYMBOL_GPL(skb_complete_wifi_ack);
|
|
|
*/
|
|
|
bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off)
|
|
|
{
|
|
|
- if (unlikely(start > skb_headlen(skb)) ||
|
|
|
- unlikely((int)start + off > skb_headlen(skb) - 2)) {
|
|
|
- net_warn_ratelimited("bad partial csum: csum=%u/%u len=%u\n",
|
|
|
- start, off, skb_headlen(skb));
|
|
|
+ u32 csum_end = (u32)start + (u32)off + sizeof(__sum16);
|
|
|
+ u32 csum_start = skb_headroom(skb) + (u32)start;
|
|
|
+
|
|
|
+ if (unlikely(csum_start > U16_MAX || csum_end > skb_headlen(skb))) {
|
|
|
+ net_warn_ratelimited("bad partial csum: csum=%u/%u headroom=%u headlen=%u\n",
|
|
|
+ start, off, skb_headroom(skb), skb_headlen(skb));
|
|
|
return false;
|
|
|
}
|
|
|
skb->ip_summed = CHECKSUM_PARTIAL;
|
|
|
- skb->csum_start = skb_headroom(skb) + start;
|
|
|
+ skb->csum_start = csum_start;
|
|
|
skb->csum_offset = off;
|
|
|
skb_set_transport_header(skb, start);
|
|
|
return true;
|