The ndtest provider validates get/set config-data requests by adding the ioctl-provided offset and length and comparing the result against LABEL_SIZE. That addition can wrap, so an offset such as U32_MAX with a one-byte length passes validation and then copies from or to label_area + U32_MAX.
Validate the command buffer shape, then validate the offset first and validate the length against the remaining label area so wrapped ranges are rejected before the copy. Report the rejection through the command status field so the DIMM ioctl ABI returns a nonzero command status instead of faulting. Assisted-by: Codex:gpt-5.5-cyber-preview Signed-off-by: Samuel Moelius <[email protected]> --- tools/testing/nvdimm/test/ndtest.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test/ndtest.c index 8e3b6be53839..1df93f5e4cb6 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -207,9 +207,15 @@ static int ndtest_config_get(struct ndtest_dimm *p, unsigned int buf_len, { unsigned int len; - if ((hdr->in_offset + hdr->in_length) > LABEL_SIZE) + if (buf_len < sizeof(*hdr) || hdr->in_length > buf_len - sizeof(*hdr)) return -EINVAL; + if (hdr->in_offset > LABEL_SIZE || + hdr->in_length > LABEL_SIZE - hdr->in_offset) { + hdr->status = -EINVAL; + return 0; + } + hdr->status = 0; len = min(hdr->in_length, LABEL_SIZE - hdr->in_offset); memcpy(hdr->out_buf, p->label_area + hdr->in_offset, len); @@ -221,10 +227,20 @@ static int ndtest_config_set(struct ndtest_dimm *p, unsigned int buf_len, struct nd_cmd_set_config_hdr *hdr) { unsigned int len; + u32 *status; - if ((hdr->in_offset + hdr->in_length) > LABEL_SIZE) + if (buf_len < sizeof(*hdr) + sizeof(*status) || + hdr->in_length > buf_len - sizeof(*hdr) - sizeof(*status)) return -EINVAL; + status = (void *)hdr + sizeof(*hdr) + hdr->in_length; + if (hdr->in_offset > LABEL_SIZE || + hdr->in_length > LABEL_SIZE - hdr->in_offset) { + *status = -EINVAL; + return 0; + } + + *status = 0; len = min(hdr->in_length, LABEL_SIZE - hdr->in_offset); memcpy(p->label_area + hdr->in_offset, hdr->in_buf, len); -- 2.43.0

