Re: [RFC PATCH bpf-next RESEND 03/16] bpf: Improve bpf kfuncs pointer arguments chain of trust

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

 



On Thu, 11 Jul 2024 at 13:26, Juntong Deng <juntong.deng@xxxxxxxxxxx> wrote:
>
> Currently we have only three ways to get valid pointers:
>
> 1. Pointers which are passed as tracepoint or struct_ops
> callback arguments.
>
> 2. Pointers which were returned from a KF_ACQUIRE kfunc.
>
> 3. Guaranteed valid nested pointers (e.g. using the
> BTF_TYPE_SAFE_TRUSTED macro)
>
> But this does not cover all cases and we cannot get valid
> pointers to some objects, causing the chain of trust to be
> broken (we cannot get a valid object pointer from another
> valid object pointer).
>
> The following are some examples of cases that are not covered:
>
> 1. struct socket
> There is no reference counting in a struct socket, the reference
> counting is actually in the struct file, so it does not make sense
> to use a combination of KF_ACQUIRE and KF_RELEASE to trick the
> verifier to make the pointer to struct socket valid.

Yes, but the KF_OBTAIN like flag also needs to ensure that lifetime
relationships are reflected in the verifier state.
If we return a trusted pointer A using bpf_sock_from_file, but
argument B it takes is later released, the verifier needs to ensure
that the pointer A whose lifetime belongs to that pointer B also gets
scrubbed.

>
> 2. sk_write_queue in struct sock
> sk_write_queue is a struct member in struct sock, not a pointer
> member, so we cannot use the guaranteed valid nested pointer method
> to get a valid pointer to sk_write_queue.

I think Matt recently had a patch addressing this issue:
https://lore.kernel.org/bpf/20240709210939.1544011-1-mattbobrowski@xxxxxxxxxx/
I believe that should resolve this one (as far as passing them into
KF_TRUSTED_ARGS kfuncs is concerned atleast).

>
> 3. The pointer returned by iterator next method
> Currently we cannot pass the pointer returned by the iterator next
> method as argument to the KF_TRUSTED_ARGS kfuncs, because the pointer
> returned by the iterator next method is not "valid".

This does sound ok though.

>
> This patch adds the KF_OBTAIN flag to solve examples 1 and 2, for cases
> where a valid pointer can be obtained without manipulating the reference
> count. For KF_OBTAIN kfuncs, the arguments must be valid pointers.
> KF_OBTAIN kfuncs guarantees that if the passed pointer argument is valid,
> then the pointer returned by KF_OBTAIN kfuncs is also valid.
>
> For example, bpf_socket_from_file() is KF_OBTAIN, and if the struct file
> pointer passed in is valid (KF_ACQUIRE), then the struct socket pointer
> returned is also valid. Another example, bpf_receive_queue_from_sock() is
> KF_OBTAIN, and if the struct sock pointer passed in is valid, then the
> sk_receive_queue pointer returned is also valid.
>
> In addition, this patch sets the pointer returned by the iterator next
> method to be valid. This is based on the fact that if the iterator is
> implemented correctly, then the pointer returned from the iterator next
> method should be valid. This does not make the NULL pointer valid.
> If the iterator next method has the KF_RET_NULL flag, then the verifier
> will ask the ebpf program to check the NULL pointer.
>
> Signed-off-by: Juntong Deng <juntong.deng@xxxxxxxxxxx>
> ---

I think you should look at bpf_tcp_sock helper (and others), which
converts struct bpf_sock to bpf_tcp_sock. It also transfers the
ref_obj_id into the return value to ensure ownership is reflected
correctly regardless of the type. That pattern has a specific name
(is_ptr_cast_function), but idk what to call this.




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux