cdrom: respect device capabilities during opening action
authorDiego Elio Pettenò <flameeyes@flameeyes.com>
Tue, 19 Nov 2019 21:37:08 +0000 (21:37 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 4 Jan 2020 18:13:12 +0000 (19:13 +0100)
[ Upstream commit 366ba7c71ef77c08d06b18ad61b26e2df7352338 ]

Reading the TOC only works if the device can play audio, otherwise
these commands fail (and possibly bring the device to an unhealthy
state.)

Similarly, cdrom_mmc3_profile() should only be called if the device
supports generic packet commands.

To: Jens Axboe <axboe@kernel.dk>
Cc: linux-kernel@vger.kernel.org
Cc: linux-scsi@vger.kernel.org
Signed-off-by: Diego Elio Pettenò <flameeyes@flameeyes.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/cdrom/cdrom.c

index 933268b..d394738 100644 (file)
@@ -996,6 +996,12 @@ static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype *tracks)
        tracks->xa = 0;
        tracks->error = 0;
        cd_dbg(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n");
+
+       if (!CDROM_CAN(CDC_PLAY_AUDIO)) {
+               tracks->error = CDS_NO_INFO;
+               return;
+       }
+
        /* Grab the TOC header so we can see how many tracks there are */
        ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
        if (ret) {
@@ -1162,7 +1168,8 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
                ret = open_for_data(cdi);
                if (ret)
                        goto err;
-               cdrom_mmc3_profile(cdi);
+               if (CDROM_CAN(CDC_GENERIC_PACKET))
+                       cdrom_mmc3_profile(cdi);
                if (mode & FMODE_WRITE) {
                        ret = -EROFS;
                        if (cdrom_open_write(cdi))
@@ -2882,6 +2889,9 @@ int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written)
           it doesn't give enough information or fails. then we return
           the toc contents. */
 use_toc:
+       if (!CDROM_CAN(CDC_PLAY_AUDIO))
+               return -ENOSYS;
+
        toc.cdte_format = CDROM_MSF;
        toc.cdte_track = CDROM_LEADOUT;
        if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc)))