Re: [PATCH bpf-next v4 3/4] bpf: Add kfuncs for read-only string operations

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

 



On 5/8/25 11:41, Matt Bobrowski wrote:
> On Wed, May 07, 2025 at 08:40:38AM +0200, Viktor Malik wrote:
>> String operations are commonly used so this exposes the most common ones
>> to BPF programs. For now, we limit ourselves to operations which do not
>> copy memory around.
>>
>> Unfortunately, most in-kernel implementations assume that strings are
>> %NUL-terminated, which is not necessarily true, and therefore we cannot
>> use them directly in the BPF context. Instead, we open-code them using
>> __get_kernel_nofault instead of plain dereference to make them safe and
>> limit the strings length to XATTR_SIZE_MAX to make sure the functions
>> terminate. When __get_kernel_nofault fails, functions return -EFAULT.
>> Similarly, when the size bound is reached, the functions return -E2BIG.
> 
> Curious, why was XATTR_SIZE_MAX chosen as the upper bounds here? Just
> an arbitrary value that felt large enough?

Yes, exactly that.

> 
>> At the moment, strings can be passed to the kfuncs in three forms:
>> - string literals (i.e. pointers to read-only maps)
>> - global variables (i.e. pointers to read-write maps)
>> - stack-allocated buffers
>>
>> Note that currently, it is not possible to pass strings from the BPF
>> program context (like function args) as the verifier doesn't treat them
>> as neither PTR_TO_MEM nor PTR_TO_BTF_ID.
>>
>> Suggested-by: Alexei Starovoitov <ast@xxxxxxxxxx>
>> Signed-off-by: Viktor Malik <vmalik@xxxxxxxxxx>
>> ---
>>  kernel/bpf/helpers.c | 440 +++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 440 insertions(+)
>>
>> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
>> index e3a2662f4e33..8fb7c2ca7ac0 100644
>> --- a/kernel/bpf/helpers.c
>> +++ b/kernel/bpf/helpers.c
>> @@ -23,6 +23,7 @@
>>  #include <linux/btf_ids.h>
>>  #include <linux/bpf_mem_alloc.h>
>>  #include <linux/kasan.h>
>> +#include <linux/uaccess.h>
>>  
>>  #include "../../lib/kstrtox.h"
>>  
>> @@ -3194,6 +3195,433 @@ __bpf_kfunc void bpf_local_irq_restore(unsigned long *flags__irq_flag)
>>  	local_irq_restore(*flags__irq_flag);
>>  }
>>  
>> +/* Kfuncs for string operations.
>> + *
>> + * Since strings are not necessarily %NUL-terminated, we cannot directly call
>> + * in-kernel implementations. Instead, we open-code the implementations using
>> + * __get_kernel_nofault instead of plain dereference to make them safe.
>> + */
> 
> Returning an -EFAULT error code for supplied arguments which are
> deemed to be invalid is just a very weird semantic IMO. As a BPF
> program author, I totally wouldn't expect a BPF kfunc to return
> -EINVAL if I had supplied it something that it couldn't quite possibly
> handle to begin with. Look at the prior art, being pre-existing BPF
> kfuncs, and you'll see how they handle invalidly supplied arguments. I
> totally understand that attempting to dereference a NULL-pointer would
> ultimately result in a fault being raised, so it may feel rather
> natural to also report an -EFAULT error code upon doing some
> NULL-pointer checks that hold true, but from an API usability POV it
> just seems awkward and wrong.
> 
> Another thing that I noticed was that none of these BPF kfunc
> arguments make use of the parameter suffixes i.e. __str, __sz. Why is
> that exactly? Will leaning on those break you in some way?

The reason is that they both require literal values to be passed which
is a limitation that we don't want in these APIs.

Viktor





[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