mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] cdrom: bound the device-supplied offset in cdrom_mrw_set_lba_space
@ 2026-10-22 18:19 Jay Vadayath
  2026-10-23 21:19 ` Phillip Potter
  0 siblings, 1 reply; 2+ messages in thread
From: Jay Vadayath @ 2026-10-22 18:19 UTC (permalink / raw)
  To: Phillip Potter; +Cc: linux-kernel, Jay Vadayath

cdrom_mrw_set_lba_space() issues a MODE SENSE(10) into a 16-byte stack
buffer (char buffer[16]), then takes offset = be16_to_cpu(mph->desc_length)
straight from reply bytes 6..7 and does buffer[offset + 3] = space. The
desc_length field is fully device-controlled (0..65535) and nothing
checks that offset + 3 lies within the buffer, nor that size (derived
from mode_data_length) fits. A drive that returns desc_length = 24 turns
the assignment into buffer[27] = space, a one-byte write 12 bytes past
the end of the stack buffer.

This runs when an MRW-writable CD-ROM is opened O_RDWR, so a malicious or
buggy USB/ATAPI drive (or an emulated one) is enough: no privilege beyond
being able to open /dev/sr0 for writing on an attacker-supplied device.
The sink lives in the CD-ROM core, so it affects every cdrom driver
(sr, ide-cd, pcd, gdrom).

  BUG: KASAN: stack-out-of-bounds in cdrom_mrw_set_lba_space.constprop.0+0x25c/0x260
  Write of size 1 at addr ffff88800639f6db by task poc/133
  Call Trace:
   dump_stack_lvl+0x64/0x80
   print_report+0xd0/0x630
   kasan_report+0xe5/0x120
   cdrom_mrw_set_lba_space.constprop.0+0x25c/0x260
   cdrom_open+0x1169/0x2080
   sr_block_open+0x9e/0x140
   blkdev_get_whole+0x8c/0x200
   bdev_open+0x214/0xc40
   blkdev_open+0x1f8/0x370
   do_dentry_open+0x408/0x1290
   path_openat+0xb2f/0x2210
   do_sys_openat2+0x126/0x170
   ...

Both desc_length (offset) and mode_data_length (size) come straight from
the device reply, so reject anything that would not fit in buffer:
offset + 3 >= sizeof(buffer) or size > sizeof(buffer) returns -EIO before
the write. The sibling cdrom_mode_select consumer of size is covered by
the same guard.

This bug was discovered by Artiphishell's vTriage pipeline, which
generated an emulated raw-gadget USB BOT CD-ROM (INQUIRY TYPE_ROM
advertising MRW-write) plus an open(/dev/sr0, O_RDWR) client that drives
the capability-probe chain (page 0x2a -> GET CONFIGURATION CDF_MRW ->
MODE SENSE page 0x03 with desc_length = 24) and reliably triggers the
KASAN report on an unpatched kernel. The fix below was drafted with the
Claude coding assistant; a userspace reproducer is available on request.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Jay Vadayath <jay@artiphishell.com>
---
 drivers/cdrom/cdrom.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 4f1fd389260f..5e910d79045f 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -571,6 +571,10 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
 	offset = be16_to_cpu(mph->desc_length);
 	size = be16_to_cpu(mph->mode_data_length) + 2;
 
+	/* Both fields are device-supplied; reject values that overflow buffer[]. */
+	if (offset + 3 >= (int)sizeof(buffer) || size > (int)sizeof(buffer))
+		return -EIO;
+
 	buffer[offset + 3] = space;
 	cgc.buflen = size;
 
-- 
2.51.2


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

* Re: [PATCH] cdrom: bound the device-supplied offset in cdrom_mrw_set_lba_space
  2026-10-22 18:19 [PATCH] cdrom: bound the device-supplied offset in cdrom_mrw_set_lba_space Jay Vadayath
@ 2026-10-23 21:19 ` Phillip Potter
  0 siblings, 0 replies; 2+ messages in thread
From: Phillip Potter @ 2026-10-23 21:19 UTC (permalink / raw)
  To: Jay Vadayath; +Cc: linux-kernel, Jay Vadayath

On Thu, Oct 22, 2026 at 11:19:55AM -0700, Jay Vadayath wrote:
> cdrom_mrw_set_lba_space() issues a MODE SENSE(10) into a 16-byte stack
> buffer (char buffer[16]), then takes offset = be16_to_cpu(mph->desc_length)
> straight from reply bytes 6..7 and does buffer[offset + 3] = space. The
> desc_length field is fully device-controlled (0..65535) and nothing
> checks that offset + 3 lies within the buffer, nor that size (derived
> from mode_data_length) fits. A drive that returns desc_length = 24 turns
> the assignment into buffer[27] = space, a one-byte write 12 bytes past
> the end of the stack buffer.
> 
> This runs when an MRW-writable CD-ROM is opened O_RDWR, so a malicious or
> buggy USB/ATAPI drive (or an emulated one) is enough: no privilege beyond
> being able to open /dev/sr0 for writing on an attacker-supplied device.
> The sink lives in the CD-ROM core, so it affects every cdrom driver
> (sr, ide-cd, pcd, gdrom).
> 
>   BUG: KASAN: stack-out-of-bounds in cdrom_mrw_set_lba_space.constprop.0+0x25c/0x260
>   Write of size 1 at addr ffff88800639f6db by task poc/133
>   Call Trace:
>    dump_stack_lvl+0x64/0x80
>    print_report+0xd0/0x630
>    kasan_report+0xe5/0x120
>    cdrom_mrw_set_lba_space.constprop.0+0x25c/0x260
>    cdrom_open+0x1169/0x2080
>    sr_block_open+0x9e/0x140
>    blkdev_get_whole+0x8c/0x200
>    bdev_open+0x214/0xc40
>    blkdev_open+0x1f8/0x370
>    do_dentry_open+0x408/0x1290
>    path_openat+0xb2f/0x2210
>    do_sys_openat2+0x126/0x170
>    ...
> 
> Both desc_length (offset) and mode_data_length (size) come straight from
> the device reply, so reject anything that would not fit in buffer:
> offset + 3 >= sizeof(buffer) or size > sizeof(buffer) returns -EIO before
> the write. The sibling cdrom_mode_select consumer of size is covered by
> the same guard.
> 
> This bug was discovered by Artiphishell's vTriage pipeline, which
> generated an emulated raw-gadget USB BOT CD-ROM (INQUIRY TYPE_ROM
> advertising MRW-write) plus an open(/dev/sr0, O_RDWR) client that drives
> the capability-probe chain (page 0x2a -> GET CONFIGURATION CDF_MRW ->
> MODE SENSE page 0x03 with desc_length = 24) and reliably triggers the
> KASAN report on an unpatched kernel. The fix below was drafted with the
> Claude coding assistant; a userspace reproducer is available on request.
> 
> Assisted-by: Claude:claude-opus-4-8
> Signed-off-by: Jay Vadayath <jay@artiphishell.com>
> ---
>  drivers/cdrom/cdrom.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
> index 4f1fd389260f..5e910d79045f 100644
> --- a/drivers/cdrom/cdrom.c
> +++ b/drivers/cdrom/cdrom.c
> @@ -571,6 +571,10 @@ static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
>  	offset = be16_to_cpu(mph->desc_length);
>  	size = be16_to_cpu(mph->mode_data_length) + 2;
>  
> +	/* Both fields are device-supplied; reject values that overflow buffer[]. */
> +	if (offset + 3 >= (int)sizeof(buffer) || size > (int)sizeof(buffer))
> +		return -EIO;
> +
>  	buffer[offset + 3] = space;
>  	cgc.buflen = size;
>  
> -- 
> 2.51.2
>

Hi Jay,

Thanks for your patch. Won't be able to review straight away as I'm
travelling early tomorrow and busy most of the day. Please can you
provide the userspace reproducer code to me too in the meantime,
thanks.

Regards,
Phil

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

end of thread, other threads:[~2026-10-23 21:19 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-22 18:19 [PATCH] cdrom: bound the device-supplied offset in cdrom_mrw_set_lba_space Jay Vadayath
2026-10-23 21:19 ` Phillip Potter

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

all inboxes | Powered by JetHome®