diff mbox series

[bpf,5/7] bpf: Change the type of unsafe_ptr in bpf_iter_bits_new()

Message ID 20241008091718.3797027-6-houtao@huaweicloud.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series Misc fixes for bpf | expand

Checks

Context Check Description
bpf/vmtest-bpf-PR success PR summary
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf, async
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 13 of 13 maintainers
netdev/build_clang success Errors and warnings before: 7 this patch: 7
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 61 this patch: 61
netdev/checkpatch warning WARNING: line length of 95 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 10 this patch: 10
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-7 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-8 success Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-VM_Test-16 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-VM_Test-17 success Logs for set-matrix
bpf/vmtest-bpf-VM_Test-19 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-VM_Test-15 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-VM_Test-18 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-VM_Test-27 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-28 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-VM_Test-33 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-VM_Test-35 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-VM_Test-34 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-41 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-VM_Test-13 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-VM_Test-14 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-20 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-21 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-22 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-25 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-26 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-29 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-VM_Test-36 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18

Commit Message

Hou Tao Oct. 8, 2024, 9:17 a.m. UTC
From: Hou Tao <houtao1@huawei.com>

Under 32-bits host (e.g, arm32) , when a bpf program passes an u64 to
bpf_iter_bits_new(), bpf_iter_bits_new() will use bits_copy to save the
content of the u64, but the size of bits_copy is only 4-bytes, and there
will be stack corruption.

Fix it by change the type of unsafe_ptr from u64 * to unsigned long *.

Signed-off-by: Hou Tao <houtao1@huawei.com>
---
 kernel/bpf/helpers.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

Comments

Andrii Nakryiko Oct. 8, 2024, 6:30 p.m. UTC | #1
On Tue, Oct 8, 2024 at 2:05 AM Hou Tao <houtao@huaweicloud.com> wrote:
>
> From: Hou Tao <houtao1@huawei.com>
>
> Under 32-bits host (e.g, arm32) , when a bpf program passes an u64 to
> bpf_iter_bits_new(), bpf_iter_bits_new() will use bits_copy to save the
> content of the u64, but the size of bits_copy is only 4-bytes, and there
> will be stack corruption.
>
> Fix it by change the type of unsafe_ptr from u64 * to unsigned long *.
>

This will be confusing as BPF-side long is always 64-bit. So why not
instead make sure it's u64 throughout (i.e., bits_copy is u64
explicitly), even on 32-bit architectures?

> Signed-off-by: Hou Tao <houtao1@huawei.com>
> ---
>  kernel/bpf/helpers.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)
>
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 6c0205d5018c..dee69c3904a0 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
> @@ -2852,7 +2852,7 @@ struct bpf_iter_bits {
>  } __aligned(8);
>
>  /* nr_bits only has 31 bits */
> -#define BITS_ITER_NR_WORDS_MAX ((1U << 31) / BITS_PER_TYPE(u64))
> +#define BITS_ITER_NR_WORDS_MAX ((1U << 31) / BITS_PER_TYPE(unsigned long))
>
>  struct bpf_iter_bits_kern {
>         union {
> @@ -2868,8 +2868,9 @@ struct bpf_iter_bits_kern {
>   * bpf_iter_bits_new() - Initialize a new bits iterator for a given memory area
>   * @it: The new bpf_iter_bits to be created
>   * @unsafe_ptr__ign: A pointer pointing to a memory area to be iterated over
> - * @nr_words: The size of the specified memory area, measured in 8-byte units.
> - * Due to the limitation of memalloc, it can't be greater than 512.
> + * @nr_words: The size of the specified memory area, measured in units of
> + * sizeof(unsigned long). Due to the limitation of memalloc, it can't be
> + * greater than 512.
>   *
>   * This function initializes a new bpf_iter_bits structure for iterating over
>   * a memory area which is specified by the @unsafe_ptr__ign and @nr_words. It
> @@ -2879,17 +2880,18 @@ struct bpf_iter_bits_kern {
>   * On success, 0 is returned. On failure, ERR is returned.
>   */
>  __bpf_kfunc int
> -bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_words)
> +bpf_iter_bits_new(struct bpf_iter_bits *it, const unsigned long *unsafe_ptr__ign, u32 nr_words)
>  {
> -       struct bpf_iter_bits_kern *kit = (void *)it;
> -       u32 nr_bytes = nr_words * sizeof(u64);
> +       u32 nr_bytes = nr_words * sizeof(*unsafe_ptr__ign);
>         u32 nr_bits = BYTES_TO_BITS(nr_bytes);
> +       struct bpf_iter_bits_kern *kit;
>         int err;
>
>         BUILD_BUG_ON(sizeof(struct bpf_iter_bits_kern) != sizeof(struct bpf_iter_bits));
>         BUILD_BUG_ON(__alignof__(struct bpf_iter_bits_kern) !=
>                      __alignof__(struct bpf_iter_bits));
>
> +       kit = (void *)it;
>         kit->allocated = 0;
>         kit->nr_bits = 0;
>         kit->bits_copy = 0;
> @@ -2900,8 +2902,8 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
>         if (nr_words > BITS_ITER_NR_WORDS_MAX)
>                 return -E2BIG;
>
> -       /* Optimization for u64 mask */
> -       if (nr_bits == 64) {
> +       /* Optimization for unsigned long mask */
> +       if (nr_words == 1) {
>                 err = bpf_probe_read_kernel_common(&kit->bits_copy, nr_bytes, unsafe_ptr__ign);
>                 if (err)
>                         return -EFAULT;
> --
> 2.29.2
>
Hou Tao Oct. 9, 2024, 2:45 a.m. UTC | #2
On 10/9/2024 2:30 AM, Andrii Nakryiko wrote:
> On Tue, Oct 8, 2024 at 2:05 AM Hou Tao <houtao@huaweicloud.com> wrote:
>> From: Hou Tao <houtao1@huawei.com>
>>
>> Under 32-bits host (e.g, arm32) , when a bpf program passes an u64 to
>> bpf_iter_bits_new(), bpf_iter_bits_new() will use bits_copy to save the
>> content of the u64, but the size of bits_copy is only 4-bytes, and there
>> will be stack corruption.
>>
>> Fix it by change the type of unsafe_ptr from u64 * to unsigned long *.
>>
> This will be confusing as BPF-side long is always 64-bit. So why not
> instead make sure it's u64 throughout (i.e., bits_copy is u64
> explicitly), even on 32-bit architectures?

Just learn about the size of BPF-side long is always 64-bits. I had
considered to change bits_copy to u64. The main obstacle is that the
pointer type of find_next_bit is unsigned long *, if it is used on an
u64 under big-endian host, it may return invalid result.
>
>> Signed-off-by: Hou Tao <houtao1@huawei.com>
>> ---
>>  kernel/bpf/helpers.c | 18 ++++++++++--------
>>  1 file changed, 10 insertions(+), 8 deletions(-)
>>
>> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
>> index 6c0205d5018c..dee69c3904a0 100644
>> --- a/kernel/bpf/helpers.c
>> +++ b/kernel/bpf/helpers.c
>> @@ -2852,7 +2852,7 @@ struct bpf_iter_bits {
>>  } __aligned(8);
>>
>>  /* nr_bits only has 31 bits */
>> -#define BITS_ITER_NR_WORDS_MAX ((1U << 31) / BITS_PER_TYPE(u64))
>> +#define BITS_ITER_NR_WORDS_MAX ((1U << 31) / BITS_PER_TYPE(unsigned long))
>>
>>  struct bpf_iter_bits_kern {
>>         union {
>> @@ -2868,8 +2868,9 @@ struct bpf_iter_bits_kern {
>>   * bpf_iter_bits_new() - Initialize a new bits iterator for a given memory area
>>   * @it: The new bpf_iter_bits to be created
>>   * @unsafe_ptr__ign: A pointer pointing to a memory area to be iterated over
>> - * @nr_words: The size of the specified memory area, measured in 8-byte units.
>> - * Due to the limitation of memalloc, it can't be greater than 512.
>> + * @nr_words: The size of the specified memory area, measured in units of
>> + * sizeof(unsigned long). Due to the limitation of memalloc, it can't be
>> + * greater than 512.
>>   *
>>   * This function initializes a new bpf_iter_bits structure for iterating over
>>   * a memory area which is specified by the @unsafe_ptr__ign and @nr_words. It
>> @@ -2879,17 +2880,18 @@ struct bpf_iter_bits_kern {
>>   * On success, 0 is returned. On failure, ERR is returned.
>>   */
>>  __bpf_kfunc int
>> -bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_words)
>> +bpf_iter_bits_new(struct bpf_iter_bits *it, const unsigned long *unsafe_ptr__ign, u32 nr_words)
>>  {
>> -       struct bpf_iter_bits_kern *kit = (void *)it;
>> -       u32 nr_bytes = nr_words * sizeof(u64);
>> +       u32 nr_bytes = nr_words * sizeof(*unsafe_ptr__ign);
>>         u32 nr_bits = BYTES_TO_BITS(nr_bytes);
>> +       struct bpf_iter_bits_kern *kit;
>>         int err;
>>
>>         BUILD_BUG_ON(sizeof(struct bpf_iter_bits_kern) != sizeof(struct bpf_iter_bits));
>>         BUILD_BUG_ON(__alignof__(struct bpf_iter_bits_kern) !=
>>                      __alignof__(struct bpf_iter_bits));
>>
>> +       kit = (void *)it;
>>         kit->allocated = 0;
>>         kit->nr_bits = 0;
>>         kit->bits_copy = 0;
>> @@ -2900,8 +2902,8 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
>>         if (nr_words > BITS_ITER_NR_WORDS_MAX)
>>                 return -E2BIG;
>>
>> -       /* Optimization for u64 mask */
>> -       if (nr_bits == 64) {
>> +       /* Optimization for unsigned long mask */
>> +       if (nr_words == 1) {
>>                 err = bpf_probe_read_kernel_common(&kit->bits_copy, nr_bytes, unsafe_ptr__ign);
>>                 if (err)
>>                         return -EFAULT;
>> --
>> 2.29.2
>>
> .
Yafang Shao Oct. 9, 2024, 11:39 a.m. UTC | #3
On Wed, Oct 9, 2024 at 10:45 AM Hou Tao <houtao@huaweicloud.com> wrote:
>
>
>
> On 10/9/2024 2:30 AM, Andrii Nakryiko wrote:
> > On Tue, Oct 8, 2024 at 2:05 AM Hou Tao <houtao@huaweicloud.com> wrote:
> >> From: Hou Tao <houtao1@huawei.com>
> >>
> >> Under 32-bits host (e.g, arm32) , when a bpf program passes an u64 to
> >> bpf_iter_bits_new(), bpf_iter_bits_new() will use bits_copy to save the
> >> content of the u64, but the size of bits_copy is only 4-bytes, and there
> >> will be stack corruption.
> >>
> >> Fix it by change the type of unsafe_ptr from u64 * to unsigned long *.
> >>
> > This will be confusing as BPF-side long is always 64-bit. So why not
> > instead make sure it's u64 throughout (i.e., bits_copy is u64
> > explicitly), even on 32-bit architectures?
>
> Just learn about the size of BPF-side long is always 64-bits. I had
> considered to change bits_copy to u64. The main obstacle is that the
> pointer type of find_next_bit is unsigned long *, if it is used on an
> u64 under big-endian host, it may return invalid result.

IIUC, BPF  targets only 64-bit systems?
Alexei Starovoitov Oct. 9, 2024, 11:39 p.m. UTC | #4
On Wed, Oct 9, 2024 at 4:40 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> On Wed, Oct 9, 2024 at 10:45 AM Hou Tao <houtao@huaweicloud.com> wrote:
> >
> >
> >
> > On 10/9/2024 2:30 AM, Andrii Nakryiko wrote:
> > > On Tue, Oct 8, 2024 at 2:05 AM Hou Tao <houtao@huaweicloud.com> wrote:
> > >> From: Hou Tao <houtao1@huawei.com>
> > >>
> > >> Under 32-bits host (e.g, arm32) , when a bpf program passes an u64 to
> > >> bpf_iter_bits_new(), bpf_iter_bits_new() will use bits_copy to save the
> > >> content of the u64, but the size of bits_copy is only 4-bytes, and there
> > >> will be stack corruption.
> > >>
> > >> Fix it by change the type of unsafe_ptr from u64 * to unsigned long *.
> > >>
> > > This will be confusing as BPF-side long is always 64-bit. So why not
> > > instead make sure it's u64 throughout (i.e., bits_copy is u64
> > > explicitly), even on 32-bit architectures?
> >
> > Just learn about the size of BPF-side long is always 64-bits. I had
> > considered to change bits_copy to u64. The main obstacle is that the
> > pointer type of find_next_bit is unsigned long *, if it is used on an
> > u64 under big-endian host, it may return invalid result.
>
> IIUC, BPF  targets only 64-bit systems?

64-bit bpf programs run just fine on 32-bit systems.
Hou Tao Oct. 10, 2024, 1:19 a.m. UTC | #5
On 10/9/2024 10:45 AM, Hou Tao wrote:
>
> On 10/9/2024 2:30 AM, Andrii Nakryiko wrote:
>> On Tue, Oct 8, 2024 at 2:05 AM Hou Tao <houtao@huaweicloud.com> wrote:
>>> From: Hou Tao <houtao1@huawei.com>
>>>
>>> Under 32-bits host (e.g, arm32) , when a bpf program passes an u64 to
>>> bpf_iter_bits_new(), bpf_iter_bits_new() will use bits_copy to save the
>>> content of the u64, but the size of bits_copy is only 4-bytes, and there
>>> will be stack corruption.
>>>
>>> Fix it by change the type of unsafe_ptr from u64 * to unsigned long *.
>>>
>> This will be confusing as BPF-side long is always 64-bit. So why not
>> instead make sure it's u64 throughout (i.e., bits_copy is u64
>> explicitly), even on 32-bit architectures?
> Just learn about the size of BPF-side long is always 64-bits. I had
> considered to change bits_copy to u64. The main obstacle is that the
> pointer type of find_next_bit is unsigned long *, if it is used on an
> u64 under big-endian host, it may return invalid result.

I think doing the following swap for big endian and 32-bits host will
let find_next_bit return the correct result:

+static void swap_bits(u64 *bits, unsigned int nr)
+{
+#if defined(__BIG_ENDIAN) && !defined(CONFIG_64BIT)
+       unsigned int i;
+
+       for (i = 0; i < nr; i++)
+               bits[i] = (bits[i] >> 32) | ((u64)(u32)bits[i] << 32);
+#endif
+}
+

Will try to get some test environment to test it.
>>> Signed-off-by: Hou Tao <houtao1@huawei.com>
>>> ---
>>>  kernel/bpf/helpers.c | 18 ++++++++++--------
>>>  1 file changed, 10 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
>>> index 6c0205d5018c..dee69c3904a0 100644
>>> --- a/kernel/bpf/helpers.c
>>> +++ b/kernel/bpf/helpers.c
>>> @@ -2852,7 +2852,7 @@ struct bpf_iter_bits {
>>>  } __aligned(8);
>>>
>>>  /* nr_bits only has 31 bits */
>>> -#define BITS_ITER_NR_WORDS_MAX ((1U << 31) / BITS_PER_TYPE(u64))
>>> +#define BITS_ITER_NR_WORDS_MAX ((1U << 31) / BITS_PER_TYPE(unsigned long))
>>>
>>>  struct bpf_iter_bits_kern {
>>>         union {
>>> @@ -2868,8 +2868,9 @@ struct bpf_iter_bits_kern {
>>>   * bpf_iter_bits_new() - Initialize a new bits iterator for a given memory area
>>>   * @it: The new bpf_iter_bits to be created
>>>   * @unsafe_ptr__ign: A pointer pointing to a memory area to be iterated over
>>> - * @nr_words: The size of the specified memory area, measured in 8-byte units.
>>> - * Due to the limitation of memalloc, it can't be greater than 512.
>>> + * @nr_words: The size of the specified memory area, measured in units of
>>> + * sizeof(unsigned long). Due to the limitation of memalloc, it can't be
>>> + * greater than 512.
>>>   *
>>>   * This function initializes a new bpf_iter_bits structure for iterating over
>>>   * a memory area which is specified by the @unsafe_ptr__ign and @nr_words. It
>>> @@ -2879,17 +2880,18 @@ struct bpf_iter_bits_kern {
>>>   * On success, 0 is returned. On failure, ERR is returned.
>>>   */
>>>  __bpf_kfunc int
>>> -bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_words)
>>> +bpf_iter_bits_new(struct bpf_iter_bits *it, const unsigned long *unsafe_ptr__ign, u32 nr_words)
>>>  {
>>> -       struct bpf_iter_bits_kern *kit = (void *)it;
>>> -       u32 nr_bytes = nr_words * sizeof(u64);
>>> +       u32 nr_bytes = nr_words * sizeof(*unsafe_ptr__ign);
>>>         u32 nr_bits = BYTES_TO_BITS(nr_bytes);
>>> +       struct bpf_iter_bits_kern *kit;
>>>         int err;
>>>
>>>         BUILD_BUG_ON(sizeof(struct bpf_iter_bits_kern) != sizeof(struct bpf_iter_bits));
>>>         BUILD_BUG_ON(__alignof__(struct bpf_iter_bits_kern) !=
>>>                      __alignof__(struct bpf_iter_bits));
>>>
>>> +       kit = (void *)it;
>>>         kit->allocated = 0;
>>>         kit->nr_bits = 0;
>>>         kit->bits_copy = 0;
>>> @@ -2900,8 +2902,8 @@ bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
>>>         if (nr_words > BITS_ITER_NR_WORDS_MAX)
>>>                 return -E2BIG;
>>>
>>> -       /* Optimization for u64 mask */
>>> -       if (nr_bits == 64) {
>>> +       /* Optimization for unsigned long mask */
>>> +       if (nr_words == 1) {
>>>                 err = bpf_probe_read_kernel_common(&kit->bits_copy, nr_bytes, unsafe_ptr__ign);
>>>                 if (err)
>>>                         return -EFAULT;
>>> --
>>> 2.29.2
>>>
>> .
> .
diff mbox series

Patch

diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 6c0205d5018c..dee69c3904a0 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -2852,7 +2852,7 @@  struct bpf_iter_bits {
 } __aligned(8);
 
 /* nr_bits only has 31 bits */
-#define BITS_ITER_NR_WORDS_MAX ((1U << 31) / BITS_PER_TYPE(u64))
+#define BITS_ITER_NR_WORDS_MAX ((1U << 31) / BITS_PER_TYPE(unsigned long))
 
 struct bpf_iter_bits_kern {
 	union {
@@ -2868,8 +2868,9 @@  struct bpf_iter_bits_kern {
  * bpf_iter_bits_new() - Initialize a new bits iterator for a given memory area
  * @it: The new bpf_iter_bits to be created
  * @unsafe_ptr__ign: A pointer pointing to a memory area to be iterated over
- * @nr_words: The size of the specified memory area, measured in 8-byte units.
- * Due to the limitation of memalloc, it can't be greater than 512.
+ * @nr_words: The size of the specified memory area, measured in units of
+ * sizeof(unsigned long). Due to the limitation of memalloc, it can't be
+ * greater than 512.
  *
  * This function initializes a new bpf_iter_bits structure for iterating over
  * a memory area which is specified by the @unsafe_ptr__ign and @nr_words. It
@@ -2879,17 +2880,18 @@  struct bpf_iter_bits_kern {
  * On success, 0 is returned. On failure, ERR is returned.
  */
 __bpf_kfunc int
-bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_words)
+bpf_iter_bits_new(struct bpf_iter_bits *it, const unsigned long *unsafe_ptr__ign, u32 nr_words)
 {
-	struct bpf_iter_bits_kern *kit = (void *)it;
-	u32 nr_bytes = nr_words * sizeof(u64);
+	u32 nr_bytes = nr_words * sizeof(*unsafe_ptr__ign);
 	u32 nr_bits = BYTES_TO_BITS(nr_bytes);
+	struct bpf_iter_bits_kern *kit;
 	int err;
 
 	BUILD_BUG_ON(sizeof(struct bpf_iter_bits_kern) != sizeof(struct bpf_iter_bits));
 	BUILD_BUG_ON(__alignof__(struct bpf_iter_bits_kern) !=
 		     __alignof__(struct bpf_iter_bits));
 
+	kit = (void *)it;
 	kit->allocated = 0;
 	kit->nr_bits = 0;
 	kit->bits_copy = 0;
@@ -2900,8 +2902,8 @@  bpf_iter_bits_new(struct bpf_iter_bits *it, const u64 *unsafe_ptr__ign, u32 nr_w
 	if (nr_words > BITS_ITER_NR_WORDS_MAX)
 		return -E2BIG;
 
-	/* Optimization for u64 mask */
-	if (nr_bits == 64) {
+	/* Optimization for unsigned long mask */
+	if (nr_words == 1) {
 		err = bpf_probe_read_kernel_common(&kit->bits_copy, nr_bytes, unsafe_ptr__ign);
 		if (err)
 			return -EFAULT;