Commit 5ec9d26b authored by Phillip Potter's avatar Phillip Potter Committed by Jens Axboe
Browse files

cdrom: Call cdrom_mrw_exit from cdrom_release function



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: default avatarSergey Senozhatsky <senozhatsky@chromium.org>
Closes: https://lore.kernel.org/linux-block/uxgzea5ibqxygv3x7i4ojbpvcpv2wziorvb3ns5cdtyvobyn7h@y4g4l5ezv2ec


Suggested-by: default avatarJens Axboe <axboe@kernel.dk>
Link: https://lore.kernel.org/linux-block/6686fe78-a050-4a1d-aa27-b7bf7ca6e912@kernel.dk


Tested-by: default avatarPhillip Potter <phil@philpotter.co.uk>
Signed-off-by: default avatarPhillip Potter <phil@philpotter.co.uk>
Link: https://lore.kernel.org/r/20250722231900.1164-2-phil@philpotter.co.uk


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 63ce5372
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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 */
  };

+2 −6
Original line number Diff line number Diff line
@@ -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");
+0 −1
Original line number Diff line number Diff line
@@ -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;