Question about possible misuse checksum in tcf_csum_ipv6_icmp()
Subsystems (2)
Dear TC subsystem maintainers,
We are curious whether the function tcf_csum_ipv6_icmp() would have a misuse of csum_partial() leading to an out-of-bounds access.
The function tcf_csum_ipv6_icmp is https://elixir.bootlin.com/linux/v6.8/source/net/sched/act_csum.c#L183 and the relevant code is
```
static int tcf_csum_ipv6_icmp(struct sk_buff *skb, unsigned int ihl,
unsigned int ipl)
{
...
ip6h = ipv6_hdr(skb);
icmp6h->icmp6_cksum = 0;
skb->csum = csum_partial(icmp6h, ipl - ihl, 0);
icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
ipl - ihl, IPPROTO_ICMPV6,
skb->csum);
...
}
```Based on this patch: https://lore.kernel.org/netdev/[email protected]/T/, it seems that the skb here for ICMPv6 could be non-linear, and csum_partial is not suitable for non-linear SKBs, which could lead to an out-of-bound access. The correct approach is to use skb_checksum which properly handles non-linear SKBs.
Based on the above information, a possible fix would be
``` - skb->csum = csum_partial(icmp6h, ipl - ihl, 0); + skb->csum = skb_checksum(skb, skb_transport_offset(skb), ipl - ihl, 0); ```
Please kindly correct us if we missed any key information. Looking forward to your response!
Best,
Chenyuan
Quoted 27 lines · Chenyuan Yang
Dear TC subsystem maintainers,
We are curious whether the function
tcf_csum_ipv6_icmp()would have a misuse ofcsum_partial()leading to an out-of-bounds access.The function
tcf_csum_ipv6_icmpis https://elixir.bootlin.com/linux/v6.8/source/net/sched/act_csum.c#L183 and the relevant code is``` static int tcf_csum_ipv6_icmp(struct sk_buff *skb, unsigned int ihl, unsigned int ipl) { ... ip6h = ipv6_hdr(skb); icmp6h->icmp6_cksum = 0; skb->csum = csum_partial(icmp6h, ipl - ihl, 0); icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, ipl - ihl, IPPROTO_ICMPV6, skb->csum); ... } ```Based on this patch: https://lore.kernel.org/netdev/[email protected]/T/, it seems that the
skbhere for ICMPv6 could be non-linear, andcsum_partialis not suitable for non-linear SKBs, which could lead to an out-of-bound access. The correct approach is to useskb_checksumwhich properly handles non-linear SKBs.Based on the above information, a possible fix would be ```
(quoted diff) +1
-1- skb->csum = csum_partial(icmp6h, ipl - ihl, 0); + skb->csum = skb_checksum(skb, skb_transport_offset(skb), ipl - ihl, 0);
Quoted 1 line
```
Why would this code be an issue only in tcf_csum_ipv6_icmp(), and not in other functions ?
It seems we have proper pskb_may_pull() calls.
If you have a syzbot/syzkaller trace, please share it.
Thank you very much for your swift response.
Quoted 1 line
It seems we have proper
pskb_may_pull()calls.
I realized that I had overlooked verifying the suitability of the SKB in this context. Your observation is indeed correct, and I now understand that this should not present any concerns.
Thank you once again for your valuable feedback.
Best,
Chenyuan
Quoted 37 lines · Eric Dumazet
Quoted 27 lines · Chenyuan Yang
Dear TC subsystem maintainers,
We are curious whether the function
tcf_csum_ipv6_icmp()would have a misuse ofcsum_partial()leading to an out-of-bounds access.The function
tcf_csum_ipv6_icmpis https://elixir.bootlin.com/linux/v6.8/source/net/sched/act_csum.c#L183 and the relevant code is``` static int tcf_csum_ipv6_icmp(struct sk_buff *skb, unsigned int ihl, unsigned int ipl) { ... ip6h = ipv6_hdr(skb); icmp6h->icmp6_cksum = 0; skb->csum = csum_partial(icmp6h, ipl - ihl, 0); icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, ipl - ihl, IPPROTO_ICMPV6, skb->csum); ... } ```Based on this patch: https://lore.kernel.org/netdev/[email protected]/T/, it seems that the
skbhere for ICMPv6 could be non-linear, andcsum_partialis not suitable for non-linear SKBs, which could lead to an out-of-bound access. The correct approach is to useskb_checksumwhich properly handles non-linear SKBs.Based on the above information, a possible fix would be ```
(quoted diff) +1
-1- skb->csum = csum_partial(icmp6h, ipl - ihl, 0); + skb->csum = skb_checksum(skb, skb_transport_offset(skb), ipl - ihl, 0);Quoted 1 line
```
Why would this code be an issue only in
tcf_csum_ipv6_icmp(), and not in other functions ?It seems we have proper
pskb_may_pull()calls.If you have a syzbot/syzkaller trace, please share it.