Re: [ndctl PATCH] test/fwctl: Add Get Feature OOB rejection regression test
From: Alison Schofield
Date: Tue Jun 30 2026 - 14:31:46 EST
On Wed, Jun 24, 2026 at 10:00:06PM +0800, Richard Cheng wrote:
> Add a negative case to the CXL fwctl test that issues a Get Feature
> FWCTL_RPC with out_len == offset(struct fwctl_rpc_cxl_out, payload) and
> a non-zero count. The kernel must reject this with -EINVAL instead of
> writing the feature payload past the rpc_out buffer.
>
> This is the userspace regression test for corresponding kernel fix [1].
>
> [1]: https://lore.kernel.org/all/20260624134737.49166-1-icheng@xxxxxxxxxx/
> Signed-off-by: Richard Cheng <icheng@xxxxxxxxxx>
Thanks Richard!
In the unit tests when we have cases that depend on a specific
kernel fix landing we prefer to gate on that kver. This is a
first though, because the gate needs to be within the C program
not simply using the check_min_kver helper as is done for the
test shell scripts.
I think something like appended would be useful here. See if that
works for you.
I only tested without the fix to confirm it fails the entire fwctl
test. I also stopped short of testing with the fix because I see
another patchset in flight grouping bounds checks and figure you
will come back around and update this test patch similarly.
diff --git a/test/fwctl.c b/test/fwctl.c
index 69d0048c09df..b18a4f10717b 100644
--- a/test/fwctl.c
+++ b/test/fwctl.c
@@ -6,10 +6,12 @@
#include <endian.h>
#include <stdint.h>
#include <stddef.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
#include <unistd.h>
+#include <sys/utsname.h>
#include <sys/ioctl.h>
#include <cxl/libcxl.h>
#include <linux/uuid.h>
@@ -21,6 +23,37 @@
static const char provider[] = "cxl_test";
+/* Running kernel version parsed once in main(). */
+static unsigned int kver_major;
+static unsigned int kver_minor;
+
+/*
+ * kver_ge - is the running kernel at least major.minor?
+ *
+ * The C version of the shell suite's check_min_kver helper.
+ * Test cases for fixes tied to a specific kver, gate here so that test
+ * cases quietly skip rather than fail on kernels that predate the fix.
+ * Acknowledging that doesn't help testing of backports.
+ */
+static bool kver_ge(unsigned int major, unsigned int minor)
+{
+ if (kver_major != major)
+ return kver_major > major;
+ return kver_minor >= minor;
+}
+
+static void parse_kver(void)
+{
+ struct utsname uts;
+
+ if (uname(&uts) == 0 &&
+ sscanf(uts.release, "%u.%u", &kver_major, &kver_minor) == 2)
+ return;
+
+ kver_major = 0;
+ kver_minor = 0;
+}
+
UUID_DEFINE(test_uuid,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff,
@@ -208,6 +241,10 @@ out:
return rc;
}
+/* First kernel release with the Get Feature OOB rejection fix */
+#define GET_FEAT_OOB_FIX_MAJOR 7
+#define GET_FEAT_OOB_FIX_MINOR 3
+
static int cxl_fwctl_rpc_get_feature_oob(int fd, struct test_feature *feat_ctx)
{
struct cxl_mbox_get_feat_in *feat_in;
@@ -217,6 +254,13 @@ static int cxl_fwctl_rpc_get_feature_oob(int fd, struct test_feature *feat_ctx)
struct fwctl_rpc *rpc;
int rc;
+ if (!kver_ge(GET_FEAT_OOB_FIX_MAJOR, GET_FEAT_OOB_FIX_MINOR)) {
+ fprintf(stderr,
+ "skip: Get Feature OOB rejection test needs kernel >= %u.%u\n",
+ GET_FEAT_OOB_FIX_MAJOR, GET_FEAT_OOB_FIX_MINOR);
+ return 0;
+ }
+
in_size = sizeof(*in) + sizeof(*feat_in);
/* header only => zero payload room */
out_size = offsetof(struct fwctl_rpc_cxl_out, payload);
@@ -463,6 +507,8 @@ int main(int argc, char *argv[])
struct cxl_bus *bus;
int rc;
+ parse_kver();
+
rc = cxl_new(&ctx);
if (rc < 0)
return rc;