On Mon, Oct 11, 2021 at 09:16 PM CEST, John Fastabend wrote: > From: Jussi Maki <joamaki@xxxxxxxxx> > > The current conversion of skb->data_end reads like this, > > ; data_end = (void*)(long)skb->data_end; > 559: (79) r1 = *(u64 *)(r2 +200) ; r1 = skb->data > 560: (61) r11 = *(u32 *)(r2 +112) ; r11 = skb->len > 561: (0f) r1 += r11 > 562: (61) r11 = *(u32 *)(r2 +116) > 563: (1f) r1 -= r11 > > But similar to the case > > ("bpf: sock_ops sk access may stomp registers when dst_reg = src_reg"), > > the code will read an incorrect skb->len when src == dst. In this case we > end up generating this xlated code. > > ; data_end = (void*)(long)skb->data_end; > 559: (79) r1 = *(u64 *)(r1 +200) ; r1 = skb->data > 560: (61) r11 = *(u32 *)(r1 +112) ; r11 = (skb->data)->len > 561: (0f) r1 += r11 > 562: (61) r11 = *(u32 *)(r1 +116) > 563: (1f) r1 -= r11 > > where line 560 is the reading 4B of (skb->data + 112) instead of the > intended skb->len Here the skb pointer in r1 gets set to skb->data and > the later deref for skb->len ends up following skb->data instead of skb. > > This fixes the issue similarly to the patch mentioned above by creating > an additional temporary variable and using to store the register when > dst_reg = src_reg. We name the variable bpf_temp_reg and place it in the > cb context for sk_skb. Then we restore from the temp to ensure nothing > is lost. > > Fixes: 16137b09a66f2 ("bpf: Compute data_end dynamically with JIT code") > Signed-off-by: Jussi Maki <joamaki@xxxxxxxxx> > Signed-off-by: John Fastabend <john.fastabend@xxxxxxxxx> > --- Reviewed-by: Jakub Sitnicki <jakub@xxxxxxxxxxxxxx>