]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cdrom: Call cdrom_mrw_exit from cdrom_release function
authorPhillip Potter <phil@philpotter.co.uk>
Tue, 22 Jul 2025 23:19:00 +0000 (00:19 +0100)
committerJens Axboe <axboe@kernel.dk>
Wed, 23 Jul 2025 01:10:17 +0000 (19:10 -0600)
Remove the cdrom_mrw_exit call from unregister_cdrom, as it invokes
block commands that can fail due to a NULL pointer dereference from the
call happening too late, during the unloading of the driver (e.g.
unplugging of USB optical drives).

Instead perform the call inside cdrom_release, thus also removing the
need for the exit function pointer inside the cdrom_device_info struct.

Reported-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Closes: https://lore.kernel.org/linux-block/uxgzea5ibqxygv3x7i4ojbpvcpv2wziorvb3ns5cdtyvobyn7h@y4g4l5ezv2ec
Suggested-by: Jens Axboe <axboe@kernel.dk>
Link: https://lore.kernel.org/linux-block/6686fe78-a050-4a1d-aa27-b7bf7ca6e912@kernel.dk
Tested-by: Phillip Potter <phil@philpotter.co.uk>
Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
Link: https://lore.kernel.org/r/20250722231900.1164-2-phil@philpotter.co.uk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Documentation/cdrom/cdrom-standard.rst
drivers/cdrom/cdrom.c
include/linux/cdrom.h

index 6c1303cff159e16daba2bf7c9a5fe8b72a3ebcad..b97a4e9b9bd38344b4a121c0c84ecc127c6e989f 100644 (file)
@@ -273,7 +273,6 @@ The drive-specific, minor-like information that is registered with
        __u8 media_written;                     /*  dirty flag, DVD+RW bookkeeping */
        unsigned short mmc3_profile;            /*  current MMC3 profile */
        int for_data;                           /*  unknown:TBD */
-       int (*exit)(struct cdrom_device_info *);/*  unknown:TBD */
        int mrw_mode_page;                      /*  which MRW mode page is in use */
   };
 
index 21a10552da61e38ccc3780c21fae2dd0de0d02e0..31ba1f8c1f7865dc99b70d6079765e52cc15a7a2 100644 (file)
@@ -624,9 +624,6 @@ int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi)
        if (check_media_type == 1)
                cdi->options |= (int) CDO_CHECK_TYPE;
 
-       if (CDROM_CAN(CDC_MRW_W))
-               cdi->exit = cdrom_mrw_exit;
-
        if (cdi->ops->read_cdda_bpc)
                cdi->cdda_method = CDDA_BPC_FULL;
        else
@@ -651,9 +648,6 @@ void unregister_cdrom(struct cdrom_device_info *cdi)
        list_del(&cdi->list);
        mutex_unlock(&cdrom_mutex);
 
-       if (cdi->exit)
-               cdi->exit(cdi);
-
        cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
 }
 EXPORT_SYMBOL(unregister_cdrom);
@@ -1264,6 +1258,8 @@ void cdrom_release(struct cdrom_device_info *cdi)
                cd_dbg(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n",
                       cdi->name);
                cdrom_dvd_rw_close_write(cdi);
+               if (CDROM_CAN(CDC_MRW_W))
+                       cdrom_mrw_exit(cdi);
 
                if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) {
                        cd_dbg(CD_CLOSE, "Unlocking door!\n");
index fdfb61ccf55aef23721aa8dbcd52161a1b9e1c90..b907e6c2307d8516ddf93411a18c7d031c0f98cb 100644 (file)
@@ -62,7 +62,6 @@ struct cdrom_device_info {
        __u8 last_sense;
        __u8 media_written;             /* dirty flag, DVD+RW bookkeeping */
        unsigned short mmc3_profile;    /* current MMC3 profile */
-       int (*exit)(struct cdrom_device_info *);
        int mrw_mode_page;
        bool opened_for_data;
        __s64 last_media_change_ms;