{"id":"CVE-2026-89571","state":"PUBLISHED","title":"cxl/features: bound fwctl command payload to the input buffer","description":"In the Linux kernel, the following vulnerability has been resolved:\n\ncxl/features: bound fwctl command payload to the input buffer\n\nfwctl_cmd_rpc() copies cmd->in_len bytes into inbuf = kvzalloc(cmd->in_len)\nand passes inbuf and in_len to ->fw_rpc(). The CXL callback cxlctl_fw_rpc()\nignores in_len and never checks the user-controlled op_size against it.\n\ncxlctl_set_feature() bounds op_size only from below\n(op_size <= sizeof(feat_in->hdr)) and then reads op_size - sizeof(hdr)\nbytes from feat_in->feat_data via cxl_set_feature(). With a small in_len\nand a large op_size the first memcpy() already reads past the\nkvzalloc(in_len) buffer; the out-of-bounds bytes are placed in the mailbox\npayload and sent to the device, and a large enough op_size can walk into\nunmapped memory and oops the kernel. The Get paths pin op_size to a fixed\nsize but likewise read the input struct without checking in_len.\n\nReject, at the single dispatch point, any request whose fixed header plus\nop_size does not fit in the copied-in buffer. The lower-bound test guards\nthe subtraction and ensures op_size was copied in before it is read.","publishedAt":"2026-09-11T19:44:40.328Z","updatedAt":"2026-10-19T08:49:04.541Z","severity":{"score":7.1,"label":"High","version":"3.1","vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H","source":"Linux"},"assigner":"Linux","products":["Linux Linux"],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"eb5dfcb9e36d0e46089fec777d911313c1876fa3","status":"affected","lessThan":"14d52c15d5d99477b20a2d61fe36f347080da6cd","versionType":"git"},{"version":"eb5dfcb9e36d0e46089fec777d911313c1876fa3","status":"affected","lessThan":"d8957545fe96f7905791c937758ebfc1ae1e5b17","versionType":"git"},{"version":"eb5dfcb9e36d0e46089fec777d911313c1876fa3","status":"affected","lessThan":"f687394af983df5660b6afae7e0d06969f3af206","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/cxl/core/features.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"6.15","status":"affected"},{"version":"0","status":"unaffected","lessThan":"6.15","versionType":"semver"},{"version":"6.18.50","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.4","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/cxl/core/features.c"]}],"references":["https://git.kernel.org/stable/c/14d52c15d5d99477b20a2d61fe36f347080da6cd","https://git.kernel.org/stable/c/d8957545fe96f7905791c937758ebfc1ae1e5b17","https://git.kernel.org/stable/c/f687394af983df5660b6afae7e0d06969f3af206"],"weaknesses":[],"ingestedAt":"2026-10-29T20:13:26.108Z","source":{"repository":"CVEProject/cvelistV5","path":"cves/2026/89xxx/CVE-2026-89571.json","commit":"556c9d3a8cd17e218bb8e452ba7cd619a384ff47"},"raw":{"dataType":"CVE_RECORD","dataVersion":"5.2","cveMetadata":{"cveId":"CVE-2026-89571","state":"PUBLISHED","datePublished":"2026-09-11T19:44:40.328Z","dateUpdated":"2026-10-19T08:49:04.541Z","assignerShortName":"Linux","assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateReserved":"2026-09-11T19:38:34.726Z"},"containers":{"cna":{"title":"cxl/features: bound fwctl command payload to the input buffer","descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\ncxl/features: bound fwctl command payload to the input buffer\n\nfwctl_cmd_rpc() copies cmd->in_len bytes into inbuf = kvzalloc(cmd->in_len)\nand passes inbuf and in_len to ->fw_rpc(). The CXL callback cxlctl_fw_rpc()\nignores in_len and never checks the user-controlled op_size against it.\n\ncxlctl_set_feature() bounds op_size only from below\n(op_size <= sizeof(feat_in->hdr)) and then reads op_size - sizeof(hdr)\nbytes from feat_in->feat_data via cxl_set_feature(). With a small in_len\nand a large op_size the first memcpy() already reads past the\nkvzalloc(in_len) buffer; the out-of-bounds bytes are placed in the mailbox\npayload and sent to the device, and a large enough op_size can walk into\nunmapped memory and oops the kernel. The Get paths pin op_size to a fixed\nsize but likewise read the input struct without checking in_len.\n\nReject, at the single dispatch point, any request whose fixed header plus\nop_size does not fit in the copied-in buffer. The lower-bound test guards\nthe subtraction and ensures op_size was copied in before it is read."}],"affected":[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","versions":[{"version":"eb5dfcb9e36d0e46089fec777d911313c1876fa3","status":"affected","lessThan":"14d52c15d5d99477b20a2d61fe36f347080da6cd","versionType":"git"},{"version":"eb5dfcb9e36d0e46089fec777d911313c1876fa3","status":"affected","lessThan":"d8957545fe96f7905791c937758ebfc1ae1e5b17","versionType":"git"},{"version":"eb5dfcb9e36d0e46089fec777d911313c1876fa3","status":"affected","lessThan":"f687394af983df5660b6afae7e0d06969f3af206","versionType":"git"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/cxl/core/features.c"]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","versions":[{"version":"6.15","status":"affected"},{"version":"0","status":"unaffected","lessThan":"6.15","versionType":"semver"},{"version":"6.18.50","status":"unaffected","lessThanOrEqual":"6.18.*","versionType":"semver"},{"version":"7.2.4","status":"unaffected","lessThanOrEqual":"7.2.*","versionType":"semver"},{"version":"7.3","status":"unaffected","lessThanOrEqual":"*","versionType":"original_commit_for_fix"}],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","programFiles":["drivers/cxl/core/features.c"]}],"references":[{"url":"https://git.kernel.org/stable/c/14d52c15d5d99477b20a2d61fe36f347080da6cd"},{"url":"https://git.kernel.org/stable/c/d8957545fe96f7905791c937758ebfc1ae1e5b17"},{"url":"https://git.kernel.org/stable/c/f687394af983df5660b6afae7e0d06969f3af206"}],"metrics":[{"cvssV3_1":{"version":"3.1","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H","baseScore":7.1,"baseSeverity":"HIGH"},"scenarios":[{"lang":"en","value":"AV:L - The bug is reached only via local ioctl(FWCTL_RPC) on /dev/fwctl/fwctlN through fwctl_fops_ioctl()->fwctl_cmd_rpc()->cxlctl_fw_rpc(); CXL features/fwctl has no network, adjacent-radio, or physical-bus entry point.\nAC:L - The attacker fully controls fwctl_rpc.in_len and fwctl_rpc_cxl.op_size; a short in_len with a large op_size, or in_len=0, deterministically over-reads the kvzalloc buffer or dereferences ZERO_SIZE_PTR. No race or attacker-uncontrollable layout is required.\nPR:L - GET commands run at FWCTL_RPC_CONFIGURATION with no capability check, and SET_FEATURE for reset-effect features needs only FWCTL_RPC_DEBUG_WRITE (no CAP_SYS_RAWIO). Per CNA fwctl precedent, /dev/fwctl access is routinely granted to management/VMM users without init-namespace root.\nUI:N - The attacker opens the fwctl device and issues the RPC ioctl themselves; no victim action such as mounting a filesystem or opening a file is required.\nS:U - The heap over-read, mailbox copy, and any oops stay inside the host kernel CXL/fwctl code. This is ordinary same-host kernel impact, not a VM escape, IOMMU bypass, or other changed-scope boundary.\nC:H - cxl_set_feature() memcpy()s attacker-chosen op_size bytes from past the kvzalloc(in_len) buffer into the CXL mailbox and to the device; that unbounded kernel-heap over-read is C:H per kernel CNA guidance, and GET_FEATURE can return stored feature data including leaked heap.\nI:N - The defect is a read-only over-read into a newly allocated mailbox buffer sent to the device; there is no kernel out-of-bounds write, use-after-free, or control-flow hijack primitive.\nA:H - A large op_size walks from the short kvzalloc buffer into unmapped memory and oopses, and in_len=0 makes kvzalloc return ZERO_SIZE_PTR so reading opcode faults; either path panics the kernel and is repeatable at will."}]}],"providerMetadata":{"shortName":"Linux","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","dateUpdated":"2026-10-19T08:49:04.541Z"},"cpeApplicability":[{"nodes":[{"operator":"OR","negate":false,"cpeMatch":[{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.15","versionEndExcluding":"6.18.50"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.15","versionEndExcluding":"7.2.4"},{"vulnerable":true,"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionStartIncluding":"6.15","versionEndExcluding":"7.3"}]}]}],"x_generator":{"engine":"bippy-1.2.0"}}}}}