[LTP] [PATCH] syscalls/listmount04: Detect backported commit 78f0e33cd6c9 dynamically
Darren Chang
chihsheng@google.com
Wed Jun 3 07:14:01 CEST 2026
Commit 78f0e33cd6c9 ("fs/namespace: correctly handle errors returned
by grab_requested_mnt_ns") changed the expected errno for an invalid
mnt_ns_fd from EINVAL to EBADF. This was introduced in v6.17.9.
Currently, the test relies solely on tst_kvercmp() to determine which
errno to expect. However, this causes the test to fail on older LTS
or Android kernels (e.g., v6.12) that have backported this specific
patch. On these kernels, listmount() correctly returns EBADF, but the
test expects EINVAL purely based on the older kernel version number.
Fix this by introducing a runtime probe in setup(). By issuing a dummy
listmount() syscall with an invalid mnt_ns_fd (-1), we can check the
returned errno and accurately determine the kernel's behavior regardless
of its version string.
Additionally, rename the 'kver' variable to 'current_fd_err_behavior'
and update the macros to clearly reflect the expected errno behavior
(INVALID_FD_RET_EINVAL vs INVALID_FD_RET_EBADF) rather than relying on
version thresholds, improving overall code readability and semantics.
Signed-off-by: Darren Chang <chihsheng@google.com>
---
.../kernel/syscalls/listmount/listmount04.c | 51 ++++++++++++++-----
1 file changed, 39 insertions(+), 12 deletions(-)
diff --git a/testcases/kernel/syscalls/listmount/listmount04.c b/testcases/kernel/syscalls/listmount/listmount04.c
index 919f4c854..38eaffede 100644
--- a/testcases/kernel/syscalls/listmount/listmount04.c
+++ b/testcases/kernel/syscalls/listmount/listmount04.c
@@ -15,22 +15,26 @@
#define _GNU_SOURCE
+#include <errno.h>
#include "config.h"
#include "tst_test.h"
#include "lapi/mount.h"
#include "lapi/syscalls.h"
#define MNT_SIZE 32
+
/*
* For commit 78f0e33cd6c9 ("fs/namespace: correctly handle errors returned
* by grab_requested_mnt_ns") from v6.18-rc7 backported to v6.17.9.
+ * Defines the expected error code behavior when an invalid file descriptor
+ * is passed to mnt_ns_fd (previously known as spare).
*/
-#define BEFORE_6_17_9 1
-#define AFTER_6_17_9 2
+#define INVALID_FD_RET_EINVAL 1
+#define INVALID_FD_RET_EBADF 2
static mnt_id_req *request;
static uint64_t mnt_ids[MNT_SIZE];
-static int kver;
+static int current_fd_err_behavior;
static struct tcase {
int req_usage;
@@ -43,7 +47,7 @@ static struct tcase {
uint64_t flags;
int exp_errno;
char *msg;
- int kver;
+ int fd_err_behavior;
} tcases[] = {
{
.req_usage = 0,
@@ -89,7 +93,7 @@ static struct tcase {
.nr_mnt_ids = MNT_SIZE,
.exp_errno = EINVAL,
.msg = "invalid mnt_id_req.spare",
- .kver = BEFORE_6_17_9,
+ .fd_err_behavior = INVALID_FD_RET_EINVAL,
},
{
.req_usage = 1,
@@ -100,7 +104,7 @@ static struct tcase {
.nr_mnt_ids = MNT_SIZE,
.exp_errno = EBADF,
.msg = "invalid mnt_id_req.mnt_ns_fd",
- .kver = AFTER_6_17_9,
+ .fd_err_behavior = INVALID_FD_RET_EBADF,
},
{
.req_usage = 1,
@@ -137,8 +141,9 @@ static void run(unsigned int n)
struct tcase *tc = &tcases[n];
mnt_id_req *req = NULL;
- if (tc->kver && tc->kver != kver) {
- tst_res(TCONF, "Test not suitable for current kernel version");
+ /* Skip tests that do not match the runtime behavior of current kernel */
+ if (tc->fd_err_behavior && tc->fd_err_behavior != current_fd_err_behavior) {
+ tst_res(TCONF, "Test not suitable for current kernel's FD error behavior");
return;
}
@@ -159,10 +164,32 @@ static void run(unsigned int n)
static void setup(void)
{
- if (tst_kvercmp(6, 17, 9) >= 0)
- kver = AFTER_6_17_9;
- else
- kver = BEFORE_6_17_9;
+ /* 1. If kernel is 6.17.9 or newer, it definitively has the new behavior */
+ if (tst_kvercmp(6, 17, 9) >= 0) {
+ current_fd_err_behavior = INVALID_FD_RET_EBADF;
+ return;
+ }
+
+ /* 2. Runtime probe for older kernels:
+ * Check if commit 78f0e33cd6c9 was backported by manually issuing
+ * a syscall with an invalid mnt_ns_fd (-1).
+ */
+ mnt_id_req probe_req = {
+ .size = MNT_ID_REQ_SIZE_VER0,
+ .mnt_id = LSMT_ROOT,
+ .mnt_ns_fd = -1,
+ .param = 0
+ };
+
+ tst_syscall(__NR_listmount, &probe_req, mnt_ids, MNT_SIZE, 0);
+
+ /* 3. Set global behavior flag based on actual kernel response */
+ if (errno == EBADF) {
+ tst_res(TINFO, "Detected backported commit 78f0e33cd6c9 (returns EBADF)");
+ current_fd_err_behavior = INVALID_FD_RET_EBADF;
+ } else {
+ current_fd_err_behavior = INVALID_FD_RET_EINVAL;
+ }
}
static struct tst_test test = {
--
2.54.0.1032.g2f8565e1d1-goog
More information about the ltp
mailing list