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

Commit 6409a7d0 authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by James Bottomley
Browse files

[SCSI] mpt2sas: Null pointer deference possibility in mpt2sas_ctl_event_callback function



Added a check to identify if mpi_reply is NULL in mpt2sas_ctl_event_callback()
and return without proceeding if it is the case.

Also modified the following functions to return void instead of 0 or 1
as returning those values from events perspective doesn't make sense.
* _base_async_event()
* mpt2sas_ctl_event_callback()
* mpt2sas_scsih_event_callback()

Signed-off-by: default avatarSreekanth Reddy <Sreekanth.Reddy@lsi.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 804a5cb5
Loading
Loading
Loading
Loading
+5 −6
Original line number Original line Diff line number Diff line
@@ -768,10 +768,9 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
 * @msix_index: MSIX table index supplied by the OS
 * @msix_index: MSIX table index supplied by the OS
 * @reply: reply message frame(lower 32bit addr)
 * @reply: reply message frame(lower 32bit addr)
 *
 *
 * Return 1 meaning mf should be freed from _base_interrupt
 * Returns void.
 *        0 means the mf is freed from this function.
 */
 */
static u8
static void
_base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
_base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
{
{
	Mpi2EventNotificationReply_t *mpi_reply;
	Mpi2EventNotificationReply_t *mpi_reply;
@@ -780,9 +779,9 @@ _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)


	mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
	mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
	if (!mpi_reply)
	if (!mpi_reply)
		return 1;
		return;
	if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION)
	if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION)
		return 1;
		return;
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
	_base_display_event_data(ioc, mpi_reply);
	_base_display_event_data(ioc, mpi_reply);
#endif
#endif
@@ -812,7 +811,7 @@ _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
	/* ctl callback handler */
	/* ctl callback handler */
	mpt2sas_ctl_event_callback(ioc, msix_index, reply);
	mpt2sas_ctl_event_callback(ioc, msix_index, reply);


	return 1;
	return;
}
}


/**
/**
+2 −2
Original line number Original line Diff line number Diff line
@@ -1061,7 +1061,7 @@ void mpt2sas_base_update_missing_delay(struct MPT2SAS_ADAPTER *ioc,
int mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc);
int mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc);


/* scsih shared API */
/* scsih shared API */
u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
    u32 reply);
    u32 reply);
int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
int mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle,
	uint channel, uint id, uint lun, u8 type, u16 smid_task,
	uint channel, uint id, uint lun, u8 type, u16 smid_task,
@@ -1144,7 +1144,7 @@ void mpt2sas_ctl_exit(void);
u8 mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u8 mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
    u32 reply);
    u32 reply);
void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
u8 mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
void mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
    u32 reply);
    u32 reply);
void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
    Mpi2EventNotificationReply_t *mpi_reply);
    Mpi2EventNotificationReply_t *mpi_reply);
+8 −4
Original line number Original line Diff line number Diff line
@@ -397,18 +397,22 @@ mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
 * This function merely adds a new work task into ioc->firmware_event_thread.
 * This function merely adds a new work task into ioc->firmware_event_thread.
 * The tasks are worked from _firmware_event_work in user context.
 * The tasks are worked from _firmware_event_work in user context.
 *
 *
 * Return 1 meaning mf should be freed from _base_interrupt
 * Returns void.
 *        0 means the mf is freed from this function.
 */
 */
u8
void
mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
	u32 reply)
	u32 reply)
{
{
	Mpi2EventNotificationReply_t *mpi_reply;
	Mpi2EventNotificationReply_t *mpi_reply;


	mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
	mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
	if (unlikely(!mpi_reply)) {
		printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
		    ioc->name, __FILE__, __LINE__, __func__);
		return;
	}
	mpt2sas_ctl_add_to_event_log(ioc, mpi_reply);
	mpt2sas_ctl_add_to_event_log(ioc, mpi_reply);
	return 1;
	return;
}
}


/**
/**
+10 −11
Original line number Original line Diff line number Diff line
@@ -7471,10 +7471,9 @@ _firmware_event_work(struct work_struct *work)
 * This function merely adds a new work task into ioc->firmware_event_thread.
 * This function merely adds a new work task into ioc->firmware_event_thread.
 * The tasks are worked from _firmware_event_work in user context.
 * The tasks are worked from _firmware_event_work in user context.
 *
 *
 * Return 1 meaning mf should be freed from _base_interrupt
 * Returns void.
 *        0 means the mf is freed from this function.
 */
 */
u8
void
mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
	u32 reply)
	u32 reply)
{
{
@@ -7485,14 +7484,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,


	/* events turned off due to host reset or driver unloading */
	/* events turned off due to host reset or driver unloading */
	if (ioc->remove_host || ioc->pci_error_recovery)
	if (ioc->remove_host || ioc->pci_error_recovery)
		return 1;
		return;


	mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
	mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);


	if (unlikely(!mpi_reply)) {
	if (unlikely(!mpi_reply)) {
		printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
		printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
		    ioc->name, __FILE__, __LINE__, __func__);
		    ioc->name, __FILE__, __LINE__, __func__);
		return 1;
		return;
	}
	}


	event = le16_to_cpu(mpi_reply->Event);
	event = le16_to_cpu(mpi_reply->Event);
@@ -7507,11 +7506,11 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,


		if (baen_data->Primitive !=
		if (baen_data->Primitive !=
		    MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
		    MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
			return 1;
			return;


		if (ioc->broadcast_aen_busy) {
		if (ioc->broadcast_aen_busy) {
			ioc->broadcast_aen_pending++;
			ioc->broadcast_aen_pending++;
			return 1;
			return;
		} else
		} else
			ioc->broadcast_aen_busy = 1;
			ioc->broadcast_aen_busy = 1;
		break;
		break;
@@ -7587,14 +7586,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
		break;
		break;


	default: /* ignore the rest */
	default: /* ignore the rest */
		return 1;
		return;
	}
	}


	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
	if (!fw_event) {
	if (!fw_event) {
		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
		    ioc->name, __FILE__, __LINE__, __func__);
		    ioc->name, __FILE__, __LINE__, __func__);
		return 1;
		return;
	}
	}
	sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
	sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
	fw_event->event_data = kzalloc(sz, GFP_ATOMIC);
	fw_event->event_data = kzalloc(sz, GFP_ATOMIC);
@@ -7602,7 +7601,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
		    ioc->name, __FILE__, __LINE__, __func__);
		    ioc->name, __FILE__, __LINE__, __func__);
		kfree(fw_event);
		kfree(fw_event);
		return 1;
		return;
	}
	}


	memcpy(fw_event->event_data, mpi_reply->EventData,
	memcpy(fw_event->event_data, mpi_reply->EventData,
@@ -7612,7 +7611,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
	fw_event->VP_ID = mpi_reply->VP_ID;
	fw_event->VP_ID = mpi_reply->VP_ID;
	fw_event->event = event;
	fw_event->event = event;
	_scsih_fw_event_add(ioc, fw_event);
	_scsih_fw_event_add(ioc, fw_event);
	return 1;
	return;
}
}


/* shost template */
/* shost template */