Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33af79d1 authored by Chandra Seetharaman's avatar Chandra Seetharaman Committed by Linus Torvalds
Browse files

scsi_dh: Verify "dev" is a sdev before accessing it.



Before accessing the device data structure in hardware handlers,
make sure it is a indeed a sdev device.

Yinghai Lu <yhlu.kernel@gmail.com> found the bug on Jul 16, 2008,
and later tested/verified the following fix.

Signed-off-by: default avatarChandra Seetharaman <sekharan@us.ibm.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent dc7c65db
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -416,12 +416,17 @@ static int clariion_bus_notify(struct notifier_block *nb,
				unsigned long action, void *data)
				unsigned long action, void *data)
{
{
	struct device *dev = data;
	struct device *dev = data;
	struct scsi_device *sdev = to_scsi_device(dev);
	struct scsi_device *sdev;
	struct scsi_dh_data *scsi_dh_data;
	struct scsi_dh_data *scsi_dh_data;
	struct clariion_dh_data *h;
	struct clariion_dh_data *h;
	int i, found = 0;
	int i, found = 0;
	unsigned long flags;
	unsigned long flags;


	if (!scsi_is_sdev_device(dev))
		return 0;

	sdev = to_scsi_device(dev);

	if (action == BUS_NOTIFY_ADD_DEVICE) {
	if (action == BUS_NOTIFY_ADD_DEVICE) {
		for (i = 0; clariion_dev_list[i].vendor; i++) {
		for (i = 0; clariion_dev_list[i].vendor; i++) {
			if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor,
			if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor,
+6 −1
Original line number Original line Diff line number Diff line
@@ -131,11 +131,16 @@ static int hp_sw_bus_notify(struct notifier_block *nb,
			    unsigned long action, void *data)
			    unsigned long action, void *data)
{
{
	struct device *dev = data;
	struct device *dev = data;
	struct scsi_device *sdev = to_scsi_device(dev);
	struct scsi_device *sdev;
	struct scsi_dh_data *scsi_dh_data;
	struct scsi_dh_data *scsi_dh_data;
	int i, found = 0;
	int i, found = 0;
	unsigned long flags;
	unsigned long flags;


	if (!scsi_is_sdev_device(dev))
		return 0;

	sdev = to_scsi_device(dev);

	if (action == BUS_NOTIFY_ADD_DEVICE) {
	if (action == BUS_NOTIFY_ADD_DEVICE) {
		for (i = 0; hp_sw_dh_data_list[i].vendor; i++) {
		for (i = 0; hp_sw_dh_data_list[i].vendor; i++) {
			if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor,
			if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor,
+6 −1
Original line number Original line Diff line number Diff line
@@ -608,12 +608,17 @@ static int rdac_bus_notify(struct notifier_block *nb,
			    unsigned long action, void *data)
			    unsigned long action, void *data)
{
{
	struct device *dev = data;
	struct device *dev = data;
	struct scsi_device *sdev = to_scsi_device(dev);
	struct scsi_device *sdev;
	struct scsi_dh_data *scsi_dh_data;
	struct scsi_dh_data *scsi_dh_data;
	struct rdac_dh_data *h;
	struct rdac_dh_data *h;
	int i, found = 0;
	int i, found = 0;
	unsigned long flags;
	unsigned long flags;


	if (!scsi_is_sdev_device(dev))
		return 0;

	sdev = to_scsi_device(dev);

	if (action == BUS_NOTIFY_ADD_DEVICE) {
	if (action == BUS_NOTIFY_ADD_DEVICE) {
		for (i = 0; rdac_dev_list[i].vendor; i++) {
		for (i = 0; rdac_dev_list[i].vendor; i++) {
			if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor,
			if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor,