* [PATCH 0/2] cxl/mbox: fix undersized payload handling in cxl_payload_from_user_allowed()
@ 2026-02-20 0:16 Davidlohr Bueso
2026-02-20 0:16 ` [PATCH 1/2] cxl/mbox: validate payload size before accessing contents " Davidlohr Bueso
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Davidlohr Bueso @ 2026-02-20 0:16 UTC (permalink / raw)
To: dave.jiang
Cc: jonathan.cameron, alison.schofield, vishal.l.verma, ira.weiny,
dan.j.williams, linux-cxl, Davidlohr Bueso
Hi,
The first patch fixes a KSAN splat uncovered by cxl fuzzying, the second
is a follow up for maintain proper error code semantics.
Applies against 'next' from cxl.git.
Thanks!
Davidlohr Bueso (2):
cxl/mbox: validate payload size before accessing contents in cxl_payload_from_user_allowed()
cxl/mbox: return appropriate error in cxl_payload_from_user_allowed()
drivers/cxl/core/mbox.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH 1/2] cxl/mbox: validate payload size before accessing contents in cxl_payload_from_user_allowed() 2026-02-20 0:16 [PATCH 0/2] cxl/mbox: fix undersized payload handling in cxl_payload_from_user_allowed() Davidlohr Bueso @ 2026-02-20 0:16 ` Davidlohr Bueso 2026-02-23 19:23 ` Alison Schofield 2026-02-23 22:39 ` Dave Jiang 2026-02-20 0:16 ` [PATCH 2/2] cxl/mbox: return appropriate error " Davidlohr Bueso 2026-02-20 17:23 ` [PATCH 0/2] cxl/mbox: fix undersized payload handling " Dave Jiang 2 siblings, 2 replies; 11+ messages in thread From: Davidlohr Bueso @ 2026-02-20 0:16 UTC (permalink / raw) To: dave.jiang Cc: jonathan.cameron, alison.schofield, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl, Davidlohr Bueso cxl_payload_from_user_allowed() casts and dereferences the input payload without first verifying its size. When a raw mailbox command is sent with an undersized payload (ie: 1 byte for CXL_MBOX_OP_CLEAR_LOG, which expects a 16-byte UUID), uuid_equal() reads past the allocated buffer, triggering a KASAN splat: BUG: KASAN: slab-out-of-bounds in memcmp+0x176/0x1d0 lib/string.c:683 Read of size 8 at addr ffff88810130f5c0 by task syz.1.62/2258 CPU: 2 UID: 0 PID: 2258 Comm: syz.1.62 Not tainted 6.19.0-dirty #3 PREEMPT(voluntary) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0xab/0xe0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0xce/0x650 mm/kasan/report.c:482 kasan_report+0xce/0x100 mm/kasan/report.c:595 memcmp+0x176/0x1d0 lib/string.c:683 uuid_equal include/linux/uuid.h:73 [inline] cxl_payload_from_user_allowed drivers/cxl/core/mbox.c:345 [inline] cxl_mbox_cmd_ctor drivers/cxl/core/mbox.c:368 [inline] cxl_validate_cmd_from_user drivers/cxl/core/mbox.c:522 [inline] cxl_send_cmd+0x9c0/0xb50 drivers/cxl/core/mbox.c:643 __cxl_memdev_ioctl drivers/cxl/core/memdev.c:698 [inline] cxl_memdev_ioctl+0x14f/0x190 drivers/cxl/core/memdev.c:713 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl fs/ioctl.c:583 [inline] __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xa8/0x330 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fdaf331ba79 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fdaf1d77038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007fdaf3585fa0 RCX: 00007fdaf331ba79 RDX: 00002000000001c0 RSI: 00000000c030ce02 RDI: 0000000000000003 RBP: 00007fdaf33749df R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007fdaf3586038 R14: 00007fdaf3585fa0 R15: 00007ffced2af768 </TASK> Add 'in_size' parameter to cxl_payload_from_user_allowed() and validate the payload is large enough. Fixes: 6179045ccc0c ("cxl/mbox: Block immediate mode in SET_PARTITION_INFO command") Fixes: 206f9fa9d555 ("cxl/mbox: Add Clear Log mailbox command") Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> --- drivers/cxl/core/mbox.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index fa6dd0c94656..e7a6452bf544 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -311,6 +311,7 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) * cxl_payload_from_user_allowed() - Check contents of in_payload. * @opcode: The mailbox command opcode. * @payload_in: Pointer to the input payload passed in from user space. + * @in_size: Size of @payload_in in bytes. * * Return: * * true - payload_in passes check for @opcode. @@ -325,12 +326,15 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) * * The specific checks are determined by the opcode. */ -static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in) +static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in, + size_t in_size) { switch (opcode) { case CXL_MBOX_OP_SET_PARTITION_INFO: { struct cxl_mbox_set_partition_info *pi = payload_in; + if (in_size < sizeof(*pi)) + return false; if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG) return false; break; @@ -338,6 +342,8 @@ static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in) case CXL_MBOX_OP_CLEAR_LOG: { const uuid_t *uuid = (uuid_t *)payload_in; + if (in_size < sizeof(uuid_t)) + return false; /* * Restrict the ‘Clear log’ action to only apply to * Vendor debug logs. @@ -365,7 +371,8 @@ static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, if (IS_ERR(mbox_cmd->payload_in)) return PTR_ERR(mbox_cmd->payload_in); - if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in)) { + if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, + in_size)) { dev_dbg(cxl_mbox->host, "%s: input payload not allowed\n", cxl_mem_opcode_to_name(opcode)); kvfree(mbox_cmd->payload_in); -- 2.39.5 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cxl/mbox: validate payload size before accessing contents in cxl_payload_from_user_allowed() 2026-02-20 0:16 ` [PATCH 1/2] cxl/mbox: validate payload size before accessing contents " Davidlohr Bueso @ 2026-02-23 19:23 ` Alison Schofield 2026-02-23 22:39 ` Dave Jiang 1 sibling, 0 replies; 11+ messages in thread From: Alison Schofield @ 2026-02-23 19:23 UTC (permalink / raw) To: Davidlohr Bueso Cc: dave.jiang, jonathan.cameron, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl On Thu, Feb 19, 2026 at 04:16:17PM -0800, Davidlohr Bueso wrote: > cxl_payload_from_user_allowed() casts and dereferences the input > payload without first verifying its size. When a raw mailbox command > is sent with an undersized payload (ie: 1 byte for CXL_MBOX_OP_CLEAR_LOG, > which expects a 16-byte UUID), uuid_equal() reads past the allocated buffer, > triggering a KASAN splat: > > BUG: KASAN: slab-out-of-bounds in memcmp+0x176/0x1d0 lib/string.c:683 > Read of size 8 at addr ffff88810130f5c0 by task syz.1.62/2258 > > CPU: 2 UID: 0 PID: 2258 Comm: syz.1.62 Not tainted 6.19.0-dirty #3 PREEMPT(voluntary) > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014 > Call Trace: > <TASK> > __dump_stack lib/dump_stack.c:94 [inline] > dump_stack_lvl+0xab/0xe0 lib/dump_stack.c:120 > print_address_description mm/kasan/report.c:378 [inline] > print_report+0xce/0x650 mm/kasan/report.c:482 > kasan_report+0xce/0x100 mm/kasan/report.c:595 > memcmp+0x176/0x1d0 lib/string.c:683 > uuid_equal include/linux/uuid.h:73 [inline] > cxl_payload_from_user_allowed drivers/cxl/core/mbox.c:345 [inline] > cxl_mbox_cmd_ctor drivers/cxl/core/mbox.c:368 [inline] > cxl_validate_cmd_from_user drivers/cxl/core/mbox.c:522 [inline] > cxl_send_cmd+0x9c0/0xb50 drivers/cxl/core/mbox.c:643 > __cxl_memdev_ioctl drivers/cxl/core/memdev.c:698 [inline] > cxl_memdev_ioctl+0x14f/0x190 drivers/cxl/core/memdev.c:713 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:597 [inline] > __se_sys_ioctl fs/ioctl.c:583 [inline] > __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xa8/0x330 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > RIP: 0033:0x7fdaf331ba79 > Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 > RSP: 002b:00007fdaf1d77038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 > RAX: ffffffffffffffda RBX: 00007fdaf3585fa0 RCX: 00007fdaf331ba79 > RDX: 00002000000001c0 RSI: 00000000c030ce02 RDI: 0000000000000003 > RBP: 00007fdaf33749df R08: 0000000000000000 R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 > R13: 00007fdaf3586038 R14: 00007fdaf3585fa0 R15: 00007ffced2af768 > </TASK> > > Add 'in_size' parameter to cxl_payload_from_user_allowed() and validate > the payload is large enough. Reviewed-by: Alison Schofield <alison.schofield@intel.com> > > Fixes: 6179045ccc0c ("cxl/mbox: Block immediate mode in SET_PARTITION_INFO command") > Fixes: 206f9fa9d555 ("cxl/mbox: Add Clear Log mailbox command") > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> snip ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] cxl/mbox: validate payload size before accessing contents in cxl_payload_from_user_allowed() 2026-02-20 0:16 ` [PATCH 1/2] cxl/mbox: validate payload size before accessing contents " Davidlohr Bueso 2026-02-23 19:23 ` Alison Schofield @ 2026-02-23 22:39 ` Dave Jiang 1 sibling, 0 replies; 11+ messages in thread From: Dave Jiang @ 2026-02-23 22:39 UTC (permalink / raw) To: Davidlohr Bueso Cc: jonathan.cameron, alison.schofield, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl On 2/19/26 5:16 PM, Davidlohr Bueso wrote: > cxl_payload_from_user_allowed() casts and dereferences the input > payload without first verifying its size. When a raw mailbox command > is sent with an undersized payload (ie: 1 byte for CXL_MBOX_OP_CLEAR_LOG, > which expects a 16-byte UUID), uuid_equal() reads past the allocated buffer, > triggering a KASAN splat: > > BUG: KASAN: slab-out-of-bounds in memcmp+0x176/0x1d0 lib/string.c:683 > Read of size 8 at addr ffff88810130f5c0 by task syz.1.62/2258 > > CPU: 2 UID: 0 PID: 2258 Comm: syz.1.62 Not tainted 6.19.0-dirty #3 PREEMPT(voluntary) > Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014 > Call Trace: > <TASK> > __dump_stack lib/dump_stack.c:94 [inline] > dump_stack_lvl+0xab/0xe0 lib/dump_stack.c:120 > print_address_description mm/kasan/report.c:378 [inline] > print_report+0xce/0x650 mm/kasan/report.c:482 > kasan_report+0xce/0x100 mm/kasan/report.c:595 > memcmp+0x176/0x1d0 lib/string.c:683 > uuid_equal include/linux/uuid.h:73 [inline] > cxl_payload_from_user_allowed drivers/cxl/core/mbox.c:345 [inline] > cxl_mbox_cmd_ctor drivers/cxl/core/mbox.c:368 [inline] > cxl_validate_cmd_from_user drivers/cxl/core/mbox.c:522 [inline] > cxl_send_cmd+0x9c0/0xb50 drivers/cxl/core/mbox.c:643 > __cxl_memdev_ioctl drivers/cxl/core/memdev.c:698 [inline] > cxl_memdev_ioctl+0x14f/0x190 drivers/cxl/core/memdev.c:713 > vfs_ioctl fs/ioctl.c:51 [inline] > __do_sys_ioctl fs/ioctl.c:597 [inline] > __se_sys_ioctl fs/ioctl.c:583 [inline] > __x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583 > do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] > do_syscall_64+0xa8/0x330 arch/x86/entry/syscall_64.c:94 > entry_SYSCALL_64_after_hwframe+0x77/0x7f > RIP: 0033:0x7fdaf331ba79 > Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 > RSP: 002b:00007fdaf1d77038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 > RAX: ffffffffffffffda RBX: 00007fdaf3585fa0 RCX: 00007fdaf331ba79 > RDX: 00002000000001c0 RSI: 00000000c030ce02 RDI: 0000000000000003 > RBP: 00007fdaf33749df R08: 0000000000000000 R09: 0000000000000000 > R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 > R13: 00007fdaf3586038 R14: 00007fdaf3585fa0 R15: 00007ffced2af768 > </TASK> > > Add 'in_size' parameter to cxl_payload_from_user_allowed() and validate > the payload is large enough. > > Fixes: 6179045ccc0c ("cxl/mbox: Block immediate mode in SET_PARTITION_INFO command") > Fixes: 206f9fa9d555 ("cxl/mbox: Add Clear Log mailbox command") > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> Applied to cxl/fixes 37589c9804b8 > --- > drivers/cxl/core/mbox.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c > index fa6dd0c94656..e7a6452bf544 100644 > --- a/drivers/cxl/core/mbox.c > +++ b/drivers/cxl/core/mbox.c > @@ -311,6 +311,7 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) > * cxl_payload_from_user_allowed() - Check contents of in_payload. > * @opcode: The mailbox command opcode. > * @payload_in: Pointer to the input payload passed in from user space. > + * @in_size: Size of @payload_in in bytes. > * > * Return: > * * true - payload_in passes check for @opcode. > @@ -325,12 +326,15 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) > * > * The specific checks are determined by the opcode. > */ > -static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in) > +static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in, > + size_t in_size) > { > switch (opcode) { > case CXL_MBOX_OP_SET_PARTITION_INFO: { > struct cxl_mbox_set_partition_info *pi = payload_in; > > + if (in_size < sizeof(*pi)) > + return false; > if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG) > return false; > break; > @@ -338,6 +342,8 @@ static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in) > case CXL_MBOX_OP_CLEAR_LOG: { > const uuid_t *uuid = (uuid_t *)payload_in; > > + if (in_size < sizeof(uuid_t)) > + return false; > /* > * Restrict the ‘Clear log’ action to only apply to > * Vendor debug logs. > @@ -365,7 +371,8 @@ static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, > if (IS_ERR(mbox_cmd->payload_in)) > return PTR_ERR(mbox_cmd->payload_in); > > - if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in)) { > + if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, > + in_size)) { > dev_dbg(cxl_mbox->host, "%s: input payload not allowed\n", > cxl_mem_opcode_to_name(opcode)); > kvfree(mbox_cmd->payload_in); ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/2] cxl/mbox: return appropriate error in cxl_payload_from_user_allowed() 2026-02-20 0:16 [PATCH 0/2] cxl/mbox: fix undersized payload handling in cxl_payload_from_user_allowed() Davidlohr Bueso 2026-02-20 0:16 ` [PATCH 1/2] cxl/mbox: validate payload size before accessing contents " Davidlohr Bueso @ 2026-02-20 0:16 ` Davidlohr Bueso 2026-02-20 22:14 ` Alison Schofield ` (3 more replies) 2026-02-20 17:23 ` [PATCH 0/2] cxl/mbox: fix undersized payload handling " Dave Jiang 2 siblings, 4 replies; 11+ messages in thread From: Davidlohr Bueso @ 2026-02-20 0:16 UTC (permalink / raw) To: dave.jiang Cc: jonathan.cameron, alison.schofield, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl, Davidlohr Bueso Make cxl_payload_from_user_allowed() return int such that the it can distinguish between different errors. The payload size failure is not well represented by EBUSY (exclusive access by the kernel). Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> --- drivers/cxl/core/mbox.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index e7a6452bf544..164da335fa33 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -314,8 +314,9 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) * @in_size: Size of @payload_in in bytes. * * Return: - * * true - payload_in passes check for @opcode. - * * false - payload_in contains invalid or unsupported values. + * * %0 - payload_in passes check for @opcode. + * * %-EINVAL - payload_in is too small for the opcode. + * * %-EBUSY - payload_in contains unsupported values. * * The driver may inspect payload contents before sending a mailbox * command from user space to the device. The intent is to reject @@ -326,40 +327,44 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) * * The specific checks are determined by the opcode. */ -static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in, - size_t in_size) +static int cxl_payload_from_user_allowed(u16 opcode, void *payload_in, + size_t in_size) { switch (opcode) { case CXL_MBOX_OP_SET_PARTITION_INFO: { struct cxl_mbox_set_partition_info *pi = payload_in; if (in_size < sizeof(*pi)) - return false; + return -EINVAL; if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG) - return false; + return -EBUSY; break; } case CXL_MBOX_OP_CLEAR_LOG: { const uuid_t *uuid = (uuid_t *)payload_in; if (in_size < sizeof(uuid_t)) - return false; + return -EINVAL; /* - * Restrict the ‘Clear log’ action to only apply to + * Restrict the 'Clear log' action to only apply to * Vendor debug logs. */ - return uuid_equal(uuid, &DEFINE_CXL_VENDOR_DEBUG_UUID); + if (!uuid_equal(uuid, &DEFINE_CXL_VENDOR_DEBUG_UUID)) + return -EBUSY; + break; } default: break; } - return true; + return 0; } static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, struct cxl_mailbox *cxl_mbox, u16 opcode, size_t in_size, size_t out_size, u64 in_payload) { + int rc; + *mbox_cmd = (struct cxl_mbox_cmd) { .opcode = opcode, .size_in = in_size, @@ -371,12 +376,13 @@ static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, if (IS_ERR(mbox_cmd->payload_in)) return PTR_ERR(mbox_cmd->payload_in); - if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, - in_size)) { + rc = cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, + in_size); + if (rc) { dev_dbg(cxl_mbox->host, "%s: input payload not allowed\n", cxl_mem_opcode_to_name(opcode)); kvfree(mbox_cmd->payload_in); - return -EBUSY; + return rc; } } -- 2.39.5 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] cxl/mbox: return appropriate error in cxl_payload_from_user_allowed() 2026-02-20 0:16 ` [PATCH 2/2] cxl/mbox: return appropriate error " Davidlohr Bueso @ 2026-02-20 22:14 ` Alison Schofield 2026-02-21 18:55 ` Davidlohr Bueso 2026-02-23 19:27 ` Alison Schofield ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: Alison Schofield @ 2026-02-20 22:14 UTC (permalink / raw) To: Davidlohr Bueso Cc: dave.jiang, jonathan.cameron, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl On Thu, Feb 19, 2026 at 04:16:18PM -0800, Davidlohr Bueso wrote: > Make cxl_payload_from_user_allowed() return int such that the it can > distinguish between different errors. The payload size failure is not > well represented by EBUSY (exclusive access by the kernel). Hi David, Patch 1's payload size check is obviously needed, but let's have an ABI-ish discussion about changing externally visible errno. My concern is preserving ABI simplicity and avoid implying that the kernel validates RAW mailbox payloads in general, when it doesn't. cxl_payload_from_user_allowed() is a limited safety gate. Before this patchset, any payload rejection returned -EBUSY. Returning -EINVAL for undersized payloads could be read as broader RAW validation than we actually perform. If we want to keep the ABI surface simple, we could treat undersized payloads as another “payload not allowed” case and continue returning -EBUSY. Conversely, if we are going to split errno values and distinguish -EINVAL for undersized payloads, then for consistency we should also reconsider whether -EBUSY is appropriate for the IMMEDIATE flag case. That is a deliberate policy restriction (not a busy condition), so tightening errno semantics in one place raises the question of whether we should do so consistently. I’m not suggesting we expand scope here, just pointing out the implication. I say all this knowing that these RAW commands are meant for CXL hardware or driver developers only (Kconfig:config CXL_MEM_RAW_COMMANDS), so this may be way more attention than this topic requires. -- Alison > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> > --- > drivers/cxl/core/mbox.c | 32 +++++++++++++++++++------------- > 1 file changed, 19 insertions(+), 13 deletions(-) > > diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c > index e7a6452bf544..164da335fa33 100644 > --- a/drivers/cxl/core/mbox.c > +++ b/drivers/cxl/core/mbox.c > @@ -314,8 +314,9 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) > * @in_size: Size of @payload_in in bytes. > * > * Return: > - * * true - payload_in passes check for @opcode. > - * * false - payload_in contains invalid or unsupported values. > + * * %0 - payload_in passes check for @opcode. > + * * %-EINVAL - payload_in is too small for the opcode. > + * * %-EBUSY - payload_in contains unsupported values. > * > * The driver may inspect payload contents before sending a mailbox > * command from user space to the device. The intent is to reject > @@ -326,40 +327,44 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) > * > * The specific checks are determined by the opcode. > */ > -static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in, > - size_t in_size) > +static int cxl_payload_from_user_allowed(u16 opcode, void *payload_in, > + size_t in_size) > { > switch (opcode) { > case CXL_MBOX_OP_SET_PARTITION_INFO: { > struct cxl_mbox_set_partition_info *pi = payload_in; > > if (in_size < sizeof(*pi)) > - return false; > + return -EINVAL; > if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG) > - return false; > + return -EBUSY; > break; > } > case CXL_MBOX_OP_CLEAR_LOG: { > const uuid_t *uuid = (uuid_t *)payload_in; > > if (in_size < sizeof(uuid_t)) > - return false; > + return -EINVAL; > /* > - * Restrict the ‘Clear log’ action to only apply to > + * Restrict the 'Clear log' action to only apply to > * Vendor debug logs. > */ > - return uuid_equal(uuid, &DEFINE_CXL_VENDOR_DEBUG_UUID); > + if (!uuid_equal(uuid, &DEFINE_CXL_VENDOR_DEBUG_UUID)) > + return -EBUSY; > + break; > } > default: > break; > } > - return true; > + return 0; > } > > static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, > struct cxl_mailbox *cxl_mbox, u16 opcode, > size_t in_size, size_t out_size, u64 in_payload) > { > + int rc; > + > *mbox_cmd = (struct cxl_mbox_cmd) { > .opcode = opcode, > .size_in = in_size, > @@ -371,12 +376,13 @@ static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, > if (IS_ERR(mbox_cmd->payload_in)) > return PTR_ERR(mbox_cmd->payload_in); > > - if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, > - in_size)) { > + rc = cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, > + in_size); > + if (rc) { > dev_dbg(cxl_mbox->host, "%s: input payload not allowed\n", > cxl_mem_opcode_to_name(opcode)); > kvfree(mbox_cmd->payload_in); > - return -EBUSY; > + return rc; > } > } > > -- > 2.39.5 > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] cxl/mbox: return appropriate error in cxl_payload_from_user_allowed() 2026-02-20 22:14 ` Alison Schofield @ 2026-02-21 18:55 ` Davidlohr Bueso 0 siblings, 0 replies; 11+ messages in thread From: Davidlohr Bueso @ 2026-02-21 18:55 UTC (permalink / raw) To: Alison Schofield Cc: dave.jiang, jonathan.cameron, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl On Fri, 20 Feb 2026, Alison Schofield wrote: >My concern is preserving ABI simplicity and avoid implying that the >kernel validates RAW mailbox payloads in general, when it doesn't. >cxl_payload_from_user_allowed() is a limited safety gate. Before this >patchset, any payload rejection returned -EBUSY. Returning -EINVAL for >undersized payloads could be read as broader RAW validation than we >actually perform. If we want to keep the ABI surface simple, we could >treat undersized payloads as another ???payload not allowed??? case and >continue returning -EBUSY. So while the bug is only triggered for RAW commands, these paths are ultimately for all user cmds, so it's pretty implicit, and ultimately does not respect cxl_validate_cmd_from_user() return semantics. So I don't really see it as a case of adding complexity to the ABI surface or sending the wrong message about RAW command verification. That said, I don't have a strong preference if only patch 1 is picked up, I do understand your concerns; and it's kind of the reason why I split it the way I did. >Conversely, if we are going to split errno values and distinguish -EINVAL >for undersized payloads, then for consistency we should also reconsider >whether -EBUSY is appropriate for the IMMEDIATE flag case. That is a >deliberate policy restriction (not a busy condition), so tightening errno >semantics in one place raises the question of whether we should do so >consistently. I???m not suggesting we expand scope here, just pointing out >the implication. That's fair. Thanks, Davidlohr ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] cxl/mbox: return appropriate error in cxl_payload_from_user_allowed() 2026-02-20 0:16 ` [PATCH 2/2] cxl/mbox: return appropriate error " Davidlohr Bueso 2026-02-20 22:14 ` Alison Schofield @ 2026-02-23 19:27 ` Alison Schofield 2026-02-23 22:40 ` Dave Jiang 2026-02-27 13:38 ` Jonathan Cameron 3 siblings, 0 replies; 11+ messages in thread From: Alison Schofield @ 2026-02-23 19:27 UTC (permalink / raw) To: Davidlohr Bueso Cc: dave.jiang, jonathan.cameron, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl On Thu, Feb 19, 2026 at 04:16:18PM -0800, Davidlohr Bueso wrote: > Make cxl_payload_from_user_allowed() return int such that the it can > distinguish between different errors. The payload size failure is not > well represented by EBUSY (exclusive access by the kernel). > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> After airing the ABI and raw-ness with Davidlohr, and since this is expert user option, why not give them any info we have without worry about expectations. So for me: Reviewed-by: Alison Schofield <alison.schofield@intel.com> snip ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] cxl/mbox: return appropriate error in cxl_payload_from_user_allowed() 2026-02-20 0:16 ` [PATCH 2/2] cxl/mbox: return appropriate error " Davidlohr Bueso 2026-02-20 22:14 ` Alison Schofield 2026-02-23 19:27 ` Alison Schofield @ 2026-02-23 22:40 ` Dave Jiang 2026-02-27 13:38 ` Jonathan Cameron 3 siblings, 0 replies; 11+ messages in thread From: Dave Jiang @ 2026-02-23 22:40 UTC (permalink / raw) To: Davidlohr Bueso Cc: jonathan.cameron, alison.schofield, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl On 2/19/26 5:16 PM, Davidlohr Bueso wrote: > Make cxl_payload_from_user_allowed() return int such that the it can > distinguish between different errors. The payload size failure is not > well represented by EBUSY (exclusive access by the kernel). > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> Since this isn't a fix, I'm going to wait and apply it to cxl/next later after the fix goes in 7.0-rc2. Please remind me if I forget. > --- > drivers/cxl/core/mbox.c | 32 +++++++++++++++++++------------- > 1 file changed, 19 insertions(+), 13 deletions(-) > > diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c > index e7a6452bf544..164da335fa33 100644 > --- a/drivers/cxl/core/mbox.c > +++ b/drivers/cxl/core/mbox.c > @@ -314,8 +314,9 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) > * @in_size: Size of @payload_in in bytes. > * > * Return: > - * * true - payload_in passes check for @opcode. > - * * false - payload_in contains invalid or unsupported values. > + * * %0 - payload_in passes check for @opcode. > + * * %-EINVAL - payload_in is too small for the opcode. > + * * %-EBUSY - payload_in contains unsupported values. > * > * The driver may inspect payload contents before sending a mailbox > * command from user space to the device. The intent is to reject > @@ -326,40 +327,44 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) > * > * The specific checks are determined by the opcode. > */ > -static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in, > - size_t in_size) > +static int cxl_payload_from_user_allowed(u16 opcode, void *payload_in, > + size_t in_size) > { > switch (opcode) { > case CXL_MBOX_OP_SET_PARTITION_INFO: { > struct cxl_mbox_set_partition_info *pi = payload_in; > > if (in_size < sizeof(*pi)) > - return false; > + return -EINVAL; > if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG) > - return false; > + return -EBUSY; > break; > } > case CXL_MBOX_OP_CLEAR_LOG: { > const uuid_t *uuid = (uuid_t *)payload_in; > > if (in_size < sizeof(uuid_t)) > - return false; > + return -EINVAL; > /* > - * Restrict the ‘Clear log’ action to only apply to > + * Restrict the 'Clear log' action to only apply to > * Vendor debug logs. > */ > - return uuid_equal(uuid, &DEFINE_CXL_VENDOR_DEBUG_UUID); > + if (!uuid_equal(uuid, &DEFINE_CXL_VENDOR_DEBUG_UUID)) > + return -EBUSY; > + break; > } > default: > break; > } > - return true; > + return 0; > } > > static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, > struct cxl_mailbox *cxl_mbox, u16 opcode, > size_t in_size, size_t out_size, u64 in_payload) > { > + int rc; > + > *mbox_cmd = (struct cxl_mbox_cmd) { > .opcode = opcode, > .size_in = in_size, > @@ -371,12 +376,13 @@ static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, > if (IS_ERR(mbox_cmd->payload_in)) > return PTR_ERR(mbox_cmd->payload_in); > > - if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, > - in_size)) { > + rc = cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, > + in_size); > + if (rc) { > dev_dbg(cxl_mbox->host, "%s: input payload not allowed\n", > cxl_mem_opcode_to_name(opcode)); > kvfree(mbox_cmd->payload_in); > - return -EBUSY; > + return rc; > } > } > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/2] cxl/mbox: return appropriate error in cxl_payload_from_user_allowed() 2026-02-20 0:16 ` [PATCH 2/2] cxl/mbox: return appropriate error " Davidlohr Bueso ` (2 preceding siblings ...) 2026-02-23 22:40 ` Dave Jiang @ 2026-02-27 13:38 ` Jonathan Cameron 3 siblings, 0 replies; 11+ messages in thread From: Jonathan Cameron @ 2026-02-27 13:38 UTC (permalink / raw) To: Davidlohr Bueso Cc: dave.jiang, alison.schofield, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl On Thu, 19 Feb 2026 16:16:18 -0800 Davidlohr Bueso <dave@stgolabs.net> wrote: > Make cxl_payload_from_user_allowed() return int such that the it can > distinguish between different errors. The payload size failure is not > well represented by EBUSY (exclusive access by the kernel). > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> Hi Davidlohr, If you are going to sneak in a fix to quotation style, then I'd like to see it mentioned in the commit message. Anyhow either way Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> > +static int cxl_payload_from_user_allowed(u16 opcode, void *payload_in, > + size_t in_size) > { > switch (opcode) { > case CXL_MBOX_OP_SET_PARTITION_INFO: { > struct cxl_mbox_set_partition_info *pi = payload_in; > > if (in_size < sizeof(*pi)) > - return false; > + return -EINVAL; > if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG) > - return false; > + return -EBUSY; > break; > } > case CXL_MBOX_OP_CLEAR_LOG: { > const uuid_t *uuid = (uuid_t *)payload_in; > > if (in_size < sizeof(uuid_t)) > - return false; > + return -EINVAL; > /* > - * Restrict the ‘Clear log’ action to only apply to > + * Restrict the 'Clear log' action to only apply to Unrelated change. I don't mind it but should at least be mentioned. Maybe Dave can add something to the commit description when picking this up. > * Vendor debug logs. > */ > - return uuid_equal(uuid, &DEFINE_CXL_VENDOR_DEBUG_UUID); > + if (!uuid_equal(uuid, &DEFINE_CXL_VENDOR_DEBUG_UUID)) ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 0/2] cxl/mbox: fix undersized payload handling in cxl_payload_from_user_allowed() 2026-02-20 0:16 [PATCH 0/2] cxl/mbox: fix undersized payload handling in cxl_payload_from_user_allowed() Davidlohr Bueso 2026-02-20 0:16 ` [PATCH 1/2] cxl/mbox: validate payload size before accessing contents " Davidlohr Bueso 2026-02-20 0:16 ` [PATCH 2/2] cxl/mbox: return appropriate error " Davidlohr Bueso @ 2026-02-20 17:23 ` Dave Jiang 2 siblings, 0 replies; 11+ messages in thread From: Dave Jiang @ 2026-02-20 17:23 UTC (permalink / raw) To: Davidlohr Bueso Cc: jonathan.cameron, alison.schofield, vishal.l.verma, ira.weiny, dan.j.williams, linux-cxl On 2/19/26 5:16 PM, Davidlohr Bueso wrote: > Hi, > > The first patch fixes a KSAN splat uncovered by cxl fuzzying, the second > is a follow up for maintain proper error code semantics. > > Applies against 'next' from cxl.git. > > Thanks! > > Davidlohr Bueso (2): > cxl/mbox: validate payload size before accessing contents in cxl_payload_from_user_allowed() > cxl/mbox: return appropriate error in cxl_payload_from_user_allowed() > > drivers/cxl/core/mbox.c | 31 ++++++++++++++++++++++--------- > 1 file changed, 22 insertions(+), 9 deletions(-) > > -- > 2.39.5 > > Reviewed-by: Dave Jiang <dave.jiang@intel.com> for the series ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-02-27 13:38 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-20 0:16 [PATCH 0/2] cxl/mbox: fix undersized payload handling in cxl_payload_from_user_allowed() Davidlohr Bueso 2026-02-20 0:16 ` [PATCH 1/2] cxl/mbox: validate payload size before accessing contents " Davidlohr Bueso 2026-02-23 19:23 ` Alison Schofield 2026-02-23 22:39 ` Dave Jiang 2026-02-20 0:16 ` [PATCH 2/2] cxl/mbox: return appropriate error " Davidlohr Bueso 2026-02-20 22:14 ` Alison Schofield 2026-02-21 18:55 ` Davidlohr Bueso 2026-02-23 19:27 ` Alison Schofield 2026-02-23 22:40 ` Dave Jiang 2026-02-27 13:38 ` Jonathan Cameron 2026-02-20 17:23 ` [PATCH 0/2] cxl/mbox: fix undersized payload handling " Dave Jiang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox