From: Josef Bacik <josef@toxicpanda.com>
For SEG6_LOCAL_ACTION_END_B6 and END_B6_ENCAP bpf_lwt_seg6_action() looks
for the SRH again only if bpf_push_seg6_encap() has succeeded. That
function pushes the new header, for which the head of the skb is
reallocated if it has not got the room, and then looks up the route to the
first segment. If there is none, it returns an error, and the pointer to
the SRH in seg6_bpf_srh_states still points into the old head, which has
been freed.
The program goes on behind the error. bpf_lwt_seg6_store_bytes() and
bpf_lwt_seg6_adjust_srh() read the SRH through that pointer.
Look for the SRH whatever bpf_push_seg6_encap() says.
Fixes: 486cdf21583e ("bpf: add End.DT6 action to bpf_lwt_seg6_action helper")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
net/core/filter.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index be792b160e18..bf01152d0cf9 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -7084,8 +7084,8 @@ BPF_CALL_4(bpf_lwt_seg6_action, struct sk_buff *, skb,
return -EBADMSG;
err = bpf_push_seg6_encap(skb, BPF_LWT_ENCAP_SEG6_INLINE,
param, param_len);
- if (!err)
- bpf_update_srh_state(skb);
+ /* The header can be in place although err says otherwise */
+ bpf_update_srh_state(skb);
return err;
case SEG6_LOCAL_ACTION_END_B6_ENCAP:
@@ -7093,8 +7093,8 @@ BPF_CALL_4(bpf_lwt_seg6_action, struct sk_buff *, skb,
return -EBADMSG;
err = bpf_push_seg6_encap(skb, BPF_LWT_ENCAP_SEG6,
param, param_len);
- if (!err)
- bpf_update_srh_state(skb);
+ /* The header can be in place although err says otherwise */
+ bpf_update_srh_state(skb);
return err;
default:
--
2.55.0