From patchwork Sun Apr 28 03:09:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13645818 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D3C415A4 for ; Sun, 28 Apr 2024 03:09:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714273799; cv=none; b=n4ZCYKRt9B5t2DkmkSiz42VH6QyEh1n4ZNV0RP9AHD5QVaG+P/Unqjl7xLs34+qtixP3u9+kSZgu3KXwCWOGh7pAHbvArL5D29G6hqx6huKRSS6epjpfcvdaN7UnFDgpXLjdfAAUze0kaYq2A//aQQN50FJydgKQWtWU8dqZc5E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714273799; c=relaxed/simple; bh=M+f6FGX/NlpWY2UAW4CMRy1hoWIOuV8ddiIs7DCIe9k=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=iKgonTNR/t6mGSNMzrhY+so8KiGiypexvIAv6+vCLJqxvWOkuQHTAIMWA9MXB4TE2kKRjuJSUmSj3kcexh8uKEuOSYaL1t+xNaSTWNbHUCr/WnsbJSilgUK3qTeqN6K1J2UAbVIpOBOXS4LC6BG+CPgoFG+RMY1B6gA5sa/4ZXU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E9qNGKpA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="E9qNGKpA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69FC7C4AF17; Sun, 28 Apr 2024 03:09:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714273798; bh=M+f6FGX/NlpWY2UAW4CMRy1hoWIOuV8ddiIs7DCIe9k=; h=From:To:Cc:Subject:Date:From; b=E9qNGKpAwnXCRVwaFypJDYW3nXN8wMNLH36R38C7M7o5cE5zhHv4DFBUiZ9szHJwR FSWZN4v6uyaq3KfGg/Qt9h1Wn2fIBKKlbnUhNmXAFgfYiI9QfOIawKM8HXe9r/qN4u TXz+Go8kbb20H3lKf1S0jCWv6K3q2hqw7f44a4l6qxy+MglowurJGp6AP5N1BwMHkk EzEdXN/+vesC17JqTMoecCBUwVilcWmEHsE8e8SSFtqvN6/dfD2157RimZV5KtZxQu d1x2TWexC4MZMCcuF/t2kCZNLzg0Ny37C7nMu6uPItxPSLk4Zk29Hm1+I1bj976DHg /lHdksqZO6Qag== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: andrii@kernel.org, kernel-team@meta.com Subject: [PATCH bpf-next 1/2] libbpf: handle nulled-out program in struct_ops correctly Date: Sat, 27 Apr 2024 20:09:53 -0700 Message-ID: <20240428030954.3918764-1-andrii@kernel.org> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net If struct_ops has one of program callbacks set declaratively and host kernel is old and doesn't support this callback, libbpf will allow to load such struct_ops as long as that callback was explicitly nulled-out (presumably through skeleton). This is all working correctly, except we won't reset corresponding program slot to NULL before bailing out, which will lead to libbpf not detecting that BPF program has to be not auto-loaded. Fix this by unconditionally resetting corresponding program slot to NULL. Fixes: c911fc61a7ce ("libbpf: Skip zeroed or null fields if not found in the kernel type.") Signed-off-by: Andrii Nakryiko --- tools/lib/bpf/libbpf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 97eb6e5dd7c8..898d5d34ecea 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -1148,6 +1148,7 @@ static int bpf_map__init_kern_struct_ops(struct bpf_map *map) * presented in the kernel BTF. */ if (libbpf_is_mem_zeroed(mdata, msize)) { + st_ops->progs[i] = NULL; pr_info("struct_ops %s: member %s not found in kernel, skipping it as it's set to zero\n", map->name, mname); continue; From patchwork Sun Apr 28 03:09:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13645819 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C93820ED for ; Sun, 28 Apr 2024 03:10:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714273802; cv=none; b=dojvc51ZwK5TLZZt3mv9x5JY0VqdPY6H8kQisR9Q//eIEKaTlmEek4QqEvyZCt0Q08Ukgu9glS+ny+h7OOpxmlGfb9waZrvX9Xn05TfQDCrJOnnC6Cy4HkzZWElLDog0SU1A/xwHXuuBC7531uAD8BtzbtqD8VL7mukxww2bFRU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714273802; c=relaxed/simple; bh=f3ERFM9Oj5nWnafsoH+s7sxf2OiWiW9ATrnjp9gISoU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=G7/TV1op2txl8pyUEg9Kq1knUvMgv5WoR/MD/zDP+ha+l4k98POvvYM5L70n9hlQj8VD7YSHbmCrqeSdDx17UKG8yrRfwX0aaq1a684gdqdGd68v6zaKmv1Pi8wxCvoNPmIXL72Eowp9qdf5o7GugEg5llxzj9lAP8fK1+2Qyeg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MAa0tBlv; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MAa0tBlv" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A40ABC4AF17; Sun, 28 Apr 2024 03:10:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714273801; bh=f3ERFM9Oj5nWnafsoH+s7sxf2OiWiW9ATrnjp9gISoU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MAa0tBlvus6oNXBbcPGUbru+p+R/4Aft1ZAvPnuy1V6AOh5qn/YP0APSu2ZxlyINN ibT3DbrhQsLwMsckVjEq7b+X5xC0SIBeypqNk0fJcRzho2yFv39E7NPR3YfQuFBQNS ypDsnX4eU3JT3s9HLuipIr/qxseAE8yAdMAVvckJ/tZnbz8455EZS/l3O4VZS+zHtF yTXKleiMP7RSYYZv6Puo7a4Vktqpy6MrYSlxtvrtfaF+WcbUVSQH2ioGl5dhcD0hBY 3txMjTxxIedhnUiHSTyWkKZexje3uPM3BrFtZiBC7dn4wwr1G6zES9wrLPJ0mkcz+D um2CB8C6fjUxg== From: Andrii Nakryiko To: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, martin.lau@kernel.org Cc: andrii@kernel.org, kernel-team@meta.com Subject: [PATCH bpf-next 2/2] selftests/bpf: validate nulled-out struct_ops program is handled properly Date: Sat, 27 Apr 2024 20:09:54 -0700 Message-ID: <20240428030954.3918764-2-andrii@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240428030954.3918764-1-andrii@kernel.org> References: <20240428030954.3918764-1-andrii@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net Add a selftests validating that it's possible to have some struct_ops callback set declaratively, then disable it (by setting to NULL) programmatically. Libbpf should detect that such program should be loaded, even if host kernel doesn't have type information for it. Signed-off-by: Andrii Nakryiko --- .../bpf/prog_tests/test_struct_ops_module.c | 18 ++++++++++++++++-- .../selftests/bpf/progs/struct_ops_module.c | 7 +++++++ 2 files changed, 23 insertions(+), 2 deletions(-) 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 7cf2b9ddd3e1..bd39586abd5a 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 @@ -66,6 +66,7 @@ static void test_struct_ops_load(void) * auto-loading, or it will fail to load. */ bpf_program__set_autoload(skel->progs.test_2, false); + bpf_map__set_autocreate(skel->maps.testmod_zeroed, false); err = struct_ops_module__load(skel); if (!ASSERT_OK(err, "struct_ops_module_load")) @@ -103,6 +104,10 @@ static void test_struct_ops_not_zeroed(void) if (!ASSERT_OK_PTR(skel, "struct_ops_module_open")) return; + skel->struct_ops.testmod_zeroed->zeroed = 0; + /* zeroed_op prog should be not loaded automatically now */ + skel->struct_ops.testmod_zeroed->zeroed_op = NULL; + err = struct_ops_module__load(skel); ASSERT_OK(err, "struct_ops_module_load"); @@ -118,6 +123,7 @@ static void test_struct_ops_not_zeroed(void) * value of "zeroed" is non-zero. */ skel->struct_ops.testmod_zeroed->zeroed = 0xdeadbeef; + skel->struct_ops.testmod_zeroed->zeroed_op = NULL; err = struct_ops_module__load(skel); ASSERT_ERR(err, "struct_ops_module_load_not_zeroed"); @@ -148,15 +154,23 @@ static void test_struct_ops_incompatible(void) { struct struct_ops_module *skel; struct bpf_link *link; + int err; - skel = struct_ops_module__open_and_load(); - if (!ASSERT_OK_PTR(skel, "open_and_load")) + skel = struct_ops_module__open(); + if (!ASSERT_OK_PTR(skel, "struct_ops_module_open")) return; + bpf_map__set_autocreate(skel->maps.testmod_zeroed, false); + + err = struct_ops_module__load(skel); + if (!ASSERT_OK(err, "skel_load")) + goto cleanup; + link = bpf_map__attach_struct_ops(skel->maps.testmod_incompatible); if (ASSERT_OK_PTR(link, "attach_struct_ops")) bpf_link__destroy(link); +cleanup: struct_ops_module__destroy(skel); } diff --git a/tools/testing/selftests/bpf/progs/struct_ops_module.c b/tools/testing/selftests/bpf/progs/struct_ops_module.c index 63b065dae002..40109be2b3ae 100644 --- a/tools/testing/selftests/bpf/progs/struct_ops_module.c +++ b/tools/testing/selftests/bpf/progs/struct_ops_module.c @@ -63,10 +63,17 @@ struct bpf_testmod_ops___zeroed { int zeroed; }; +SEC("?struct_ops/test_3") +int BPF_PROG(zeroed_op) +{ + return 1; +} + SEC(".struct_ops.link") struct bpf_testmod_ops___zeroed testmod_zeroed = { .test_1 = (void *)test_1, .test_2 = (void *)test_2_v2, + .zeroed_op = (void *)zeroed_op, }; struct bpf_testmod_ops___incompatible {