mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [ndctl PATCH] test/fwctl: Add Get Feature OOB rejection regression test
@ 2026-06-24 14:00 Richard Cheng
  2026-06-30 18:30 ` Alison Schofield
  2026-07-14 19:28 ` Alison Schofield
  0 siblings, 2 replies; 4+ messages in thread
From: Richard Cheng @ 2026-06-24 14:00 UTC (permalink / raw)
  To: dave, jic23, dave.jiang, alison.schofield, vishal.l.verma, djbw,
	danwilliams, nvdimm
  Cc: iweiny, ming.li, kobak, kaihengf, kees, newtonl, kristinc, mochs,
	linux-cxl, linux-kernel, Richard Cheng

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@nvidia.com/
Signed-off-by: Richard Cheng <icheng@nvidia.com>
---
 test/fwctl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/test/fwctl.c b/test/fwctl.c
index 979c1a6..69d0048 100644
--- a/test/fwctl.c
+++ b/test/fwctl.c
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include <endian.h>
 #include <stdint.h>
+#include <stddef.h>
 #include <stdlib.h>
 #include <syslog.h>
 #include <string.h>
@@ -207,6 +208,45 @@ out:
 	return rc;
 }
 
+static int cxl_fwctl_rpc_get_feature_oob(int fd, struct test_feature *feat_ctx)
+{
+	struct cxl_mbox_get_feat_in *feat_in;
+	struct fwctl_rpc_cxl_out *out;
+	size_t out_size, in_size;
+	struct fwctl_rpc_cxl *in;
+	struct fwctl_rpc *rpc;
+	int rc;
+
+	in_size = sizeof(*in) + sizeof(*feat_in);
+	/* header only => zero payload room */
+	out_size = offsetof(struct fwctl_rpc_cxl_out, payload);
+
+	rpc = get_prepped_command(in_size, out_size,
+				  CXL_MBOX_OPCODE_GET_FEATURE);
+	if (!rpc)
+		return -ENXIO;
+
+	in = (struct fwctl_rpc_cxl *)rpc->in;
+	out = (struct fwctl_rpc_cxl_out *)rpc->out;
+
+	feat_in = &in->get_feat_in;
+	uuid_copy(feat_in->uuid, feat_ctx->uuid);
+	/* non-zero count that exceeds the zero payload room */
+	feat_in->count = feat_ctx->get_size;
+
+	rc = send_command(fd, rpc, out);
+	free_rpc(rpc);
+
+	if (rc == -EINVAL)
+		return 0;
+	if (rc == 0) {
+		fprintf(stderr, "Get Feature with undersized out_len was not rejected\n");
+		return -ENXIO;
+	}
+	fprintf(stderr, "Get Feature OOB rejection test: unexpected rc %d\n", rc);
+	return rc;
+}
+
 static int cxl_fwctl_rpc_set_test_feature(int fd, struct test_feature *feat_ctx)
 {
 	struct cxl_mbox_set_feat_in *feat_in;
@@ -393,6 +433,12 @@ static int test_fwctl_features(struct cxl_memdev *memdev)
 		goto out;
 	}
 
+	rc = cxl_fwctl_rpc_get_feature_oob(fd, &feat_ctx);
+	if (rc) {
+		fprintf(stderr, "Failed Get Feature OOB rejection test: %d\n", rc);
+		goto out;
+	}
+
 out:
 	close(fd);
 	return rc;

base-commit: 8ad90e54f0ff4f7291e7f21d44d769d10f24e2b6
-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ndctl PATCH] test/fwctl: Add Get Feature OOB rejection regression test
  2026-06-24 14:00 [ndctl PATCH] test/fwctl: Add Get Feature OOB rejection regression test Richard Cheng
@ 2026-06-30 18:30 ` Alison Schofield
  2026-07-14 19:28 ` Alison Schofield
  1 sibling, 0 replies; 4+ messages in thread
From: Alison Schofield @ 2026-06-30 18:30 UTC (permalink / raw)
  To: Richard Cheng
  Cc: dave, jic23, dave.jiang, vishal.l.verma, djbw, danwilliams,
	nvdimm, iweiny, ming.li, kobak, kaihengf, kees, newtonl,
	kristinc, mochs, linux-cxl, linux-kernel

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@nvidia.com/
> Signed-off-by: Richard Cheng <icheng@nvidia.com>

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;


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ndctl PATCH] test/fwctl: Add Get Feature OOB rejection regression test
  2026-06-24 14:00 [ndctl PATCH] test/fwctl: Add Get Feature OOB rejection regression test Richard Cheng
  2026-06-30 18:30 ` Alison Schofield
@ 2026-07-14 19:28 ` Alison Schofield
  2026-07-16  4:08   ` Richard Cheng
  1 sibling, 1 reply; 4+ messages in thread
From: Alison Schofield @ 2026-07-14 19:28 UTC (permalink / raw)
  To: Richard Cheng
  Cc: dave, jic23, dave.jiang, vishal.l.verma, djbw, danwilliams,
	nvdimm, iweiny, ming.li, kobak, kaihengf, kees, newtonl,
	kristinc, mochs, linux-cxl, linux-kernel

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].

Hi Richard,

I just finished reviewing the now 3 piece series[2], that [1] is now
a piece of.

One suggestion on top of the kver gating suggested in prior response
is to add a companion negative case for the Set Feature bounds fix
in the same series. Same shape as this one, ie build a normal Set
Feature RPC, set out_len to 0, expect -EINVAL. It's a stronger backstop
than the Get case, too because before the fix an out_len of 0 makes
kvzalloc() return ZERO_SIZE_PTR, which passes the !rpc_out check, and
the header write then oopses rather than just returning a wrong status.
Gate it on the same kver helper.

I'm stopping short of suggesting a test for the third patch (the Get
Feature per-iteration clamp). That one looks like it needs a
multi-transfer feature and a device that over returns on the last chunk,
neither possible without a cxl_test mock change.

-- Alison

> [1]: https://lore.kernel.org/all/20260624134737.49166-1-icheng@nvidia.com/
[2]: https://lore.kernel.org/linux-cxl/20260626104102.53892-1-icheng@nvidia.com/#r


> Signed-off-by: Richard Cheng <icheng@nvidia.com>
> ---
>  test/fwctl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
> 
> diff --git a/test/fwctl.c b/test/fwctl.c
> index 979c1a6..69d0048 100644
> --- a/test/fwctl.c
> +++ b/test/fwctl.c
> @@ -5,6 +5,7 @@
>  #include <stdio.h>
>  #include <endian.h>
>  #include <stdint.h>
> +#include <stddef.h>
>  #include <stdlib.h>
>  #include <syslog.h>
>  #include <string.h>
> @@ -207,6 +208,45 @@ out:
>  	return rc;
>  }
>  
> +static int cxl_fwctl_rpc_get_feature_oob(int fd, struct test_feature *feat_ctx)
> +{
> +	struct cxl_mbox_get_feat_in *feat_in;
> +	struct fwctl_rpc_cxl_out *out;
> +	size_t out_size, in_size;
> +	struct fwctl_rpc_cxl *in;
> +	struct fwctl_rpc *rpc;
> +	int rc;
> +
> +	in_size = sizeof(*in) + sizeof(*feat_in);
> +	/* header only => zero payload room */
> +	out_size = offsetof(struct fwctl_rpc_cxl_out, payload);
> +
> +	rpc = get_prepped_command(in_size, out_size,
> +				  CXL_MBOX_OPCODE_GET_FEATURE);
> +	if (!rpc)
> +		return -ENXIO;
> +
> +	in = (struct fwctl_rpc_cxl *)rpc->in;
> +	out = (struct fwctl_rpc_cxl_out *)rpc->out;
> +
> +	feat_in = &in->get_feat_in;
> +	uuid_copy(feat_in->uuid, feat_ctx->uuid);
> +	/* non-zero count that exceeds the zero payload room */
> +	feat_in->count = feat_ctx->get_size;
> +
> +	rc = send_command(fd, rpc, out);
> +	free_rpc(rpc);
> +
> +	if (rc == -EINVAL)
> +		return 0;
> +	if (rc == 0) {
> +		fprintf(stderr, "Get Feature with undersized out_len was not rejected\n");
> +		return -ENXIO;
> +	}
> +	fprintf(stderr, "Get Feature OOB rejection test: unexpected rc %d\n", rc);
> +	return rc;
> +}
> +
>  static int cxl_fwctl_rpc_set_test_feature(int fd, struct test_feature *feat_ctx)
>  {
>  	struct cxl_mbox_set_feat_in *feat_in;
> @@ -393,6 +433,12 @@ static int test_fwctl_features(struct cxl_memdev *memdev)
>  		goto out;
>  	}
>  
> +	rc = cxl_fwctl_rpc_get_feature_oob(fd, &feat_ctx);
> +	if (rc) {
> +		fprintf(stderr, "Failed Get Feature OOB rejection test: %d\n", rc);
> +		goto out;
> +	}
> +
>  out:
>  	close(fd);
>  	return rc;
> 
> base-commit: 8ad90e54f0ff4f7291e7f21d44d769d10f24e2b6
> -- 
> 2.43.0
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [ndctl PATCH] test/fwctl: Add Get Feature OOB rejection regression test
  2026-07-14 19:28 ` Alison Schofield
@ 2026-07-16  4:08   ` Richard Cheng
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Cheng @ 2026-07-16  4:08 UTC (permalink / raw)
  To: Alison Schofield
  Cc: dave, jic23, dave.jiang, vishal.l.verma, djbw, danwilliams,
	nvdimm, iweiny, ming.li, kobak, kaihengf, kees, newtonl,
	kristinc, mochs, linux-cxl, linux-kernel

On Tue, Jul 14, 2026 at 12:28:28PM +0800, Alison Schofield wrote:
> 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].
> 
> Hi Richard,
> 
> I just finished reviewing the now 3 piece series[2], that [1] is now
> a piece of.
> 
> One suggestion on top of the kver gating suggested in prior response
> is to add a companion negative case for the Set Feature bounds fix
> in the same series. Same shape as this one, ie build a normal Set
> Feature RPC, set out_len to 0, expect -EINVAL. It's a stronger backstop
> than the Get case, too because before the fix an out_len of 0 makes
> kvzalloc() return ZERO_SIZE_PTR, which passes the !rpc_out check, and
> the header write then oopses rather than just returning a wrong status.
> Gate it on the same kver helper.
> 
> I'm stopping short of suggesting a test for the third patch (the Get
> Feature per-iteration clamp). That one looks like it needs a
> multi-transfer feature and a device that over returns on the last chunk,
> neither possible without a cxl_test mock change.
> 
> -- Alison
> 
> > [1]: https://lore.kernel.org/all/20260624134737.49166-1-icheng@nvidia.com/
> [2]: https://lore.kernel.org/linux-cxl/20260626104102.53892-1-icheng@nvidia.com/#r
> 
>

Hi Alison,

Thanks for the review. I'll update the ndctl patch to add kernel-version check
and a Set Feature negative test with "out_len=0"

I'll use the same version check for both tsets and send a new version for it.

As for the Get Feature per-iteration clamp, I'll also work on extending cxl_test
with the required mock behavior. I'll send the cxl_test change and its regression
test as follow-up patches.

--Richard
 
> > Signed-off-by: Richard Cheng <icheng@nvidia.com>
> > ---
> >  test/fwctl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 46 insertions(+)
> > 
> > diff --git a/test/fwctl.c b/test/fwctl.c
> > index 979c1a6..69d0048 100644
> > --- a/test/fwctl.c
> > +++ b/test/fwctl.c
> > @@ -5,6 +5,7 @@
> >  #include <stdio.h>
> >  #include <endian.h>
> >  #include <stdint.h>
> > +#include <stddef.h>
> >  #include <stdlib.h>
> >  #include <syslog.h>
> >  #include <string.h>
> > @@ -207,6 +208,45 @@ out:
> >  	return rc;
> >  }
> >  
> > +static int cxl_fwctl_rpc_get_feature_oob(int fd, struct test_feature *feat_ctx)
> > +{
> > +	struct cxl_mbox_get_feat_in *feat_in;
> > +	struct fwctl_rpc_cxl_out *out;
> > +	size_t out_size, in_size;
> > +	struct fwctl_rpc_cxl *in;
> > +	struct fwctl_rpc *rpc;
> > +	int rc;
> > +
> > +	in_size = sizeof(*in) + sizeof(*feat_in);
> > +	/* header only => zero payload room */
> > +	out_size = offsetof(struct fwctl_rpc_cxl_out, payload);
> > +
> > +	rpc = get_prepped_command(in_size, out_size,
> > +				  CXL_MBOX_OPCODE_GET_FEATURE);
> > +	if (!rpc)
> > +		return -ENXIO;
> > +
> > +	in = (struct fwctl_rpc_cxl *)rpc->in;
> > +	out = (struct fwctl_rpc_cxl_out *)rpc->out;
> > +
> > +	feat_in = &in->get_feat_in;
> > +	uuid_copy(feat_in->uuid, feat_ctx->uuid);
> > +	/* non-zero count that exceeds the zero payload room */
> > +	feat_in->count = feat_ctx->get_size;
> > +
> > +	rc = send_command(fd, rpc, out);
> > +	free_rpc(rpc);
> > +
> > +	if (rc == -EINVAL)
> > +		return 0;
> > +	if (rc == 0) {
> > +		fprintf(stderr, "Get Feature with undersized out_len was not rejected\n");
> > +		return -ENXIO;
> > +	}
> > +	fprintf(stderr, "Get Feature OOB rejection test: unexpected rc %d\n", rc);
> > +	return rc;
> > +}
> > +
> >  static int cxl_fwctl_rpc_set_test_feature(int fd, struct test_feature *feat_ctx)
> >  {
> >  	struct cxl_mbox_set_feat_in *feat_in;
> > @@ -393,6 +433,12 @@ static int test_fwctl_features(struct cxl_memdev *memdev)
> >  		goto out;
> >  	}
> >  
> > +	rc = cxl_fwctl_rpc_get_feature_oob(fd, &feat_ctx);
> > +	if (rc) {
> > +		fprintf(stderr, "Failed Get Feature OOB rejection test: %d\n", rc);
> > +		goto out;
> > +	}
> > +
> >  out:
> >  	close(fd);
> >  	return rc;
> > 
> > base-commit: 8ad90e54f0ff4f7291e7f21d44d769d10f24e2b6
> > -- 
> > 2.43.0
> > 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-07-16  4:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-24 14:00 [ndctl PATCH] test/fwctl: Add Get Feature OOB rejection regression test Richard Cheng
2026-06-30 18:30 ` Alison Schofield
2026-07-14 19:28 ` Alison Schofield
2026-07-16  4:08   ` Richard Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox