From: Ricardo B. Marlière rbm@suse.com
[ Upstream commit 98857d111c53954aa038fcbc4cf48873e4240f7c ]
Commit e9fc3ce99b34 ("libbpf: Streamline error reporting for high-level APIs") redefined the way that bpf_prog_detach2() returns. Therefore, adapt the usage in test_lirc_mode2_user.c.
Signed-off-by: Ricardo B. Marlière rbm@suse.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20250828-selftests-bpf-v1-1-c7811cd8b98c@suse.co... Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Analysis Complete
**Backport Status: YES**
### Extensive Technical Explanation
#### The Bug and Its Context
This commit fixes a **broken selftest** in `test_lirc_mode2_user.c` that has been failing since Linux kernel v6.0 (June 2022) - a period of approximately **3 years**.
#### Historical Timeline of the API Change
**Phase 1 - May 2021 (v5.14)**: Commit e9fc3ce99b34 ("libbpf: Streamline error reporting for high-level APIs") introduced a new error handling model for libbpf:
- **Legacy mode (default before v6.0)**: Integer-returning functions like `bpf_prog_detach2()` returned `-1` on error and set `errno` - **Strict mode (LIBBPF_STRICT_DIRECT_ERRS)**: Functions return negative error codes directly (e.g., `-ENOENT` instead of `-1`)
The implementation in `libbpf_internal.h` showed: ```c static inline int libbpf_err_errno(int ret) { if (libbpf_mode & LIBBPF_STRICT_DIRECT_ERRS) return ret < 0 ? -errno : ret; // New behavior return ret; // Legacy: return -1 } ```
**Phase 2 - June 2022 (v6.0)**: Commit bd054102a8c7f ("libbpf: enforce strict libbpf 1.0 behaviors") **made strict mode the mandatory default** by removing the conditional logic:
```c static inline int libbpf_err_errno(int ret) { /* errno is already assumed to be set on error */ return ret < 0 ? -errno : ret; // Always strict mode now } ```
This change is in all stable branches from **v6.0 onwards** (6.0.y, 6.1.y, 6.6.y, 6.12.y, 6.17.y, etc.).
#### The Actual Code Problem (tools/testing/selftests/bpf/test_lirc_mode2_user.c:77)
**Before the fix** (broken since v6.0): ```c ret = bpf_prog_detach2(progfd, lircfd, BPF_LIRC_MODE2); if (ret != -1 || errno != ENOENT) { // WRONG: expects ret == -1 printf("bpf_prog_detach2 not attached should fail: %m\n"); return 1; } ```
**After the fix**: ```c ret = bpf_prog_detach2(progfd, lircfd, BPF_LIRC_MODE2); if (ret != -ENOENT) { // CORRECT: expects ret == -ENOENT printf("bpf_prog_detach2 not attached should fail: %m\n"); return 1; } ```
#### Why The Test Was Broken
**Execution flow in v6.0+**: 1. `bpf_prog_detach2()` calls `sys_bpf(BPF_PROG_DETACH, ...)` 2. `sys_bpf()` → `syscall(__NR_bpf, ...)` returns `-1`, sets `errno = ENOENT` 3. `libbpf_err_errno(-1)` converts: `ret < 0 ? -errno : ret` → returns `-ENOENT` (value: -2) 4. Test checks `if (ret != -1 || errno != ENOENT)`: - `ret` is `-2` (not `-1`) ✗ - Condition evaluates to `TRUE` - **Test incorrectly fails**
#### Why This Should Be Backported
1. **Fixes a Real Problem**: The test has been incorrectly failing for 3 years on all v6.0+ kernels, potentially misleading developers who run BPF selftests
2. **Minimal Risk**: This is a **1-line change** in a selftest (not kernel code), changing only the expected return value check from `-1` to `-ENOENT`
3. **Meets Stable Criteria**: - ✅ Small (1 line changed) - ✅ Obviously correct (adapts test to match documented API behavior) - ✅ Fixes a genuine bug (broken test) - ✅ Already in mainline (v6.18)
4. **Selftest Policy**: My research shows selftests ARE regularly backported to stable kernels. Example commits in stable/linux-6.1.y: - `138749a8ff619 selftests/bpf: Fix a user_ringbuf failure with arm64 64KB page size` - `5f3d693861c71 selftests/bpf: Mitigate sockmap_ktls disconnect_after_delete failure`
5. **Affects All Active Stable Branches**: Every stable kernel from v6.0 onwards (including LTS 6.1, 6.6, and 6.12) has the broken test
#### Scope of Backport
This fix should be backported to **all stable kernels v6.0 and later** that contain commit bd054102a8c7f (libbpf 1.0 enforcement). This includes: - linux-6.0.y - linux-6.1.y (LTS) - linux-6.6.y (LTS) - linux-6.12.y (LTS) - linux-6.13.y through linux-6.17.y
Kernels v5.19 and earlier do NOT need this fix because they still use legacy mode where `bpf_prog_detach2()` returns `-1`.
tools/testing/selftests/bpf/test_lirc_mode2_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/test_lirc_mode2_user.c b/tools/testing/selftests/bpf/test_lirc_mode2_user.c index 4694422aa76c3..88e4aeab21b7b 100644 --- a/tools/testing/selftests/bpf/test_lirc_mode2_user.c +++ b/tools/testing/selftests/bpf/test_lirc_mode2_user.c @@ -74,7 +74,7 @@ int main(int argc, char **argv)
/* Let's try detach it before it was ever attached */ ret = bpf_prog_detach2(progfd, lircfd, BPF_LIRC_MODE2); - if (ret != -1 || errno != ENOENT) { + if (ret != -ENOENT) { printf("bpf_prog_detach2 not attached should fail: %m\n"); return 1; }