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

Commit 6dc618cd authored by Elena Reshetova's avatar Elena Reshetova Committed by Martin K. Petersen
Browse files

scsi: libiscsi: qedi: convert iscsi_task.refcount from atomic_t to refcount_t



refcount_t type and corresponding API should be used instead of atomic_t
when the variable is used as a reference counter. This allows to avoid
accidental refcounter overflows that might lead to use-after-free
situations.

Signed-off-by: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Acked-by: default avatarChris Leech <cleech@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 22c70d1a
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -517,13 +517,13 @@ static void iscsi_free_task(struct iscsi_task *task)

void __iscsi_get_task(struct iscsi_task *task)
{
	atomic_inc(&task->refcount);
	refcount_inc(&task->refcount);
}
EXPORT_SYMBOL_GPL(__iscsi_get_task);

void __iscsi_put_task(struct iscsi_task *task)
{
	if (atomic_dec_and_test(&task->refcount))
	if (refcount_dec_and_test(&task->refcount))
		iscsi_free_task(task);
}
EXPORT_SYMBOL_GPL(__iscsi_put_task);
@@ -745,7 +745,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
	 * released by the lld when it has transmitted the task for
	 * pdus we do not expect a response for.
	 */
	atomic_set(&task->refcount, 1);
	refcount_set(&task->refcount, 1);
	task->conn = conn;
	task->sc = NULL;
	INIT_LIST_HEAD(&task->running);
@@ -1617,7 +1617,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn,
	sc->SCp.phase = conn->session->age;
	sc->SCp.ptr = (char *) task;

	atomic_set(&task->refcount, 1);
	refcount_set(&task->refcount, 1);
	task->state = ISCSI_TASK_PENDING;
	task->conn = conn;
	task->sc = sc;
+1 −1
Original line number Diff line number Diff line
@@ -1372,7 +1372,7 @@ static void qedi_cleanup_task(struct iscsi_task *task)
{
	if (!task->sc || task->state == ISCSI_TASK_PENDING) {
		QEDI_INFO(NULL, QEDI_LOG_IO, "Returning ref_cnt=%d\n",
			  atomic_read(&task->refcount));
			  refcount_read(&task->refcount));
		return;
	}

+2 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/kfifo.h>
#include <linux/refcount.h>
#include <scsi/iscsi_proto.h>
#include <scsi/iscsi_if.h>
#include <scsi/scsi_transport_iscsi.h>
@@ -139,7 +140,7 @@ struct iscsi_task {

	/* state set/tested under session->lock */
	int			state;
	atomic_t		refcount;
	refcount_t		refcount;
	struct list_head	running;	/* running cmd list */
	void			*dd_data;	/* driver/transport data */
};