Skip to content

Commit c29390c

Browse files
edumazetdavem330
authored andcommitted
xps: must clear sender_cpu before forwarding
John reported that my previous commit added a regression on his router. This is because sender_cpu & napi_id share a common location, so get_xps_queue() can see garbage and perform an out of bound access. We need to make sure sender_cpu is cleared before doing the transmit, otherwise any NIC busy poll enabled (skb_mark_napi_id()) can trigger this bug. Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: John <jw@nuclearfallout.net> Bisected-by: John <jw@nuclearfallout.net> Fixes: 2bd8248 ("xps: fix xps for stacked devices") Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent c8a4d29 commit c29390c

File tree

4 files changed

+10
-1
lines changed

4 files changed

+10
-1
lines changed

include/linux/skbuff.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,13 @@ static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from)
948948
to->l4_hash = from->l4_hash;
949949
};
950950

951+
static inline void skb_sender_cpu_clear(struct sk_buff *skb)
952+
{
953+
#ifdef CONFIG_XPS
954+
skb->sender_cpu = 0;
955+
#endif
956+
}
957+
951958
#ifdef NET_SKBUFF_DATA_USES_OFFSET
952959
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
953960
{

net/core/skbuff.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4173,7 +4173,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
41734173
skb->ignore_df = 0;
41744174
skb_dst_drop(skb);
41754175
skb->mark = 0;
4176-
skb->sender_cpu = 0;
4176+
skb_sender_cpu_clear(skb);
41774177
skb_init_secmark(skb);
41784178
secpath_reset(skb);
41794179
nf_reset(skb);

net/ipv4/ip_forward.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static int ip_forward_finish(struct sk_buff *skb)
6767
if (unlikely(opt->optlen))
6868
ip_forward_options(skb);
6969

70+
skb_sender_cpu_clear(skb);
7071
return dst_output(skb);
7172
}
7273

net/ipv6/ip6_output.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ static int ip6_forward_proxy_check(struct sk_buff *skb)
318318

319319
static inline int ip6_forward_finish(struct sk_buff *skb)
320320
{
321+
skb_sender_cpu_clear(skb);
321322
return dst_output(skb);
322323
}
323324

0 commit comments

Comments
 (0)