On 08/20/2018 04:13 PM, Willem de Bruijn wrote:
> On Mon, Aug 20, 2018 at 1:47 AM Song Liu <liu.song....@gmail.com> wrote:
>> On Thu, Aug 16, 2018 at 4:14 PM, Petar Penkov <ppen...@google.com> wrote:
>>> On Thu, Aug 16, 2018 at 3:40 PM, Song Liu <liu.song....@gmail.com> wrote:
>>>> On Thu, Aug 16, 2018 at 9:44 AM, Petar Penkov <peterpenko...@gmail.com> 
>>>> wrote:
>>>>> From: Petar Penkov <ppen...@google.com>
>>>>>
>>>>> Adds a hook for programs of type BPF_PROG_TYPE_FLOW_DISSECTOR and
>>>>> attach type BPF_FLOW_DISSECTOR that is executed in the flow dissector
>>>>> path. The BPF program is kept as a global variable so it is
>>>>> accessible to all flow dissectors.
>>>>>
>>>>> Signed-off-by: Petar Penkov <ppen...@google.com>
>>>>> Signed-off-by: Willem de Bruijn <will...@google.com>
> 
>>>>> @@ -658,6 +698,42 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
>>>>>                                               FLOW_DISSECTOR_KEY_BASIC,
>>>>>                                               target_container);
>>>>>
>>>>> +       rcu_read_lock();
>>>>> +       attached = rcu_dereference(flow_dissector_prog);
>>>>> +       if (attached) {
>>>>> +               /* Note that even though the const qualifier is discarded
>>>>> +                * throughout the execution of the BPF program, all 
>>>>> changes(the
>>>>> +                * control block) are reverted after the BPF program 
>>>>> returns.
>>>>> +                * Therefore, __skb_flow_dissect does not alter the skb.
>>>>> +                */
>>>>> +               struct bpf_flow_dissect_cb *cb;
>>>>> +               u8 cb_saved[BPF_SKB_CB_LEN];
>>>>> +               u32 result;
>>>>> +
>>>>> +               cb = (struct bpf_flow_dissect_cb *)(bpf_skb_cb((struct 
>>>>> sk_buff *)skb));
>>>>> +
>>>>> +               /* Save Control Block */
>>>>> +               memcpy(cb_saved, cb, sizeof(cb_saved));
>>>>> +               memset(cb, 0, sizeof(cb_saved));
>>>>> +
>>>>> +               /* Pass parameters to the BPF program */
>>>>> +               cb->nhoff = nhoff;
>>>>> +               cb->target_container = target_container;
>>>>> +               cb->flow_dissector = flow_dissector;
>>>>> +
>>>>> +               bpf_compute_data_pointers((struct sk_buff *)skb);
>>>>> +               result = BPF_PROG_RUN(attached, skb);
>>>>> +
>>>>> +               /* Restore state */
>>>>> +               memcpy(cb, cb_saved, sizeof(cb_saved));
>>>>> +
>>>>> +               key_control->thoff = min_t(u16, key_control->thoff,
>>>>> +                                          skb ? skb->len : hlen);
>>>>> +               rcu_read_unlock();
>>>>> +               return result == BPF_OK;
>>>>> +       }
>>>>
>>>> If the BPF program cannot handle certain protocol, shall we fall back
>>>> to the built-in logic? Otherwise, all BPF programs need to have some
>>>> code for all protocols.
>>>>
>>>> Song
>>>
>>> I believe that if we fall back to the built-in logic we lose all security
>>> guarantees from BPF and this is why the code does not support
>>> fall back.
>>>
>>> Petar
>>
>> I am not really sure we are on the same page. I am proposing 3
>> different return values from BPF_PROG_RUN(), and they should be
>> handled as
>>
>> 1. result == BPF_OK                      => return true;
>> 2. result == BPF_DROP                 => return false;
>> 3. result == something else            => fall back.
>>
>> Does this proposal make any sense?
>>
>> Thanks,
>> Song
> 
> It certainly makes sense. We debated it initially, as well.
> 
> In the short term, it allows for simpler BPF programs, as they can
> off-load some protocols to the C implementation.
> 
> But the RFC patchset already implements most protocols in BPF.
> I had not expected that when we started out.
> 
> Eventually, I think it is preferable to just deprecate the C
> implementation. Which is not possible if we make this opt-out
> a part of the BPF flow dissector interface.

+1

> There is also the lesser issue that a buggy BPF program might
> accidentally pass the third value and unknowing open itself up
> to the large attack surface. Without this option, the security
> audit is much simpler.

Fully agree, I'm all for dropping such option.

Thanks,
Daniel

Reply via email to