* [PATCH bpf 0/2] libbpf: Reject private struct_ops bitfields before data access
@ 2026-09-10 17:23 Mingpei CAO
2026-09-10 17:23 ` [PATCH bpf 1/2] libbpf: Reject struct_ops bitfields before accessing data Mingpei CAO
2026-09-10 17:23 ` [PATCH bpf 2/2] selftests/bpf: Test private struct_ops bitfield rejection Mingpei CAO
0 siblings, 2 replies; 6+ messages in thread
From: Mingpei CAO @ 2026-09-10 17:23 UTC (permalink / raw)
To: bpf; +Cc: andrii, eddyz87, Mingpei CAO
This series fixes a bug in bpf_map__init_kern_struct_ops() that can
cause a userspace crash when loading a BPF object containing an all-zero
private bitfield in a local struct_ops mirror.
For structures with kind_flag set, member->offset also encodes the
bitfield width. bpf_map__init_kern_struct_ops() currently uses that raw
value to calculate the member data pointer before rejecting bitfields.
The absent-member compatibility path can consequently pass a pointer
far outside the struct_ops data to libbpf_is_mem_zeroed().
Patch 1 rejects local bitfields before calculating the data pointer.
Patch 2 adds a regression test for the all-zero private bitfield while
retaining the existing ordinary all-zero field compatibility control.
The issue was reproduced with a Clang generated object. Before the fix,
AddressSanitizer reported a SEGV caused by a read. After the fix, the
same object was rejected with -ENOTSUP and the expected bitfield
diagnostic. The ordinary all-zero field control continued to load
successfully.
AI assistance was used in preparing this series. I independently
reviewed the changes and reproduced the results.
Mingpei CAO (2):
libbpf: Reject struct_ops bitfields before accessing data
selftests/bpf: Test private struct_ops bitfield rejection
tools/lib/bpf/libbpf.c | 9 ++++--
.../bpf/prog_tests/test_struct_ops_module.c | 31 +++++++++++++++++++
.../selftests/bpf/progs/struct_ops_module.c | 7 +++++
3 files changed, 45 insertions(+), 2 deletions(-)
base-commit: e4a62833adff6ef0fe7c0b90393204fe3c26b5c5
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH bpf 1/2] libbpf: Reject struct_ops bitfields before accessing data
2026-09-10 17:23 [PATCH bpf 0/2] libbpf: Reject private struct_ops bitfields before data access Mingpei CAO
@ 2026-09-10 17:23 ` Mingpei CAO
2026-09-10 18:26 ` bot+bpf-ci
2026-09-10 21:32 ` Amery Hung
2026-09-10 17:23 ` [PATCH bpf 2/2] selftests/bpf: Test private struct_ops bitfield rejection Mingpei CAO
1 sibling, 2 replies; 6+ messages in thread
From: Mingpei CAO @ 2026-09-10 17:23 UTC (permalink / raw)
To: bpf; +Cc: andrii, eddyz87, Mingpei CAO
A Clang-generated struct_ops mirror with an all-zero private bitfield can
crash libbpf. With kind_flag set, the BTF member offset also encodes the
bitfield width.
bpf_map__init_kern_struct_ops() divided this encoded value by eight
before rejecting bitfields. A 31-bit field therefore selects
data + 0x3e00000, where libbpf_is_mem_zeroed() triggers an ASan SEGV.
The issue was found by comparing the same ELF in JIT and interpreter
configurations. JIT+BTF reached the faulty struct_ops path, while the
interpreter configuration rejected the object before this code.
Reject local bitfields before calculating the data pointer. Preserve the
existing all-zero compatibility path for ordinary private fields.
Fixes: c911fc61a7ce ("libbpf: Skip zeroed or null fields if not found in the kernel type.")
Assisted-by: LLM
Signed-off-by: Mingpei CAO <caomingpei@gmail.com>
---
tools/lib/bpf/libbpf.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index b749c01742ee0..1738a42220f0c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1223,6 +1223,12 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
const char *mname;
mname = btf__name_by_offset(btf, member->name_off);
+ if (btf_member_bitfield_size(type, i)) {
+ pr_warn("struct_ops init_kern %s: bitfield %s is not supported\n",
+ map->name, mname);
+ return -ENOTSUP;
+ }
+
moff = member->offset / 8;
mdata = data + moff;
msize = btf__resolve_size(btf, member->type);
@@ -1259,8 +1265,7 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
}
kern_member_idx = kern_member - btf_members(kern_type);
- if (btf_member_bitfield_size(type, i) ||
- btf_member_bitfield_size(kern_type, kern_member_idx)) {
+ if (btf_member_bitfield_size(kern_type, kern_member_idx)) {
pr_warn("struct_ops init_kern %s: bitfield %s is not supported\n",
map->name, mname);
return -ENOTSUP;
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH bpf 2/2] selftests/bpf: Test private struct_ops bitfield rejection
2026-09-10 17:23 [PATCH bpf 0/2] libbpf: Reject private struct_ops bitfields before data access Mingpei CAO
2026-09-10 17:23 ` [PATCH bpf 1/2] libbpf: Reject struct_ops bitfields before accessing data Mingpei CAO
@ 2026-09-10 17:23 ` Mingpei CAO
2026-09-10 18:26 ` bot+bpf-ci
1 sibling, 1 reply; 6+ messages in thread
From: Mingpei CAO @ 2026-09-10 17:23 UTC (permalink / raw)
To: bpf; +Cc: andrii, eddyz87, Mingpei CAO
Add an optional all-zero private bitfield to the struct_ops test. Verify
that libbpf returns -ENOTSUP and emits the bitfield diagnostic.
Keep the existing all-zero scalar test as the compatibility control.
Assisted-by: LLM
Signed-off-by: Mingpei CAO <caomingpei@gmail.com>
---
.../bpf/prog_tests/test_struct_ops_module.c | 31 +++++++++++++++++++
.../selftests/bpf/progs/struct_ops_module.c | 7 +++++
2 files changed, 38 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c
index 75a0dea511b3f..517e5abe67c0c 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c
@@ -150,6 +150,35 @@ static void test_struct_ops_not_zeroed(void)
struct_ops_module__destroy(skel);
}
+static void test_struct_ops_private_bitfield(void)
+{
+ struct struct_ops_module *skel;
+ char *log = NULL;
+ int err;
+
+ skel = struct_ops_module__open();
+ if (!ASSERT_OK_PTR(skel, "struct_ops_module_open_private_bitfield"))
+ return;
+
+ bpf_map__set_autocreate(skel->maps.testmod_zeroed, false);
+ err = bpf_map__set_autocreate(skel->maps.testmod_private_bitfield, true);
+ if (!ASSERT_OK(err, "enable_private_bitfield_map"))
+ goto cleanup;
+
+ if (start_libbpf_log_capture())
+ goto cleanup;
+ err = struct_ops_module__load(skel);
+ log = stop_libbpf_log_capture();
+ ASSERT_EQ(err, -ENOTSUP, "struct_ops_module_load_private_bitfield");
+ ASSERT_HAS_SUBSTR(log,
+ "bitfield private_bitfield is not supported",
+ "private_bitfield_rejection_log");
+
+cleanup:
+ free(log);
+ struct_ops_module__destroy(skel);
+}
+
/* The signature of an implementation might not match the signature of the
* function pointer prototype defined in the BPF program. This mismatch
* should be allowed as long as the behavior of the operator program
@@ -304,6 +333,8 @@ void serial_test_struct_ops_module(void)
test_struct_ops_load();
if (test__start_subtest("struct_ops_not_zeroed"))
test_struct_ops_not_zeroed();
+ if (test__start_subtest("struct_ops_private_bitfield"))
+ test_struct_ops_private_bitfield();
if (test__start_subtest("struct_ops_incompatible"))
test_struct_ops_incompatible();
if (test__start_subtest("struct_ops_null_out_cb"))
diff --git a/tools/testing/selftests/bpf/progs/struct_ops_module.c b/tools/testing/selftests/bpf/progs/struct_ops_module.c
index 71c420c3a5a6c..423caf78f4207 100644
--- a/tools/testing/selftests/bpf/progs/struct_ops_module.c
+++ b/tools/testing/selftests/bpf/progs/struct_ops_module.c
@@ -76,6 +76,13 @@ struct bpf_testmod_ops___zeroed testmod_zeroed = {
.zeroed_op = (void *)zeroed_op,
};
+struct bpf_testmod_ops___private_bitfield {
+ unsigned int private_bitfield:31;
+};
+
+SEC("?.struct_ops.link")
+struct bpf_testmod_ops___private_bitfield testmod_private_bitfield;
+
struct bpf_testmod_ops___incompatible {
int (*test_1)(void);
void (*test_2)(int *a);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH bpf 1/2] libbpf: Reject struct_ops bitfields before accessing data
2026-09-10 17:23 ` [PATCH bpf 1/2] libbpf: Reject struct_ops bitfields before accessing data Mingpei CAO
@ 2026-09-10 18:26 ` bot+bpf-ci
2026-09-10 21:32 ` Amery Hung
1 sibling, 0 replies; 6+ messages in thread
From: bot+bpf-ci @ 2026-09-10 18:26 UTC (permalink / raw)
To: caomingpei, bpf
Cc: andrii, eddyz87, caomingpei, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, mason, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 4690 bytes --]
> libbpf: Reject struct_ops bitfields before accessing data
>
> A Clang-generated struct_ops mirror with an all-zero private bitfield can
> crash libbpf. With kind_flag set, the BTF member offset also encodes the
> bitfield width.
>
> bpf_map__init_kern_struct_ops() divided this encoded value by eight
> before rejecting bitfields. A 31-bit field therefore selects
> data + 0x3e00000, where libbpf_is_mem_zeroed() triggers an ASan SEGV.
>
> The issue was found by comparing the same ELF in JIT and interpreter
> configurations. JIT+BTF reached the faulty struct_ops path, while the
> interpreter configuration rejected the object before this code.
This isn't a bug, but is the JIT/interpreter distinction load-bearing
here, or was the real difference kernel BTF availability?
find_struct_ops_kern_types() bails out with "struct %s is not found
in kernel BTF" when vmlinux BTF is unavailable, which matches the
"+BTF" half rather than the JIT half.
> Reject local bitfields before calculating the data pointer. Preserve the
> existing all-zero compatibility path for ordinary private fields.
>
> Fixes: c911fc61a7ce ("libbpf: Skip zeroed or null fields if not found in the kernel type.")
> Assisted-by: LLM
> Signed-off-by: Mingpei CAO <caomingpei@gmail.com>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index b749c01742ee..1738a42220f0 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -1223,6 +1223,12 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
> const char *mname;
>
> mname = btf__name_by_offset(btf, member->name_off);
> + if (btf_member_bitfield_size(type, i)) {
> + pr_warn("struct_ops init_kern %s: bitfield %s is not supported\n",
> + map->name, mname);
> + return -ENOTSUP;
> + }
> +
> moff = member->offset / 8;
> mdata = data + moff;
> msize = btf__resolve_size(btf, member->type);
A subsystem pattern flags this as potentially concerning: the fix
guards only the bitfield-width half of the kind_flag member offset
encoding; the bit-offset half is still used unvalidated to form the
pointer that libbpf_is_mem_zeroed()/memcpy() read from.
st_ops->data is sized to the local struct in init_struct_ops_maps():
st_ops->data = malloc(type->size)
But moff comes straight from BTF:
moff = member->offset / 8
BTF_MEMBER_BIT_OFFSET is the low 24 bits, so moff can be up to
0x1FFFFF (~2 MiB) even with bitfield_size == 0 (or with kflag clear,
where btf_member_bitfield_size() returns 0 by construction).
libbpf does not bound-check member offsets against the struct size.
btf_sanity_check() in btf.c calls btf_validate_type(), whose
BTF_KIND_STRUCT/UNION case validates only m->name_off and m->type:
for (i = 0; i < n; i++, m++) {
err = btf_validate_str(btf, m->name_off, "field name", id);
err = err ?: btf_validate_id(btf, m->type, id);
m->offset is never checked. So the same ASan SEGV the changelog
describes is still reachable from bpf_object__open_file() with a
crafted .BTF that gives a struct_ops member a large bits_offset and
bitfield_size == 0: mdata lands up to ~2 MiB past a small malloc()
and libbpf_is_mem_zeroed(mdata, msize) walks it.
This is pre-existing and was introduced by the same commit named in
the Fixes: tag. The diff does not make it worse. It is noted here
because the patch's stated purpose is to stop this expression from
producing a wild pointer, so a reviewer will reasonably ask whether
a single bound such as:
if (moff >= type->size || msize > type->size - moff)
return -EINVAL;
would cover the whole class rather than just the bitfield encoding?
> @@ -1259,8 +1265,7 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
> }
>
> kern_member_idx = kern_member - btf_members(kern_type);
> - if (btf_member_bitfield_size(type, i) ||
> - btf_member_bitfield_size(kern_type, kern_member_idx)) {
> + if (btf_member_bitfield_size(kern_type, kern_member_idx)) {
> pr_warn("struct_ops init_kern %s: bitfield %s is not supported\n",
> map->name, mname);
> return -ENOTSUP;
This isn't a bug, but now that this check is split in two, would it
help to distinguish the two warnings so the log says which side of
the comparison has the bitfield? Everywhere else in this function the
warnings are distinct enough to identify which side failed ("Cannot
find member %s in kernel BTF", "kernel member %s is not a func ptr",
"%zd != %zd(kernel)").
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/34510539779
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH bpf 2/2] selftests/bpf: Test private struct_ops bitfield rejection
2026-09-10 17:23 ` [PATCH bpf 2/2] selftests/bpf: Test private struct_ops bitfield rejection Mingpei CAO
@ 2026-09-10 18:26 ` bot+bpf-ci
0 siblings, 0 replies; 6+ messages in thread
From: bot+bpf-ci @ 2026-09-10 18:26 UTC (permalink / raw)
To: caomingpei, bpf
Cc: andrii, eddyz87, caomingpei, ast, andrii, daniel, martin.lau,
eddyz87, yonghong.song, mason, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 5778 bytes --]
> diff --git a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c
> index 75a0dea511b3..517e5abe67c0 100644
> --- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c
> +++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c
> @@ -150,6 +150,35 @@ static void test_struct_ops_not_zeroed(void)
> struct_ops_module__destroy(skel);
> }
>
> +static void test_struct_ops_private_bitfield(void)
> +{
> + struct struct_ops_module *skel;
> + char *log = NULL;
> + int err;
> +
> + skel = struct_ops_module__open();
> + if (!ASSERT_OK_PTR(skel, "struct_ops_module_open_private_bitfield"))
> + return;
> +
> + bpf_map__set_autocreate(skel->maps.testmod_zeroed, false);
> + err = bpf_map__set_autocreate(skel->maps.testmod_private_bitfield, true);
> + if (!ASSERT_OK(err, "enable_private_bitfield_map"))
> + goto cleanup;
> +
> + if (start_libbpf_log_capture())
> + goto cleanup;
> + err = struct_ops_module__load(skel);
> + log = stop_libbpf_log_capture();
> + ASSERT_EQ(err, -ENOTSUP, "struct_ops_module_load_private_bitfield");
Does this assertion alone actually verify the fix? On pre-fix libbpf,
m->offset / 8 evaluates to 0x3E00000 for the 31-bit bitfield, and
libbpf_is_mem_zeroed() reads ~62 MiB past the 4-byte st_ops->data. If
that read happens to land on non-zero mapped memory,
bpf_map__init_kern_struct_ops() returns -ENOTSUP from the "Cannot find
member %s in kernel BTF" path, so ASSERT_EQ(err, -ENOTSUP, ...) passes on
the buggy code as well.
Only the ASSERT_HAS_SUBSTR() on the bitfield diagnostic below actually
discriminates between fixed and broken libbpf. That makes the test correct
as written, but the two checks are asserted independently, so if the load
unexpectedly succeeds, the failure is reported against the log substring
rather than against the load.
The established pattern in this area gates on the error first, for example
in prog_tests/struct_ops_autocreate.c:
if (!ASSERT_ERR(err, "struct_ops_autocreate__load"))
goto cleanup;
ASSERT_HAS_SUBSTR(log, "libbpf: struct_ops init_kern", "init_kern message");
ASSERT_EQ(err, -ENOTSUP, "errno should be ENOTSUP");
Also worth noting: both the new local-bitfield check and the retained
kernel-bitfield check in bpf_map__init_kern_struct_ops() print the
identical "bitfield %s is not supported" string. The test only pins the
new one because the kernel struct bpf_testmod_ops has no private_bitfield
member, which makes the assertion meaningful but could use a comment.
> + ASSERT_HAS_SUBSTR(log,
> + "bitfield private_bitfield is not supported",
> + "private_bitfield_rejection_log");
> +
> +cleanup:
> + free(log);
> + struct_ops_module__destroy(skel);
> +}
> +
> /* The signature of an implementation might not match the signature of the
> * function pointer prototype defined in the BPF program. This mismatch
> * should be allowed as long as the behavior of the operator program
[ ... ]
> diff --git a/tools/testing/selftests/bpf/progs/struct_ops_module.c b/tools/testing/selftests/bpf/progs/struct_ops_module.c
> index 71c420c3a5a6..423caf78f420 100644
> --- a/tools/testing/selftests/bpf/progs/struct_ops_module.c
> +++ b/tools/testing/selftests/bpf/progs/struct_ops_module.c
> @@ -76,6 +76,13 @@ struct bpf_testmod_ops___zeroed testmod_zeroed = {
> .zeroed_op = (void *)zeroed_op,
> };
>
> +struct bpf_testmod_ops___private_bitfield {
> + unsigned int private_bitfield:31;
> +};
Does this bitfield width create a latent issue in bpftool's skeleton
generator? With kind_flag set, the BTF member offset encodes the bitfield
width in the top 8 bits. walk_st_ops_shadow_vars() in
tools/bpf/bpftool/gen.c does the same unmasked division libbpf used to do:
offset = m->offset / 8;
if (next_offset < offset)
printf("\t\t\tchar __padding_%d[%u];\n", i, offset - next_offset);
For "unsigned int private_bitfield:31" at bit offset 0, m->offset ==
0x1F000000, so offset == 0x03E00000 == 65011712.
gen_st_ops_shadow_type() therefore emits into the generated
struct_ops_module.skel.h:
struct struct_ops_module__testmod_private_bitfield__bpf_testmod_ops___private_bitfield {
char __padding_0[65011712];
unsigned int private_bitfield;
} *testmod_private_bitfield;
That is a ~62 MiB shadow struct type in a selftest build artifact.
gen_st_ops_shadow_init() then assigns that pointer from
bpf_map__initial_value(obj->maps.testmod_private_bitfield, NULL), which
for a struct_ops map is the 4-byte st_ops->data buffer, so
skel->struct_ops.testmod_private_bitfield->private_bitfield is ~62 MiB out
of bounds.
Nothing in the new subtest dereferences that pointer, and a 62 MiB struct
type with no instance compiles fine, so this is not a crash today. But it
is a latent OOB accessor generated into a checked-in build artifact, and it
shows the divide-before-checking-bitfields bug still exists in bpftool
after this series.
The :31 width also has no comment explaining that it was chosen because the
width lands in the encoded offset. A narrower width like :1 still
reproduces the libbpf bug with a much smaller bogus offset (0x200000).
Worth either fixing walk_st_ops_shadow_vars() to use
btf_member_bit_offset() in the same series, or noting the interaction?
> +
> +SEC("?.struct_ops.link")
> +struct bpf_testmod_ops___private_bitfield testmod_private_bitfield;
> +
> struct bpf_testmod_ops___incompatible {
> int (*test_1)(void);
> void (*test_2)(int *a);
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/34510539779
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH bpf 1/2] libbpf: Reject struct_ops bitfields before accessing data
2026-09-10 17:23 ` [PATCH bpf 1/2] libbpf: Reject struct_ops bitfields before accessing data Mingpei CAO
2026-09-10 18:26 ` bot+bpf-ci
@ 2026-09-10 21:32 ` Amery Hung
1 sibling, 0 replies; 6+ messages in thread
From: Amery Hung @ 2026-09-10 21:32 UTC (permalink / raw)
To: Mingpei CAO; +Cc: bpf, andrii, eddyz87
On Thu, Sep 10, 2026 at 10:51 AM Mingpei CAO <caomingpei@gmail.com> wrote:
>
> A Clang-generated struct_ops mirror with an all-zero private bitfield can
> crash libbpf. With kind_flag set, the BTF member offset also encodes the
> bitfield width.
I find the commit message harder to understand than the code because
it emphasizes seemingly incidental configuration details and uses
undefined terminology.
The segmentation fault can happen when "using a local struct_ops with
bitfield absent from the kernel BTF type", so none of the detail such
as clang, all-zero, JIT vs interpreter seem to matter...
I assume “mirror” means the local struct_ops type in the BPF object,
and “private bitfield” means an extra local member absent from the
corresponding kernel BTF type. Can you state that directly instead of
inventing new terminology?
The bound-check issue raised by CI bot seems to be valid.
>
> bpf_map__init_kern_struct_ops() divided this encoded value by eight
> before rejecting bitfields. A 31-bit field therefore selects
> data + 0x3e00000, where libbpf_is_mem_zeroed() triggers an ASan SEGV.
>
> The issue was found by comparing the same ELF in JIT and interpreter
> configurations. JIT+BTF reached the faulty struct_ops path, while the
> interpreter configuration rejected the object before this code.
>
> Reject local bitfields before calculating the data pointer. Preserve the
> existing all-zero compatibility path for ordinary private fields.
>
> Fixes: c911fc61a7ce ("libbpf: Skip zeroed or null fields if not found in the kernel type.")
> Assisted-by: LLM
> Signed-off-by: Mingpei CAO <caomingpei@gmail.com>
> ---
> tools/lib/bpf/libbpf.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index b749c01742ee0..1738a42220f0c 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -1223,6 +1223,12 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
> const char *mname;
>
> mname = btf__name_by_offset(btf, member->name_off);
> + if (btf_member_bitfield_size(type, i)) {
> + pr_warn("struct_ops init_kern %s: bitfield %s is not supported\n",
> + map->name, mname);
> + return -ENOTSUP;
> + }
> +
> moff = member->offset / 8;
> mdata = data + moff;
> msize = btf__resolve_size(btf, member->type);
> @@ -1259,8 +1265,7 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map)
> }
>
> kern_member_idx = kern_member - btf_members(kern_type);
> - if (btf_member_bitfield_size(type, i) ||
> - btf_member_bitfield_size(kern_type, kern_member_idx)) {
> + if (btf_member_bitfield_size(kern_type, kern_member_idx)) {
> pr_warn("struct_ops init_kern %s: bitfield %s is not supported\n",
> map->name, mname);
> return -ENOTSUP;
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-10 21:32 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-10 17:23 [PATCH bpf 0/2] libbpf: Reject private struct_ops bitfields before data access Mingpei CAO
2026-09-10 17:23 ` [PATCH bpf 1/2] libbpf: Reject struct_ops bitfields before accessing data Mingpei CAO
2026-09-10 18:26 ` bot+bpf-ci
2026-09-10 21:32 ` Amery Hung
2026-09-10 17:23 ` [PATCH bpf 2/2] selftests/bpf: Test private struct_ops bitfield rejection Mingpei CAO
2026-09-10 18:26 ` bot+bpf-ci
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox