[PATCH bpf-next v1 14/14] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()

Ihor Solodrai posted 14 patches 1 month, 2 weeks ago
There is a newer version of this series
[PATCH bpf-next v1 14/14] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
Posted by Ihor Solodrai 1 month, 2 weeks ago
The bpftool_maps_access and bpftool_metadata tests may fail on BPF CI
with "command not found", depending on a workflow.
This happens because detect_bpftool_path() only checks two hardcoded
relative paths:
  - ./tools/sbin/bpftool
  - ../tools/sbin/bpftool

Add support for a BPFTOOL environment variable that allows specifying
the exact path to the bpftool binary.

Also replace strncpy() with snprintf() for proper null-termination.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/testing/selftests/bpf/bpftool_helpers.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/bpf/bpftool_helpers.c b/tools/testing/selftests/bpf/bpftool_helpers.c
index a5824945a4a5..5435ecd720d1 100644
--- a/tools/testing/selftests/bpf/bpftool_helpers.c
+++ b/tools/testing/selftests/bpf/bpftool_helpers.c
@@ -12,13 +12,21 @@
 static int detect_bpftool_path(char *buffer)
 {
 	char tmp[BPFTOOL_PATH_MAX_LEN];
+	const char *env_path;
+
+	/* First, check if BPFTOOL environment variable is set */
+	env_path = getenv("BPFTOOL");
+	if (env_path && access(env_path, X_OK) == 0) {
+		snprintf(buffer, BPFTOOL_PATH_MAX_LEN, "%s", env_path);
+		return 0;
+	}
 
 	/* Check default bpftool location (will work if we are running the
 	 * default flavor of test_progs)
 	 */
 	snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "./%s", BPFTOOL_DEFAULT_PATH);
 	if (access(tmp, X_OK) == 0) {
-		strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN);
+		snprintf(buffer, BPFTOOL_PATH_MAX_LEN, "%s", tmp);
 		return 0;
 	}
 
@@ -27,7 +35,7 @@ static int detect_bpftool_path(char *buffer)
 	 */
 	snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "../%s", BPFTOOL_DEFAULT_PATH);
 	if (access(tmp, X_OK) == 0) {
-		strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN);
+		snprintf(buffer, BPFTOOL_PATH_MAX_LEN, "%s", tmp);
 		return 0;
 	}
 
-- 
2.53.0
Re: [PATCH bpf-next v1 14/14] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
Posted by Alexis Lothoré 1 month, 2 weeks ago
Hi Ihor,

On Thu Feb 12, 2026 at 2:13 AM CET, Ihor Solodrai wrote:
> The bpftool_maps_access and bpftool_metadata tests may fail on BPF CI
> with "command not found", depending on a workflow.
> This happens because detect_bpftool_path() only checks two hardcoded
> relative paths:
>   - ./tools/sbin/bpftool
>   - ../tools/sbin/bpftool
>
> Add support for a BPFTOOL environment variable that allows specifying
> the exact path to the bpftool binary.
>
> Also replace strncpy() with snprintf() for proper null-termination.
>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>

LGTM, thanks for the improvement.

For the record, another issue that this path harcoding is aiming to
solve is that we definitely want a full bpftool binary (as those bpftool
helpers are used to find the binary under test), and not a _bootstrap_
version, which only exposes a few subcommands instead of the whole set.
So I'd say that it is not an issue yet, but it may be worth in the
future to enrich the checks in detect_bpftool_path to make sure that any
bpftool binary path provided by BPFTOOL env var is not pointing to a
bootstrap version.

Alexis

-- 
Alexis Lothoré, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Re: [PATCH bpf-next v1 14/14] selftests/bpf: Check BPFTOOL env var in detect_bpftool_path()
Posted by Mykyta Yatsenko 1 month, 2 weeks ago
On 2/12/26 01:13, Ihor Solodrai wrote:
> The bpftool_maps_access and bpftool_metadata tests may fail on BPF CI
> with "command not found", depending on a workflow.
> This happens because detect_bpftool_path() only checks two hardcoded
> relative paths:
>    - ./tools/sbin/bpftool
>    - ../tools/sbin/bpftool
>
> Add support for a BPFTOOL environment variable that allows specifying
> the exact path to the bpftool binary.
>
> Also replace strncpy() with snprintf() for proper null-termination.
>
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---
>   tools/testing/selftests/bpf/bpftool_helpers.c | 12 ++++++++++--
>   1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/bpftool_helpers.c b/tools/testing/selftests/bpf/bpftool_helpers.c
> index a5824945a4a5..5435ecd720d1 100644
> --- a/tools/testing/selftests/bpf/bpftool_helpers.c
> +++ b/tools/testing/selftests/bpf/bpftool_helpers.c
> @@ -12,13 +12,21 @@
>   static int detect_bpftool_path(char *buffer)
>   {
>   	char tmp[BPFTOOL_PATH_MAX_LEN];
> +	const char *env_path;
> +
> +	/* First, check if BPFTOOL environment variable is set */
> +	env_path = getenv("BPFTOOL");
> +	if (env_path && access(env_path, X_OK) == 0) {
nit: we are checking access(path, X_OK) in multiple places in this function,
but never report any failures if those checks fail, it may be confusing 
for user,
as file is there but function fails to find bpftool binary.
> +		snprintf(buffer, BPFTOOL_PATH_MAX_LEN, "%s", env_path);
> +		return 0;
> +	}
>   
>   	/* Check default bpftool location (will work if we are running the
>   	 * default flavor of test_progs)
>   	 */
>   	snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "./%s", BPFTOOL_DEFAULT_PATH);
>   	if (access(tmp, X_OK) == 0) {
> -		strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN);
> +		snprintf(buffer, BPFTOOL_PATH_MAX_LEN, "%s", tmp);
>   		return 0;
>   	}
>   
> @@ -27,7 +35,7 @@ static int detect_bpftool_path(char *buffer)
>   	 */
>   	snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "../%s", BPFTOOL_DEFAULT_PATH);
>   	if (access(tmp, X_OK) == 0) {
> -		strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN);
> +		snprintf(buffer, BPFTOOL_PATH_MAX_LEN, "%s", tmp);
>   		return 0;
>   	}
>