libbpf: Always specify expected_attach_type on program load if supported
For some types of BPF programs that utilize expected_attach_type, libbpf won't set load_attr.expected_attach_type, even if expected_attach_type is known from section definition. This was done to preserve backwards compatibility with old kernels that didn't recognize expected_attach_type attribute yet (which was added in5e43f899b0
("bpf: Check attach type at prog load time"). But this is problematic for some BPF programs that utilize newer features that require kernel to know specific expected_attach_type (e.g., extended set of return codes for cgroup_skb/egress programs). This patch makes libbpf specify expected_attach_type by default, but also detect support for this field in kernel and not set it during program load. This allows to have a good metadata for bpf_program (e.g., bpf_program__get_extected_attach_type()), but still work with old kernels (for cases where it can work at all). Additionally, due to expected_attach_type being always set for recognized program types, bpf_program__attach_cgroup doesn't have to do extra checks to determine correct attach type, so remove that additional logic. Also adjust section_names selftest to account for this change. More detailed discussion can be found in [0]. [0] https://lore.kernel.org/bpf/20200412003604.GA15986@rdna-mbp.dhcp.thefacebook.com/ Fixes:5cf1e91456
("bpf: cgroup inet skb programs can return 0 to 3") Fixes:5e43f899b0
("bpf: Check attach type at prog load time") Reported-by: Andrey Ignatov <rdna@fb.com> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Song Liu <songliubraving@fb.com> Acked-by: Andrey Ignatov <rdna@fb.com> Link: https://lore.kernel.org/bpf/20200414182645.1368174-1-andriin@fb.com
Este commit está contenido en:

cometido por
Daniel Borkmann

padre
99e3a236dd
commit
25498a1969
@@ -43,18 +43,18 @@ static struct sec_name_test tests[] = {
|
||||
{"lwt_seg6local", {0, BPF_PROG_TYPE_LWT_SEG6LOCAL, 0}, {-EINVAL, 0} },
|
||||
{
|
||||
"cgroup_skb/ingress",
|
||||
{0, BPF_PROG_TYPE_CGROUP_SKB, 0},
|
||||
{0, BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_INGRESS},
|
||||
{0, BPF_CGROUP_INET_INGRESS},
|
||||
},
|
||||
{
|
||||
"cgroup_skb/egress",
|
||||
{0, BPF_PROG_TYPE_CGROUP_SKB, 0},
|
||||
{0, BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_EGRESS},
|
||||
{0, BPF_CGROUP_INET_EGRESS},
|
||||
},
|
||||
{"cgroup/skb", {0, BPF_PROG_TYPE_CGROUP_SKB, 0}, {-EINVAL, 0} },
|
||||
{
|
||||
"cgroup/sock",
|
||||
{0, BPF_PROG_TYPE_CGROUP_SOCK, 0},
|
||||
{0, BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET_SOCK_CREATE},
|
||||
{0, BPF_CGROUP_INET_SOCK_CREATE},
|
||||
},
|
||||
{
|
||||
@@ -69,26 +69,38 @@ static struct sec_name_test tests[] = {
|
||||
},
|
||||
{
|
||||
"cgroup/dev",
|
||||
{0, BPF_PROG_TYPE_CGROUP_DEVICE, 0},
|
||||
{0, BPF_PROG_TYPE_CGROUP_DEVICE, BPF_CGROUP_DEVICE},
|
||||
{0, BPF_CGROUP_DEVICE},
|
||||
},
|
||||
{"sockops", {0, BPF_PROG_TYPE_SOCK_OPS, 0}, {0, BPF_CGROUP_SOCK_OPS} },
|
||||
{
|
||||
"sockops",
|
||||
{0, BPF_PROG_TYPE_SOCK_OPS, BPF_CGROUP_SOCK_OPS},
|
||||
{0, BPF_CGROUP_SOCK_OPS},
|
||||
},
|
||||
{
|
||||
"sk_skb/stream_parser",
|
||||
{0, BPF_PROG_TYPE_SK_SKB, 0},
|
||||
{0, BPF_PROG_TYPE_SK_SKB, BPF_SK_SKB_STREAM_PARSER},
|
||||
{0, BPF_SK_SKB_STREAM_PARSER},
|
||||
},
|
||||
{
|
||||
"sk_skb/stream_verdict",
|
||||
{0, BPF_PROG_TYPE_SK_SKB, 0},
|
||||
{0, BPF_PROG_TYPE_SK_SKB, BPF_SK_SKB_STREAM_VERDICT},
|
||||
{0, BPF_SK_SKB_STREAM_VERDICT},
|
||||
},
|
||||
{"sk_skb", {0, BPF_PROG_TYPE_SK_SKB, 0}, {-EINVAL, 0} },
|
||||
{"sk_msg", {0, BPF_PROG_TYPE_SK_MSG, 0}, {0, BPF_SK_MSG_VERDICT} },
|
||||
{"lirc_mode2", {0, BPF_PROG_TYPE_LIRC_MODE2, 0}, {0, BPF_LIRC_MODE2} },
|
||||
{
|
||||
"sk_msg",
|
||||
{0, BPF_PROG_TYPE_SK_MSG, BPF_SK_MSG_VERDICT},
|
||||
{0, BPF_SK_MSG_VERDICT},
|
||||
},
|
||||
{
|
||||
"lirc_mode2",
|
||||
{0, BPF_PROG_TYPE_LIRC_MODE2, BPF_LIRC_MODE2},
|
||||
{0, BPF_LIRC_MODE2},
|
||||
},
|
||||
{
|
||||
"flow_dissector",
|
||||
{0, BPF_PROG_TYPE_FLOW_DISSECTOR, 0},
|
||||
{0, BPF_PROG_TYPE_FLOW_DISSECTOR, BPF_FLOW_DISSECTOR},
|
||||
{0, BPF_FLOW_DISSECTOR},
|
||||
},
|
||||
{
|
||||
@@ -158,17 +170,17 @@ static void test_prog_type_by_name(const struct sec_name_test *test)
|
||||
&expected_attach_type);
|
||||
|
||||
CHECK(rc != test->expected_load.rc, "check_code",
|
||||
"prog: unexpected rc=%d for %s", rc, test->sec_name);
|
||||
"prog: unexpected rc=%d for %s\n", rc, test->sec_name);
|
||||
|
||||
if (rc)
|
||||
return;
|
||||
|
||||
CHECK(prog_type != test->expected_load.prog_type, "check_prog_type",
|
||||
"prog: unexpected prog_type=%d for %s",
|
||||
"prog: unexpected prog_type=%d for %s\n",
|
||||
prog_type, test->sec_name);
|
||||
|
||||
CHECK(expected_attach_type != test->expected_load.expected_attach_type,
|
||||
"check_attach_type", "prog: unexpected expected_attach_type=%d for %s",
|
||||
"check_attach_type", "prog: unexpected expected_attach_type=%d for %s\n",
|
||||
expected_attach_type, test->sec_name);
|
||||
}
|
||||
|
||||
@@ -180,13 +192,13 @@ static void test_attach_type_by_name(const struct sec_name_test *test)
|
||||
rc = libbpf_attach_type_by_name(test->sec_name, &attach_type);
|
||||
|
||||
CHECK(rc != test->expected_attach.rc, "check_ret",
|
||||
"attach: unexpected rc=%d for %s", rc, test->sec_name);
|
||||
"attach: unexpected rc=%d for %s\n", rc, test->sec_name);
|
||||
|
||||
if (rc)
|
||||
return;
|
||||
|
||||
CHECK(attach_type != test->expected_attach.attach_type,
|
||||
"check_attach_type", "attach: unexpected attach_type=%d for %s",
|
||||
"check_attach_type", "attach: unexpected attach_type=%d for %s\n",
|
||||
attach_type, test->sec_name);
|
||||
}
|
||||
|
||||
|
Referencia en una nueva incidencia
Block a user