Skip to content

Commit 1b935a7

Browse files
anakryikoqmonnet
authored andcommitted
bpftool: improve skeleton backwards compat with old buggy libbpfs
Old versions of libbpf don't handle varying sizes of bpf_map_skeleton struct correctly. As such, BPF skeleton generated by newest bpftool might not be compatible with older libbpf (though only when libbpf is used as a shared library), even though it, by design, should. Going forward libbpf will be fixed, plus we'll release bug fixed versions of relevant old libbpfs, but meanwhile try to mitigate from bpftool side by conservatively assuming older and smaller definition of bpf_map_skeleton, if possible. Meaning, if there are no struct_ops maps. If there are struct_ops, then presumably user would like to have auto-attaching logic and struct_ops map link placeholders, so use the full bpf_map_skeleton definition in that case. Acked-by: Quentin Monnet <[email protected]> Co-developed-by: Mykyta Yatsenko <[email protected]> Signed-off-by: Mykyta Yatsenko <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: Eduard Zingerman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 6bcdeb8 commit 1b935a7

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

src/gen.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -852,24 +852,41 @@ codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped, bool
852852
{
853853
struct bpf_map *map;
854854
char ident[256];
855-
size_t i;
855+
size_t i, map_sz;
856856

857857
if (!map_cnt)
858858
return;
859859

860+
/* for backward compatibility with old libbpf versions that don't
861+
* handle new BPF skeleton with new struct bpf_map_skeleton definition
862+
* that includes link field, avoid specifying new increased size,
863+
* unless we absolutely have to (i.e., if there are struct_ops maps
864+
* present)
865+
*/
866+
map_sz = offsetof(struct bpf_map_skeleton, link);
867+
if (populate_links) {
868+
bpf_object__for_each_map(map, obj) {
869+
if (bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS) {
870+
map_sz = sizeof(struct bpf_map_skeleton);
871+
break;
872+
}
873+
}
874+
}
875+
860876
codegen("\
861877
\n\
862-
\n\
878+
\n\
863879
/* maps */ \n\
864880
s->map_cnt = %zu; \n\
865-
s->map_skel_sz = sizeof(*s->maps); \n\
866-
s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz);\n\
881+
s->map_skel_sz = %zu; \n\
882+
s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt,\n\
883+
sizeof(*s->maps) > %zu ? sizeof(*s->maps) : %zu);\n\
867884
if (!s->maps) { \n\
868885
err = -ENOMEM; \n\
869886
goto err; \n\
870887
} \n\
871888
",
872-
map_cnt
889+
map_cnt, map_sz, map_sz, map_sz
873890
);
874891
i = 0;
875892
bpf_object__for_each_map(map, obj) {
@@ -878,23 +895,22 @@ codegen_maps_skeleton(struct bpf_object *obj, size_t map_cnt, bool mmaped, bool
878895

879896
codegen("\
880897
\n\
881-
\n\
882-
s->maps[%zu].name = \"%s\"; \n\
883-
s->maps[%zu].map = &obj->maps.%s; \n\
898+
\n\
899+
map = (struct bpf_map_skeleton *)((char *)s->maps + %zu * s->map_skel_sz);\n\
900+
map->name = \"%s\"; \n\
901+
map->map = &obj->maps.%s; \n\
884902
",
885-
i, bpf_map__name(map), i, ident);
903+
i, bpf_map__name(map), ident);
886904
/* memory-mapped internal maps */
887905
if (mmaped && is_mmapable_map(map, ident, sizeof(ident))) {
888-
printf("\ts->maps[%zu].mmaped = (void **)&obj->%s;\n",
889-
i, ident);
906+
printf("\tmap->mmaped = (void **)&obj->%s;\n", ident);
890907
}
891908

892909
if (populate_links && bpf_map__type(map) == BPF_MAP_TYPE_STRUCT_OPS) {
893910
codegen("\
894911
\n\
895-
s->maps[%zu].link = &obj->links.%s;\n\
896-
",
897-
i, ident);
912+
map->link = &obj->links.%s; \n\
913+
", ident);
898914
}
899915
i++;
900916
}
@@ -1463,6 +1479,7 @@ static int do_skeleton(int argc, char **argv)
14631479
%1$s__create_skeleton(struct %1$s *obj) \n\
14641480
{ \n\
14651481
struct bpf_object_skeleton *s; \n\
1482+
struct bpf_map_skeleton *map __attribute__((unused));\n\
14661483
int err; \n\
14671484
\n\
14681485
s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s));\n\
@@ -1753,6 +1770,7 @@ static int do_subskeleton(int argc, char **argv)
17531770
{ \n\
17541771
struct %1$s *obj; \n\
17551772
struct bpf_object_subskeleton *s; \n\
1773+
struct bpf_map_skeleton *map __attribute__((unused));\n\
17561774
int err; \n\
17571775
\n\
17581776
obj = (struct %1$s *)calloc(1, sizeof(*obj)); \n\

0 commit comments

Comments
 (0)