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/[email protected]/
> Signed-off-by: Richard Cheng <[email protected]>

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;


Reply via email to