mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
bpf: Make bpf_skb_adjust_room metadata-safe
bpf_skb_adjust_room() may push or pull bytes from skb->data. In both cases, skb metadata must be moved accordingly to stay accessible. Replace existing memmove() calls, which only move payload, with a helper that also handles metadata. Reserve enough space for metadata to fit after skb_push. Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com> Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Link: https://patch.msgid.link/20251105-skb-meta-rx-path-v4-7-5ceb08a9b37b@cloudflare.com
This commit is contained in:
committed by
Martin KaFai Lau
parent
55ffc98b44
commit
be83105d38
@@ -3253,11 +3253,11 @@ static void bpf_skb_change_protocol(struct sk_buff *skb, u16 proto)
|
|||||||
|
|
||||||
static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
|
static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
|
||||||
{
|
{
|
||||||
/* Caller already did skb_cow() with len as headroom,
|
/* Caller already did skb_cow() with meta_len+len as headroom,
|
||||||
* so no need to do it here.
|
* so no need to do it here.
|
||||||
*/
|
*/
|
||||||
skb_push(skb, len);
|
skb_push(skb, len);
|
||||||
memmove(skb->data, skb->data + len, off);
|
skb_postpush_data_move(skb, len, off);
|
||||||
memset(skb->data + off, 0, len);
|
memset(skb->data + off, 0, len);
|
||||||
|
|
||||||
/* No skb_postpush_rcsum(skb, skb->data + off, len)
|
/* No skb_postpush_rcsum(skb, skb->data + off, len)
|
||||||
@@ -3281,7 +3281,7 @@ static int bpf_skb_generic_pop(struct sk_buff *skb, u32 off, u32 len)
|
|||||||
old_data = skb->data;
|
old_data = skb->data;
|
||||||
__skb_pull(skb, len);
|
__skb_pull(skb, len);
|
||||||
skb_postpull_rcsum(skb, old_data + off, len);
|
skb_postpull_rcsum(skb, old_data + off, len);
|
||||||
memmove(skb->data, old_data, off);
|
skb_postpull_data_move(skb, len, off);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -3489,6 +3489,7 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff,
|
|||||||
u8 inner_mac_len = flags >> BPF_ADJ_ROOM_ENCAP_L2_SHIFT;
|
u8 inner_mac_len = flags >> BPF_ADJ_ROOM_ENCAP_L2_SHIFT;
|
||||||
bool encap = flags & BPF_F_ADJ_ROOM_ENCAP_L3_MASK;
|
bool encap = flags & BPF_F_ADJ_ROOM_ENCAP_L3_MASK;
|
||||||
u16 mac_len = 0, inner_net = 0, inner_trans = 0;
|
u16 mac_len = 0, inner_net = 0, inner_trans = 0;
|
||||||
|
const u8 meta_len = skb_metadata_len(skb);
|
||||||
unsigned int gso_type = SKB_GSO_DODGY;
|
unsigned int gso_type = SKB_GSO_DODGY;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -3499,7 +3500,7 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff,
|
|||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = skb_cow_head(skb, len_diff);
|
ret = skb_cow_head(skb, meta_len + len_diff);
|
||||||
if (unlikely(ret < 0))
|
if (unlikely(ret < 0))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user