mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
ip6mr: clear skb->cb[] in reg_vif_xmit()
reg_vif_xmit() hands the skb to ip6mr_cache_report() as an MRT6MSG_WHOLEPKT report. skb_realloc_headroom() copies skb->cb[] into the report, which is queued to the mroute socket, where rawv6_recvmsg() reads it as IP6CB. By the time the pim6reg device transmits the packet, skb->cb[] is not IP6CB anymore: qdisc_pkt_len_init() overwrites iif and ra, and any qdisc installed on the device (fq, fq_codel, pie, cake...) or a tc BPF program writing skb->cb[] fills the area holding dst0, srcrt, dst1, lastopt and flags. Since commitdd433671fe("ipv6: validate extension header length before copying to cmsg") these stale offsets can no longer cause out-of-bounds reads, but the mroute socket can still receive bogus IPV6_PKTINFO ifindex and extension header ancillary data. Clear IP6CB before building the report. The skb is freed right after, so nothing else depends on its control block. Fixes:14fb64e1f4("[IPV6] MROUTE: Support PIM-SM (SSM).") Signed-off-by: Eric Dumazet <edumazet@kernel.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
17271848c9
commit
2381642014
|
|
@ -653,6 +653,12 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
|
||||||
DEV_STATS_ADD(dev, tx_bytes, skb->len);
|
DEV_STATS_ADD(dev, tx_bytes, skb->len);
|
||||||
DEV_STATS_INC(dev, tx_packets);
|
DEV_STATS_INC(dev, tx_packets);
|
||||||
|
|
||||||
|
/* skb->cb[] holds qdisc/tc state at this point, not IP6CB.
|
||||||
|
* ip6mr_cache_report() copies it to the report delivered to
|
||||||
|
* the mroute socket, where it is read as IP6CB.
|
||||||
|
*/
|
||||||
|
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
|
||||||
|
|
||||||
ip6mr_cache_report(mrt, skb, READ_ONCE(mrt->mroute_reg_vif_num),
|
ip6mr_cache_report(mrt, skb, READ_ONCE(mrt->mroute_reg_vif_num),
|
||||||
MRT6MSG_WHOLEPKT);
|
MRT6MSG_WHOLEPKT);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user