Subject: Re: [PATCH net-next v2 2/2] bpf: Remove the capability check for cgroup skb eBPF program

From: Daniel Borkmann <[email-masked]>
Date: Wed, 07 Jun 2017 17:57:50 +0200

On 06/07/2017 12:44 AM, Chenbo Feng wrote:
> On 06/06/2017 09:56 AM, Daniel Borkmann wrote:
>> On 06/02/2017 01:42 AM, Alexei Starovoitov wrote:
>>> On Wed, May 31, 2017 at 06:16:00PM -0700, Chenbo Feng wrote:
>>>> From: Chenbo Feng <[email-masked]>
>>>>
>>>> Currently loading a cgroup skb eBPF program require a CAP_SYS_ADMIN
>>>> capability while attaching the program to a cgroup only requires the
>>>> user have CAP_NET_ADMIN privilege. We can escape the capability
>>>> check when load the program just like socket filter program to make
>>>> the capability requirement consistent.
>>>>
>>>> Change since v1:
>>>> Change the code style in order to be compliant with checkpatch.pl
>>>> preference
>>>>
>>>> Signed-off-by: Chenbo Feng <[email-masked]>
>>>
>>> as far as I can see they're indeed the same as socket filters, so
>>> Acked-by: Alexei Starovoitov <[email-masked]>
>>>
>>> but I don't quite understand how it helps, since as you said
>>> attaching such unpriv fd to cgroup still requires root.
>>> Do you have more patches to follow?
>>
>> Hmm, when we relax this from capable(CAP_SYS_ADMIN) to unprivileged,
>> then we must at least also zero out the not-yet-initialized memory
>> for the mac header for egress case in __cgroup_bpf_run_filter_skb().
>
> Do you mean something like:
>
> if (type == BPF_CGROUP_INET_EGRESS) {
>
>          offset = skb_network_header(skb) - skb_mac_header(skb);
>
>          memset(skb_mac_header(skb), 0, offset)

That won't work, reason is the same as per 92046578ac88 ("bpf: cgroup
skb progs cannot access ld_abs/ind"), meaning that mac header is not
yet set at that point in time, but more below.

> }
>
> And could you explain more on why we need to do this if we remove the
 > CAP_SYS_ADMIN check? I thought we still cannot directly access the
 > sk_buff without using bpf_skb_load_bytes helper and we still need a
 > CAP_NET_ADMIN in order to attach and run the program on egress side right?

Ok, forget this comment of mine. The __cgroup_bpf_run_filter_skb() does
__skb_push()/__skb_pull(), but for egress case the offset is always 0, so
we don't start at mac header but at network header instead, meaning memset()
is not needed.

Thanks,
Daniel