* [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
@ 2018-04-26 17:51 Scott Bauer
2018-04-27 12:41 ` Dan Carpenter
2018-08-29 12:48 ` Dan Carpenter
0 siblings, 2 replies; 6+ messages in thread
From: Scott Bauer @ 2018-04-26 17:51 UTC (permalink / raw)
To: axboe; +Cc: hch, dan.carpenter, linux-block, Scott Bauer, Scott Bauer, stable
Like d88b6d04: "cdrom: information leak in cdrom_ioctl_media_changed()"
There is another cast from unsigned long to int which causes
a bounds check to fail with specially crafted input. The value is
then used as an index in the slot array in cdrom_slot_status().
Signed-off-by: Scott Bauer <scott.bauer@intel.com>
Signed-off-by: Scott Bauer <sbauer@plzdonthack.me>
Cc: stable@vger.kernel.org
---
drivers/cdrom/cdrom.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index bfc566d3f31a..8cfa10ab7abc 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2542,7 +2542,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
if (!CDROM_CAN(CDC_SELECT_DISC) ||
(arg == CDSL_CURRENT || arg == CDSL_NONE))
return cdi->ops->drive_status(cdi, CDSL_CURRENT);
- if (((int)arg >= cdi->capacity))
+ if (arg >= cdi->capacity)
return -EINVAL;
return cdrom_slot_status(cdi, arg);
}
--
2.14.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
2018-04-26 17:51 [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status Scott Bauer
@ 2018-04-27 12:41 ` Dan Carpenter
2018-04-27 14:43 ` Scott Bauer
2018-08-29 12:48 ` Dan Carpenter
1 sibling, 1 reply; 6+ messages in thread
From: Dan Carpenter @ 2018-04-27 12:41 UTC (permalink / raw)
To: Scott Bauer; +Cc: axboe, hch, linux-block, Scott Bauer, stable
I sent you an email to send this patch, but reviewing it now it's not
actually a run time bug. The cdrom_slot_status() function takes an
integer argument so it works.
I'm working on a static checker warning for these kinds of bugs:
drivers/cdrom/cdrom.c:2444 cdrom_ioctl_select_disc() warn: truncated comparison 'arg' 'u64max' to 's32max'
drivers/cdrom/cdrom.c
2435 static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi,
2436 unsigned long arg)
2437 {
2438 cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
2439
2440 if (!CDROM_CAN(CDC_SELECT_DISC))
2441 return -ENOSYS;
2442
2443 if (arg != CDSL_CURRENT && arg != CDSL_NONE) {
2444 if ((int)arg >= cdi->capacity)
^^^^^^^^^^^^^^^^^^^^^^^^^
2445 return -EINVAL;
2446 }
2447
2448 /*
2449 * ->select_disc is a hook to allow a driver-specific way of
2450 * seleting disc. However, since there is no equivalent hook for
2451 * cdrom_slot_status this may not actually be useful...
2452 */
2453 if (cdi->ops->select_disc)
2454 return cdi->ops->select_disc(cdi, arg);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
->select_disc() also take an int so it's fine (plus there is no such
function so it's dead code).
2455
2456 cd_dbg(CD_CHANGER, "Using generic cdrom_select_disc()\n");
2457 return cdrom_select_disc(cdi, arg);
^^^
Also an int.
2458 }
So I think it's a good idea to fix these just for cleanliness and to
silence the static checker warnings but it doesn't affect runtime.
regards,
dan carpenter
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
2018-04-27 12:41 ` Dan Carpenter
@ 2018-04-27 14:43 ` Scott Bauer
2018-04-27 15:13 ` Dan Carpenter
0 siblings, 1 reply; 6+ messages in thread
From: Scott Bauer @ 2018-04-27 14:43 UTC (permalink / raw)
To: Dan Carpenter, Scott Bauer; +Cc: axboe, hch, linux-block, stable
[-- Attachment #1: Type: text/plain, Size: 3013 bytes --]
On 04/27/2018 06:41 AM, Dan Carpenter wrote:
> I sent you an email to send this patch, but reviewing it now it's not
> actually a run time bug. The cdrom_slot_status() function takes an
> integer argument so it works.
It's still runtime bug... I should reword the commit a bit to reflect that it's not
like the upper 32 bit issue that you had found. Look at it this way, ints can be negative, right?
The check is as follows:
2545: if (((int)arg >= cdi->capacity))
return -EINVAL <https://elixir.bootlin.com/linux/v4.17-rc2/ident/EINVAL>;
return cdrom_slot_status <https://elixir.bootlin.com/linux/v4.17-rc2/ident/cdrom_slot_status>(cdi, arg); so if (-65536 >= cdi->capacity) it's not so we don't return -einval. And we pass a negative index into cdrom_slot_status.
where we do the following (https://elixir.bootlin.com/linux/v4.17-rc2/source/drivers/cdrom/cdrom.c#L1336):
1336:
if (info->slots <https://elixir.bootlin.com/linux/v4.17-rc2/ident/slots>[slot <https://elixir.bootlin.com/linux/v4.17-rc2/ident/slot>].disc_present)
ret = CDS_DISC_OK <https://elixir.bootlin.com/linux/v4.17-rc2/ident/CDS_DISC_OK>;
>
> I'm working on a static checker warning for these kinds of bugs:
>
> drivers/cdrom/cdrom.c:2444 cdrom_ioctl_select_disc() warn: truncated comparison 'arg' 'u64max' to 's32max'
>
> drivers/cdrom/cdrom.c
> 2435 static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi,
> 2436 unsigned long arg)
> 2437 {
> 2438 cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
> 2439
> 2440 if (!CDROM_CAN(CDC_SELECT_DISC))
> 2441 return -ENOSYS;
> 2442
> 2443 if (arg != CDSL_CURRENT && arg != CDSL_NONE) {
> 2444 if ((int)arg >= cdi->capacity)
> ^^^^^^^^^^^^^^^^^^^^^^^^^
> 2445 return -EINVAL;
> 2446 }
> 2447
> 2448 /*
> 2449 * ->select_disc is a hook to allow a driver-specific way of
> 2450 * seleting disc. However, since there is no equivalent hook for
> 2451 * cdrom_slot_status this may not actually be useful...
> 2452 */
> 2453 if (cdi->ops->select_disc)
> 2454 return cdi->ops->select_disc(cdi, arg);
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ->select_disc() also take an int so it's fine (plus there is no such
> function so it's dead code).
>
> 2455
> 2456 cd_dbg(CD_CHANGER, "Using generic cdrom_select_disc()\n");
> 2457 return cdrom_select_disc(cdi, arg);
> ^^^
> Also an int.
>
> 2458 }
>
> So I think it's a good idea to fix these just for cleanliness and to
> silence the static checker warnings but it doesn't affect runtime.
Yeah, this one was "fine" aside from being messy, that's why I didn't send a patch for it.
P.S. Is your static analysis tooling available for the general public to look at?
[-- Attachment #2: Type: text/html, Size: 4678 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
2018-04-27 14:43 ` Scott Bauer
@ 2018-04-27 15:13 ` Dan Carpenter
0 siblings, 0 replies; 6+ messages in thread
From: Dan Carpenter @ 2018-04-27 15:13 UTC (permalink / raw)
To: Scott Bauer; +Cc: Scott Bauer, axboe, hch, linux-block, stable
On Fri, Apr 27, 2018 at 08:43:03AM -0600, Scott Bauer wrote:
>
>
> On 04/27/2018 06:41 AM, Dan Carpenter wrote:
> > I sent you an email to send this patch, but reviewing it now it's not
> > actually a run time bug. The cdrom_slot_status() function takes an
> > integer argument so it works.
>
> It's still� runtime bug... I should reword the commit a bit to reflect that it's not
> like the upper 32 bit issue that you had found. Look at it this way, ints can be negative, right?
>
Oh. Yeah. Duh...
> The check is as follows:
>
> 2545: if (((int)arg >= cdi->capacity))
> return -EINVAL <https://elixir.bootlin.com/linux/v4.17-rc2/ident/EINVAL>;
> return cdrom_slot_status <https://elixir.bootlin.com/linux/v4.17-rc2/ident/cdrom_slot_status>(cdi, arg); so if (-65536 >= cdi->capacity) it's not so we don't return -einval. And we pass a negative index into cdrom_slot_status.
>
>
> where we do the following (https://elixir.bootlin.com/linux/v4.17-rc2/source/drivers/cdrom/cdrom.c#L1336):
>
> 1336:
> if (info->slots <https://elixir.bootlin.com/linux/v4.17-rc2/ident/slots>[slot <https://elixir.bootlin.com/linux/v4.17-rc2/ident/slot>].disc_present)
> ret = CDS_DISC_OK <https://elixir.bootlin.com/linux/v4.17-rc2/ident/CDS_DISC_OK>;
>
>
>
> >
> > I'm working on a static checker warning for these kinds of bugs:
> >
> > drivers/cdrom/cdrom.c:2444 cdrom_ioctl_select_disc() warn: truncated comparison 'arg' 'u64max' to 's32max'
> >
> > drivers/cdrom/cdrom.c
> > 2435 static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi,
> > 2436 unsigned long arg)
> > 2437 {
> > 2438 cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
> > 2439
> > 2440 if (!CDROM_CAN(CDC_SELECT_DISC))
> > 2441 return -ENOSYS;
> > 2442
> > 2443 if (arg != CDSL_CURRENT && arg != CDSL_NONE) {
> > 2444 if ((int)arg >= cdi->capacity)
> > ^^^^^^^^^^^^^^^^^^^^^^^^^
> > 2445 return -EINVAL;
> > 2446 }
> > 2447
> > 2448 /*
> > 2449 * ->select_disc is a hook to allow a driver-specific way of
> > 2450 * seleting disc. However, since there is no equivalent hook for
> > 2451 * cdrom_slot_status this may not actually be useful...
> > 2452 */
> > 2453 if (cdi->ops->select_disc)
> > 2454 return cdi->ops->select_disc(cdi, arg);
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > ->select_disc() also take an int so it's fine (plus there is no such
> > function so it's dead code).
> >
> > 2455
> > 2456 cd_dbg(CD_CHANGER, "Using generic cdrom_select_disc()\n");
> > 2457 return cdrom_select_disc(cdi, arg);
> > ^^^
> > Also an int.
> >
> > 2458 }
> >
> > So I think it's a good idea to fix these just for cleanliness and to
> > silence the static checker warnings but it doesn't affect runtime.
>
> Yeah, this one was "fine" aside from being messy, that's why I didn't send a patch for it.
>
I'm not convinced any more. Could you patch it and resend? We could
end up sending invalid commands to the cdrom firmware when we do
cdrom_load_unload() at the end of the cdrom_select_disc() function.
Proably there is no impact but we may as well fix it. Here is my
analysis if you are curious:
1371 /* If SLOT < 0, unload the current slot. Otherwise, try to load SLOT. */
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
CDSL_CURRENT is INT_MAX and CDSL_NONE is "INT_MAX - 1" but
cdrom_select_disc() calls this with slot set to -1.
1372 static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot)
1373 {
1374 struct packet_command cgc;
1375
1376 cd_dbg(CD_CHANGER, "entering cdrom_load_unload()\n");
1377 if (cdi->sanyo_slot && slot < 0)
1378 return 0;
1379
1380 init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
1381 cgc.cmd[0] = GPCMD_LOAD_UNLOAD;
1382 cgc.cmd[4] = 2 + (slot >= 0);
^^^^^^^^^^
So cmd[4] is 2.
1383 cgc.cmd[8] = slot;
^^^^^^^^^^^^^^^^^
Here were setting cmd[8] to any u8 value we choose.
1384 cgc.timeout = 60 * HZ;
1385
1386 /* The Sanyo 3 CD changer uses byte 7 of the
1387 GPCMD_TEST_UNIT_READY to command to switch CDs instead of
1388 using the GPCMD_LOAD_UNLOAD opcode. */
1389 if (cdi->sanyo_slot && -1 < slot) {
1390 cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
1391 cgc.cmd[7] = slot;
1392 cgc.cmd[4] = cgc.cmd[8] = 0;
1393 cdi->sanyo_slot = slot ? slot : 3;
1394 }
1395
1396 return cdi->ops->generic_packet(cdi, &cgc);
1397 }
> P.S. Is your static analysis tooling available for the general public to look at?
Sure. I've been dorking with it for a couple days and I haven't tested
the latest version except on drivers/cdrom/cdrom.c so let me do some
more testing and then I'll post it.
regards,
dan carpenter
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
2018-04-26 17:51 [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status Scott Bauer
2018-04-27 12:41 ` Dan Carpenter
@ 2018-08-29 12:48 ` Dan Carpenter
2018-08-29 14:09 ` Jens Axboe
1 sibling, 1 reply; 6+ messages in thread
From: Dan Carpenter @ 2018-08-29 12:48 UTC (permalink / raw)
To: Scott Bauer; +Cc: axboe, hch, linux-block, Scott Bauer, stable
Sorry, I responded to this patch that this wasn't a real bug, but then
Scott corrected me that it was.
Anyway, it is a bug and we haven't applied this patch yet.
regards,
dan carpenter
On Thu, Apr 26, 2018 at 11:51:08AM -0600, Scott Bauer wrote:
> Like d88b6d04: "cdrom: information leak in cdrom_ioctl_media_changed()"
>
> There is another cast from unsigned long to int which causes
> a bounds check to fail with specially crafted input. The value is
> then used as an index in the slot array in cdrom_slot_status().
>
> Signed-off-by: Scott Bauer <scott.bauer@intel.com>
> Signed-off-by: Scott Bauer <sbauer@plzdonthack.me>
> Cc: stable@vger.kernel.org
> ---
> drivers/cdrom/cdrom.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
> index bfc566d3f31a..8cfa10ab7abc 100644
> --- a/drivers/cdrom/cdrom.c
> +++ b/drivers/cdrom/cdrom.c
> @@ -2542,7 +2542,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
> if (!CDROM_CAN(CDC_SELECT_DISC) ||
> (arg == CDSL_CURRENT || arg == CDSL_NONE))
> return cdi->ops->drive_status(cdi, CDSL_CURRENT);
> - if (((int)arg >= cdi->capacity))
> + if (arg >= cdi->capacity)
> return -EINVAL;
> return cdrom_slot_status(cdi, arg);
> }
> --
> 2.14.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
2018-08-29 12:48 ` Dan Carpenter
@ 2018-08-29 14:09 ` Jens Axboe
0 siblings, 0 replies; 6+ messages in thread
From: Jens Axboe @ 2018-08-29 14:09 UTC (permalink / raw)
To: Dan Carpenter, Scott Bauer; +Cc: hch, linux-block, Scott Bauer, stable
On 8/29/18 6:48 AM, Dan Carpenter wrote:
> Sorry, I responded to this patch that this wasn't a real bug, but then
> Scott corrected me that it was.
>
> Anyway, it is a bug and we haven't applied this patch yet.
It is now, apparently I lost track of it too. Thanks Scott.
--
Jens Axboe
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-08-29 14:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-04-26 17:51 [PATCH] cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status Scott Bauer
2018-04-27 12:41 ` Dan Carpenter
2018-04-27 14:43 ` Scott Bauer
2018-04-27 15:13 ` Dan Carpenter
2018-08-29 12:48 ` Dan Carpenter
2018-08-29 14:09 ` Jens Axboe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox