Re: Contextually speaking...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2017-05-13 23:36 GMT+02:00 David Miller <davem@xxxxxxxxxxxxx>:
<snip>
> So our example program above needs a little bit of an adjustment to
> make it suitable for BPF_PROG_TYPE_SOCK_FILTER:
>
> SEC("my_program")
> int my_main(struct __sk_buff *skb)
> {
>         void *data_end = (void *)(long)skb->data_end;
>         void *data = (void *)(long)skb->data;
>         struct ethhdr *eth = (struct ethhdr *)(data);
>         int len = skb->len;
>
>         if (eth + 1 > data_end)
>                 return 0;
>         if (eth->h_proto == bpf_htons(ETH_P_IP))
>                 return len;
>         return 0;
> }
>
> So what changed is that we load "len" from the context metadata and
> return "len" when we want to accept the packet.  This says "accept
> the packet and do not truncate it."

This cannot work with BPF_PROG_TYPE_SOCKET_FILTER because skb->data_end
and skb->data cannot be accessed by this BPF_PROG type. The verifier will
reject it with

0: (b7) r0 = 0
1: (61) r2 = *(u32 *)(r1 +80)
invalid bpf_context access off=80 size=4

Reason for that is the function sk_filter_is_valid_access which checks
the access to the __sk_buff context pointer (r1):

static bool sk_filter_is_valid_access(int off, int size,
      enum bpf_access_type type,
      struct bpf_insn_access_aux *info)
{
    switch (off) {
    case bpf_ctx_range(struct __sk_buff, tc_classid):
    case bpf_ctx_range(struct __sk_buff, data):
    case bpf_ctx_range(struct __sk_buff, data_meta):
    case bpf_ctx_range(struct __sk_buff, data_end):
    case bpf_ctx_range_till(struct __sk_buff, family, local_port):
        return false;
    }



[Index of Archives]     [Linux Networking Development]     [Fedora Linux Users]     [Linux SCTP]     [DCCP]     [Gimp]     [Yosemite Campsites]

  Powered by Linux