[PATCH AUTOSEL 4.14 2/3] scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress

2023-01-31 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit f484a794e4ee2a9ce61f52a78e810ac45f3fe3b3 ]

If during iscsi_sw_tcp_session_create() iscsi_tcp_r2tpool_alloc() fails,
userspace could be accessing the host's ipaddress attr. If we then free the
session via iscsi_session_teardown() while userspace is still accessing the
session we will hit a use after free bug.

Set the tcp_sw_host->session after we have completed session creation and
can no longer fail.

Link: 
https://lore.kernel.org/r/20230117193937.21244-3-michael.chris...@oracle.com
Signed-off-by: Mike Christie 
Reviewed-by: Lee Duncan 
Acked-by: Ding Hui 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index e3ca16043f9a..9161fe8fba88 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -773,7 +773,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
   enum iscsi_host_param param, char *buf)
 {
struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
-   struct iscsi_session *session = tcp_sw_host->session;
+   struct iscsi_session *session;
struct iscsi_conn *conn;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
@@ -782,6 +782,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
 
switch (param) {
case ISCSI_HOST_PARAM_IPADDRESS:
+   session = tcp_sw_host->session;
if (!session)
return -ENOTCONN;
 
@@ -870,12 +871,14 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
if (!cls_session)
goto remove_host;
session = cls_session->dd_data;
-   tcp_sw_host = iscsi_host_priv(shost);
-   tcp_sw_host->session = session;
 
shost->can_queue = session->scsi_cmds_max;
if (iscsi_tcp_r2tpool_alloc(session))
goto remove_session;
+
+   /* We are now fully setup so expose the session to sysfs. */
+   tcp_sw_host = iscsi_host_priv(shost);
+   tcp_sw_host->session = session;
return cls_session;
 
 remove_session:
-- 
2.39.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230131150126.1250471-2-sashal%40kernel.org.


[PATCH AUTOSEL 4.19 2/4] scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress

2023-01-31 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit f484a794e4ee2a9ce61f52a78e810ac45f3fe3b3 ]

If during iscsi_sw_tcp_session_create() iscsi_tcp_r2tpool_alloc() fails,
userspace could be accessing the host's ipaddress attr. If we then free the
session via iscsi_session_teardown() while userspace is still accessing the
session we will hit a use after free bug.

Set the tcp_sw_host->session after we have completed session creation and
can no longer fail.

Link: 
https://lore.kernel.org/r/20230117193937.21244-3-michael.chris...@oracle.com
Signed-off-by: Mike Christie 
Reviewed-by: Lee Duncan 
Acked-by: Ding Hui 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 7212e3a13fe6..33fb111e2e19 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -775,7 +775,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
   enum iscsi_host_param param, char *buf)
 {
struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
-   struct iscsi_session *session = tcp_sw_host->session;
+   struct iscsi_session *session;
struct iscsi_conn *conn;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
@@ -784,6 +784,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
 
switch (param) {
case ISCSI_HOST_PARAM_IPADDRESS:
+   session = tcp_sw_host->session;
if (!session)
return -ENOTCONN;
 
@@ -872,12 +873,14 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
if (!cls_session)
goto remove_host;
session = cls_session->dd_data;
-   tcp_sw_host = iscsi_host_priv(shost);
-   tcp_sw_host->session = session;
 
shost->can_queue = session->scsi_cmds_max;
if (iscsi_tcp_r2tpool_alloc(session))
goto remove_session;
+
+   /* We are now fully setup so expose the session to sysfs. */
+   tcp_sw_host = iscsi_host_priv(shost);
+   tcp_sw_host->session = session;
return cls_session;
 
 remove_session:
-- 
2.39.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230131150118.1250409-2-sashal%40kernel.org.


[PATCH AUTOSEL 5.4 2/4] scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress

2023-01-31 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit f484a794e4ee2a9ce61f52a78e810ac45f3fe3b3 ]

If during iscsi_sw_tcp_session_create() iscsi_tcp_r2tpool_alloc() fails,
userspace could be accessing the host's ipaddress attr. If we then free the
session via iscsi_session_teardown() while userspace is still accessing the
session we will hit a use after free bug.

Set the tcp_sw_host->session after we have completed session creation and
can no longer fail.

Link: 
https://lore.kernel.org/r/20230117193937.21244-3-michael.chris...@oracle.com
Signed-off-by: Mike Christie 
Reviewed-by: Lee Duncan 
Acked-by: Ding Hui 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index b5dd1caae5e9..9320a0a92bb2 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -770,7 +770,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
   enum iscsi_host_param param, char *buf)
 {
struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
-   struct iscsi_session *session = tcp_sw_host->session;
+   struct iscsi_session *session;
struct iscsi_conn *conn;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
@@ -779,6 +779,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
 
switch (param) {
case ISCSI_HOST_PARAM_IPADDRESS:
+   session = tcp_sw_host->session;
if (!session)
return -ENOTCONN;
 
@@ -867,12 +868,14 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
if (!cls_session)
goto remove_host;
session = cls_session->dd_data;
-   tcp_sw_host = iscsi_host_priv(shost);
-   tcp_sw_host->session = session;
 
shost->can_queue = session->scsi_cmds_max;
if (iscsi_tcp_r2tpool_alloc(session))
goto remove_session;
+
+   /* We are now fully setup so expose the session to sysfs. */
+   tcp_sw_host = iscsi_host_priv(shost);
+   tcp_sw_host->session = session;
return cls_session;
 
 remove_session:
-- 
2.39.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230131150110.1250351-2-sashal%40kernel.org.


[PATCH AUTOSEL 5.10 3/6] scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress

2023-01-31 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit f484a794e4ee2a9ce61f52a78e810ac45f3fe3b3 ]

If during iscsi_sw_tcp_session_create() iscsi_tcp_r2tpool_alloc() fails,
userspace could be accessing the host's ipaddress attr. If we then free the
session via iscsi_session_teardown() while userspace is still accessing the
session we will hit a use after free bug.

Set the tcp_sw_host->session after we have completed session creation and
can no longer fail.

Link: 
https://lore.kernel.org/r/20230117193937.21244-3-michael.chris...@oracle.com
Signed-off-by: Mike Christie 
Reviewed-by: Lee Duncan 
Acked-by: Ding Hui 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 6485c1aa9e74..252d7881f99c 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -802,7 +802,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
   enum iscsi_host_param param, char *buf)
 {
struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
-   struct iscsi_session *session = tcp_sw_host->session;
+   struct iscsi_session *session;
struct iscsi_conn *conn;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
@@ -812,6 +812,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
 
switch (param) {
case ISCSI_HOST_PARAM_IPADDRESS:
+   session = tcp_sw_host->session;
if (!session)
return -ENOTCONN;
 
@@ -906,12 +907,14 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
if (!cls_session)
goto remove_host;
session = cls_session->dd_data;
-   tcp_sw_host = iscsi_host_priv(shost);
-   tcp_sw_host->session = session;
 
shost->can_queue = session->scsi_cmds_max;
if (iscsi_tcp_r2tpool_alloc(session))
goto remove_session;
+
+   /* We are now fully setup so expose the session to sysfs. */
+   tcp_sw_host = iscsi_host_priv(shost);
+   tcp_sw_host->session = session;
return cls_session;
 
 remove_session:
-- 
2.39.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230131150100.1250267-3-sashal%40kernel.org.


[PATCH AUTOSEL 5.15 05/12] scsi: iscsi_tcp: Fix UAF during logout when accessing the shost ipaddress

2023-01-31 Thread Sasha Levin
des sysfs and removal from host
tracking.

 2. freeing of session.

During iscsi_tcp host and session removal we can remove the session from
sysfs then remove the host from sysfs. At this point we know userspace is
not accessing the kernel via sysfs so we can free the session and host.

Link: 
https://lore.kernel.org/r/20230117193937.21244-2-michael.chris...@oracle.com
Signed-off-by: Mike Christie 
Reviewed-by: Lee Duncan 
Acked-by: Ding Hui 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 11 +--
 drivers/scsi/libiscsi.c  | 38 +++---
 include/scsi/libiscsi.h  |  2 ++
 3 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 4d2f33087806..5c19e75c0e2f 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -982,10 +982,17 @@ static void iscsi_sw_tcp_session_destroy(struct 
iscsi_cls_session *cls_session)
if (WARN_ON_ONCE(session->leadconn))
return;
 
+   iscsi_session_remove(cls_session);
+   /*
+* Our get_host_param needs to access the session, so remove the
+* host from sysfs before freeing the session to make sure userspace
+* is no longer accessing the callout.
+*/
+   iscsi_host_remove(shost, false);
+
iscsi_tcp_r2tpool_free(cls_session->dd_data);
-   iscsi_session_teardown(cls_session);
 
-   iscsi_host_remove(shost, false);
+   iscsi_session_free(cls_session);
iscsi_host_free(shost);
 }
 
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 73d235540b98..d422e8fd7137 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -3024,17 +3024,32 @@ iscsi_session_setup(struct iscsi_transport *iscsit, 
struct Scsi_Host *shost,
 }
 EXPORT_SYMBOL_GPL(iscsi_session_setup);
 
-/**
- * iscsi_session_teardown - destroy session, host, and cls_session
- * @cls_session: iscsi session
+/*
+ * issi_session_remove - Remove session from iSCSI class.
  */
-void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
+void iscsi_session_remove(struct iscsi_cls_session *cls_session)
 {
struct iscsi_session *session = cls_session->dd_data;
-   struct module *owner = cls_session->transport->owner;
struct Scsi_Host *shost = session->host;
 
iscsi_remove_session(cls_session);
+   /*
+* host removal only has to wait for its children to be removed from
+* sysfs, and iscsi_tcp needs to do iscsi_host_remove before freeing
+* the session, so drop the session count here.
+*/
+   iscsi_host_dec_session_cnt(shost);
+}
+EXPORT_SYMBOL_GPL(iscsi_session_remove);
+
+/**
+ * iscsi_session_free - Free iscsi session and it's resources
+ * @cls_session: iscsi session
+ */
+void iscsi_session_free(struct iscsi_cls_session *cls_session)
+{
+   struct iscsi_session *session = cls_session->dd_data;
+   struct module *owner = cls_session->transport->owner;
 
iscsi_pool_free(>cmdpool);
kfree(session->password);
@@ -3052,10 +3067,19 @@ void iscsi_session_teardown(struct iscsi_cls_session 
*cls_session)
kfree(session->discovery_parent_type);
 
iscsi_free_session(cls_session);
-
-   iscsi_host_dec_session_cnt(shost);
module_put(owner);
 }
+EXPORT_SYMBOL_GPL(iscsi_session_free);
+
+/**
+ * iscsi_session_teardown - destroy session and cls_session
+ * @cls_session: iscsi session
+ */
+void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
+{
+   iscsi_session_remove(cls_session);
+   iscsi_session_free(cls_session);
+}
 EXPORT_SYMBOL_GPL(iscsi_session_teardown);
 
 /**
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 5cf84228b51d..c7ee5279e7fc 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -414,6 +414,8 @@ extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host 
*shost,
 extern struct iscsi_cls_session *
 iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
uint16_t, int, int, uint32_t, unsigned int);
+void iscsi_session_remove(struct iscsi_cls_session *cls_session);
+void iscsi_session_free(struct iscsi_cls_session *cls_session);
 extern void iscsi_session_teardown(struct iscsi_cls_session *);
 extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
 extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
-- 
2.39.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230131150030.1250104-5-sashal%40kernel.org.


[PATCH AUTOSEL 5.15 06/12] scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress

2023-01-31 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit f484a794e4ee2a9ce61f52a78e810ac45f3fe3b3 ]

If during iscsi_sw_tcp_session_create() iscsi_tcp_r2tpool_alloc() fails,
userspace could be accessing the host's ipaddress attr. If we then free the
session via iscsi_session_teardown() while userspace is still accessing the
session we will hit a use after free bug.

Set the tcp_sw_host->session after we have completed session creation and
can no longer fail.

Link: 
https://lore.kernel.org/r/20230117193937.21244-3-michael.chris...@oracle.com
Signed-off-by: Mike Christie 
Reviewed-by: Lee Duncan 
Acked-by: Ding Hui 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 5c19e75c0e2f..594336004190 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -848,7 +848,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
   enum iscsi_host_param param, char *buf)
 {
struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
-   struct iscsi_session *session = tcp_sw_host->session;
+   struct iscsi_session *session;
struct iscsi_conn *conn;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
@@ -858,6 +858,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
 
switch (param) {
case ISCSI_HOST_PARAM_IPADDRESS:
+   session = tcp_sw_host->session;
if (!session)
return -ENOTCONN;
 
@@ -958,11 +959,13 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
if (!cls_session)
goto remove_host;
session = cls_session->dd_data;
-   tcp_sw_host = iscsi_host_priv(shost);
-   tcp_sw_host->session = session;
 
if (iscsi_tcp_r2tpool_alloc(session))
goto remove_session;
+
+   /* We are now fully setup so expose the session to sysfs. */
+   tcp_sw_host = iscsi_host_priv(shost);
+   tcp_sw_host->session = session;
return cls_session;
 
 remove_session:
-- 
2.39.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230131150030.1250104-6-sashal%40kernel.org.


[PATCH AUTOSEL 6.1 07/20] scsi: iscsi_tcp: Fix UAF during logout when accessing the shost ipaddress

2023-01-31 Thread Sasha Levin
des sysfs and removal from host
tracking.

 2. freeing of session.

During iscsi_tcp host and session removal we can remove the session from
sysfs then remove the host from sysfs. At this point we know userspace is
not accessing the kernel via sysfs so we can free the session and host.

Link: 
https://lore.kernel.org/r/20230117193937.21244-2-michael.chris...@oracle.com
Signed-off-by: Mike Christie 
Reviewed-by: Lee Duncan 
Acked-by: Ding Hui 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 11 +--
 drivers/scsi/libiscsi.c  | 38 +++---
 include/scsi/libiscsi.h  |  2 ++
 3 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 5fb1f364e815..9c0c8f34ef67 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -982,10 +982,17 @@ static void iscsi_sw_tcp_session_destroy(struct 
iscsi_cls_session *cls_session)
if (WARN_ON_ONCE(session->leadconn))
return;
 
+   iscsi_session_remove(cls_session);
+   /*
+* Our get_host_param needs to access the session, so remove the
+* host from sysfs before freeing the session to make sure userspace
+* is no longer accessing the callout.
+*/
+   iscsi_host_remove(shost, false);
+
iscsi_tcp_r2tpool_free(cls_session->dd_data);
-   iscsi_session_teardown(cls_session);
 
-   iscsi_host_remove(shost, false);
+   iscsi_session_free(cls_session);
iscsi_host_free(shost);
 }
 
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index d95f4bcdeb2e..6e811d753cb1 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -3104,17 +3104,32 @@ iscsi_session_setup(struct iscsi_transport *iscsit, 
struct Scsi_Host *shost,
 }
 EXPORT_SYMBOL_GPL(iscsi_session_setup);
 
-/**
- * iscsi_session_teardown - destroy session, host, and cls_session
- * @cls_session: iscsi session
+/*
+ * issi_session_remove - Remove session from iSCSI class.
  */
-void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
+void iscsi_session_remove(struct iscsi_cls_session *cls_session)
 {
struct iscsi_session *session = cls_session->dd_data;
-   struct module *owner = cls_session->transport->owner;
struct Scsi_Host *shost = session->host;
 
iscsi_remove_session(cls_session);
+   /*
+* host removal only has to wait for its children to be removed from
+* sysfs, and iscsi_tcp needs to do iscsi_host_remove before freeing
+* the session, so drop the session count here.
+*/
+   iscsi_host_dec_session_cnt(shost);
+}
+EXPORT_SYMBOL_GPL(iscsi_session_remove);
+
+/**
+ * iscsi_session_free - Free iscsi session and it's resources
+ * @cls_session: iscsi session
+ */
+void iscsi_session_free(struct iscsi_cls_session *cls_session)
+{
+   struct iscsi_session *session = cls_session->dd_data;
+   struct module *owner = cls_session->transport->owner;
 
iscsi_pool_free(>cmdpool);
kfree(session->password);
@@ -3132,10 +3147,19 @@ void iscsi_session_teardown(struct iscsi_cls_session 
*cls_session)
kfree(session->discovery_parent_type);
 
iscsi_free_session(cls_session);
-
-   iscsi_host_dec_session_cnt(shost);
module_put(owner);
 }
+EXPORT_SYMBOL_GPL(iscsi_session_free);
+
+/**
+ * iscsi_session_teardown - destroy session and cls_session
+ * @cls_session: iscsi session
+ */
+void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
+{
+   iscsi_session_remove(cls_session);
+   iscsi_session_free(cls_session);
+}
 EXPORT_SYMBOL_GPL(iscsi_session_teardown);
 
 /**
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 654cc3918c94..7fb3cb787df4 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -422,6 +422,8 @@ extern int iscsi_host_get_max_scsi_cmds(struct Scsi_Host 
*shost,
 extern struct iscsi_cls_session *
 iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
uint16_t, int, int, uint32_t, unsigned int);
+void iscsi_session_remove(struct iscsi_cls_session *cls_session);
+void iscsi_session_free(struct iscsi_cls_session *cls_session);
 extern void iscsi_session_teardown(struct iscsi_cls_session *);
 extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
 extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
-- 
2.39.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230131145946.1249850-7-sashal%40kernel.org.


[PATCH AUTOSEL 6.1 08/20] scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress

2023-01-31 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit f484a794e4ee2a9ce61f52a78e810ac45f3fe3b3 ]

If during iscsi_sw_tcp_session_create() iscsi_tcp_r2tpool_alloc() fails,
userspace could be accessing the host's ipaddress attr. If we then free the
session via iscsi_session_teardown() while userspace is still accessing the
session we will hit a use after free bug.

Set the tcp_sw_host->session after we have completed session creation and
can no longer fail.

Link: 
https://lore.kernel.org/r/20230117193937.21244-3-michael.chris...@oracle.com
Signed-off-by: Mike Christie 
Reviewed-by: Lee Duncan 
Acked-by: Ding Hui 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 9c0c8f34ef67..c3ad04ad66e0 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -848,7 +848,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
   enum iscsi_host_param param, char *buf)
 {
struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost);
-   struct iscsi_session *session = tcp_sw_host->session;
+   struct iscsi_session *session;
struct iscsi_conn *conn;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
@@ -858,6 +858,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host 
*shost,
 
switch (param) {
case ISCSI_HOST_PARAM_IPADDRESS:
+   session = tcp_sw_host->session;
if (!session)
return -ENOTCONN;
 
@@ -958,11 +959,13 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
if (!cls_session)
goto remove_host;
session = cls_session->dd_data;
-   tcp_sw_host = iscsi_host_priv(shost);
-   tcp_sw_host->session = session;
 
if (iscsi_tcp_r2tpool_alloc(session))
goto remove_session;
+
+   /* We are now fully setup so expose the session to sysfs. */
+   tcp_sw_host = iscsi_host_priv(shost);
+   tcp_sw_host->session = session;
return cls_session;
 
 remove_session:
-- 
2.39.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20230131145946.1249850-8-sashal%40kernel.org.


[PATCH AUTOSEL 5.10 01/17] scsi: iscsi: Fix multiple iSCSI session unbind events sent to userspace

2023-01-16 Thread Sasha Levin
From: Wenchao Hao 

[ Upstream commit a3be19b91ea7121d388084e8c07f5b1b982eb40c ]

It was observed that the kernel would potentially send
ISCSI_KEVENT_UNBIND_SESSION multiple times. Introduce 'target_state' in
iscsi_cls_session() to make sure session will send only one unbind session
event.

This introduces a regression wrt. the issue fixed in commit 13e60d3ba287
("scsi: iscsi: Report unbind session event when the target has been
removed"). If iscsid dies for any reason after sending an unbind session to
kernel, once iscsid is restarted, the kernel's ISCSI_KEVENT_UNBIND_SESSION
event is lost and userspace is then unable to logout. However, the session
is actually in invalid state (its target_id is INVALID) so iscsid should
not sync this session during restart.

Consequently we need to check the session's target state during iscsid
restart.  If session is in unbound state, do not sync this session and
perform session teardown. This is OK because once a session is unbound, we
can not recover it any more (mainly because its target id is INVALID).

Signed-off-by: Wenchao Hao 
Link: https://lore.kernel.org/r/20221126010752.231917-1-haowenc...@huawei.com
Reviewed-by: Mike Christie 
Reviewed-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 50 ++---
 include/scsi/scsi_transport_iscsi.h |  9 ++
 2 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index ef7cd7520e7c..092bd6a3d64a 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1674,6 +1674,13 @@ static const char *iscsi_session_state_name(int state)
return name;
 }
 
+static char *iscsi_session_target_state_name[] = {
+   [ISCSI_SESSION_TARGET_UNBOUND]   = "UNBOUND",
+   [ISCSI_SESSION_TARGET_ALLOCATED] = "ALLOCATED",
+   [ISCSI_SESSION_TARGET_SCANNED]   = "SCANNED",
+   [ISCSI_SESSION_TARGET_UNBINDING] = "UNBINDING",
+};
+
 int iscsi_session_chkready(struct iscsi_cls_session *session)
 {
unsigned long flags;
@@ -1805,9 +1812,13 @@ static int iscsi_user_scan_session(struct device *dev, 
void *data)
if ((scan_data->channel == SCAN_WILD_CARD ||
 scan_data->channel == 0) &&
(scan_data->id == SCAN_WILD_CARD ||
-scan_data->id == id))
+scan_data->id == id)) {
scsi_scan_target(>dev, 0, id,
 scan_data->lun, scan_data->rescan);
+   spin_lock_irqsave(>lock, flags);
+   session->target_state = ISCSI_SESSION_TARGET_SCANNED;
+   spin_unlock_irqrestore(>lock, flags);
+   }
}
 
 user_scan_exit:
@@ -1996,31 +2007,41 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
struct iscsi_cls_host *ihost = shost->shost_data;
unsigned long flags;
unsigned int target_id;
+   bool remove_target = true;
 
ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n");
 
/* Prevent new scans and make sure scanning is not in progress */
mutex_lock(>mutex);
spin_lock_irqsave(>lock, flags);
-   if (session->target_id == ISCSI_MAX_TARGET) {
+   if (session->target_state == ISCSI_SESSION_TARGET_ALLOCATED) {
+   remove_target = false;
+   } else if (session->target_state != ISCSI_SESSION_TARGET_SCANNED) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   goto unbind_session_exit;
+   ISCSI_DBG_TRANS_SESSION(session,
+   "Skipping target unbinding: Session is 
unbound/unbinding.\n");
+   return;
}
 
+   session->target_state = ISCSI_SESSION_TARGET_UNBINDING;
target_id = session->target_id;
session->target_id = ISCSI_MAX_TARGET;
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
 
-   scsi_remove_target(>dev);
+   if (remove_target)
+   scsi_remove_target(>dev);
 
if (session->ida_used)
ida_simple_remove(_sess_ida, target_id);
 
-unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
+
+   spin_lock_irqsave(>lock, flags);
+   session->target_state = ISCSI_SESSION_TARGET_UNBOUND;
+   spin_unlock_irqrestore(>lock, flags);
 }
 
 static void __iscsi_destroy_session(struct work_struct *work)
@@ -2089,6 +2110,9 @@ int iscsi_add_session(struct iscsi_cls_session *session, 
unsigned int target_id)
session->id

[PATCH AUTOSEL 5.15 01/24] scsi: iscsi: Fix multiple iSCSI session unbind events sent to userspace

2023-01-16 Thread Sasha Levin
From: Wenchao Hao 

[ Upstream commit a3be19b91ea7121d388084e8c07f5b1b982eb40c ]

It was observed that the kernel would potentially send
ISCSI_KEVENT_UNBIND_SESSION multiple times. Introduce 'target_state' in
iscsi_cls_session() to make sure session will send only one unbind session
event.

This introduces a regression wrt. the issue fixed in commit 13e60d3ba287
("scsi: iscsi: Report unbind session event when the target has been
removed"). If iscsid dies for any reason after sending an unbind session to
kernel, once iscsid is restarted, the kernel's ISCSI_KEVENT_UNBIND_SESSION
event is lost and userspace is then unable to logout. However, the session
is actually in invalid state (its target_id is INVALID) so iscsid should
not sync this session during restart.

Consequently we need to check the session's target state during iscsid
restart.  If session is in unbound state, do not sync this session and
perform session teardown. This is OK because once a session is unbound, we
can not recover it any more (mainly because its target id is INVALID).

Signed-off-by: Wenchao Hao 
Link: https://lore.kernel.org/r/20221126010752.231917-1-haowenc...@huawei.com
Reviewed-by: Mike Christie 
Reviewed-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 50 ++---
 include/scsi/scsi_transport_iscsi.h |  9 ++
 2 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index cc39cbef9d7f..4d23e5af20d3 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1679,6 +1679,13 @@ static const char *iscsi_session_state_name(int state)
return name;
 }
 
+static char *iscsi_session_target_state_name[] = {
+   [ISCSI_SESSION_TARGET_UNBOUND]   = "UNBOUND",
+   [ISCSI_SESSION_TARGET_ALLOCATED] = "ALLOCATED",
+   [ISCSI_SESSION_TARGET_SCANNED]   = "SCANNED",
+   [ISCSI_SESSION_TARGET_UNBINDING] = "UNBINDING",
+};
+
 int iscsi_session_chkready(struct iscsi_cls_session *session)
 {
int err;
@@ -1807,9 +1814,13 @@ static int iscsi_user_scan_session(struct device *dev, 
void *data)
if ((scan_data->channel == SCAN_WILD_CARD ||
 scan_data->channel == 0) &&
(scan_data->id == SCAN_WILD_CARD ||
-scan_data->id == id))
+scan_data->id == id)) {
scsi_scan_target(>dev, 0, id,
 scan_data->lun, scan_data->rescan);
+   spin_lock_irqsave(>lock, flags);
+   session->target_state = ISCSI_SESSION_TARGET_SCANNED;
+   spin_unlock_irqrestore(>lock, flags);
+   }
}
 
 user_scan_exit:
@@ -1998,31 +2009,41 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
struct iscsi_cls_host *ihost = shost->shost_data;
unsigned long flags;
unsigned int target_id;
+   bool remove_target = true;
 
ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n");
 
/* Prevent new scans and make sure scanning is not in progress */
mutex_lock(>mutex);
spin_lock_irqsave(>lock, flags);
-   if (session->target_id == ISCSI_MAX_TARGET) {
+   if (session->target_state == ISCSI_SESSION_TARGET_ALLOCATED) {
+   remove_target = false;
+   } else if (session->target_state != ISCSI_SESSION_TARGET_SCANNED) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   goto unbind_session_exit;
+   ISCSI_DBG_TRANS_SESSION(session,
+   "Skipping target unbinding: Session is 
unbound/unbinding.\n");
+   return;
}
 
+   session->target_state = ISCSI_SESSION_TARGET_UNBINDING;
target_id = session->target_id;
session->target_id = ISCSI_MAX_TARGET;
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
 
-   scsi_remove_target(>dev);
+   if (remove_target)
+   scsi_remove_target(>dev);
 
if (session->ida_used)
ida_simple_remove(_sess_ida, target_id);
 
-unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
+
+   spin_lock_irqsave(>lock, flags);
+   session->target_state = ISCSI_SESSION_TARGET_UNBOUND;
+   spin_unlock_irqrestore(>lock, flags);
 }
 
 static void __iscsi_destroy_session(struct work_struct *work)
@@ -2091,6 +2112,9 @@ int iscsi_add_session(struct iscsi_cls_session *session, 
unsigned int target_id)
session->ida_used = true;
} else
  

[PATCH AUTOSEL 6.1 01/53] scsi: iscsi: Fix multiple iSCSI session unbind events sent to userspace

2023-01-16 Thread Sasha Levin
From: Wenchao Hao 

[ Upstream commit a3be19b91ea7121d388084e8c07f5b1b982eb40c ]

It was observed that the kernel would potentially send
ISCSI_KEVENT_UNBIND_SESSION multiple times. Introduce 'target_state' in
iscsi_cls_session() to make sure session will send only one unbind session
event.

This introduces a regression wrt. the issue fixed in commit 13e60d3ba287
("scsi: iscsi: Report unbind session event when the target has been
removed"). If iscsid dies for any reason after sending an unbind session to
kernel, once iscsid is restarted, the kernel's ISCSI_KEVENT_UNBIND_SESSION
event is lost and userspace is then unable to logout. However, the session
is actually in invalid state (its target_id is INVALID) so iscsid should
not sync this session during restart.

Consequently we need to check the session's target state during iscsid
restart.  If session is in unbound state, do not sync this session and
perform session teardown. This is OK because once a session is unbound, we
can not recover it any more (mainly because its target id is INVALID).

Signed-off-by: Wenchao Hao 
Link: https://lore.kernel.org/r/20221126010752.231917-1-haowenc...@huawei.com
Reviewed-by: Mike Christie 
Reviewed-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 50 ++---
 include/scsi/scsi_transport_iscsi.h |  9 ++
 2 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index f473c002fa4d..bf834e72595a 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1677,6 +1677,13 @@ static const char *iscsi_session_state_name(int state)
return name;
 }
 
+static char *iscsi_session_target_state_name[] = {
+   [ISCSI_SESSION_TARGET_UNBOUND]   = "UNBOUND",
+   [ISCSI_SESSION_TARGET_ALLOCATED] = "ALLOCATED",
+   [ISCSI_SESSION_TARGET_SCANNED]   = "SCANNED",
+   [ISCSI_SESSION_TARGET_UNBINDING] = "UNBINDING",
+};
+
 int iscsi_session_chkready(struct iscsi_cls_session *session)
 {
int err;
@@ -1786,9 +1793,13 @@ static int iscsi_user_scan_session(struct device *dev, 
void *data)
if ((scan_data->channel == SCAN_WILD_CARD ||
 scan_data->channel == 0) &&
(scan_data->id == SCAN_WILD_CARD ||
-scan_data->id == id))
+scan_data->id == id)) {
scsi_scan_target(>dev, 0, id,
 scan_data->lun, scan_data->rescan);
+   spin_lock_irqsave(>lock, flags);
+   session->target_state = ISCSI_SESSION_TARGET_SCANNED;
+   spin_unlock_irqrestore(>lock, flags);
+   }
}
 
 user_scan_exit:
@@ -1961,31 +1972,41 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
struct iscsi_cls_host *ihost = shost->shost_data;
unsigned long flags;
unsigned int target_id;
+   bool remove_target = true;
 
ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n");
 
/* Prevent new scans and make sure scanning is not in progress */
mutex_lock(>mutex);
spin_lock_irqsave(>lock, flags);
-   if (session->target_id == ISCSI_MAX_TARGET) {
+   if (session->target_state == ISCSI_SESSION_TARGET_ALLOCATED) {
+   remove_target = false;
+   } else if (session->target_state != ISCSI_SESSION_TARGET_SCANNED) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   goto unbind_session_exit;
+   ISCSI_DBG_TRANS_SESSION(session,
+   "Skipping target unbinding: Session is 
unbound/unbinding.\n");
+   return;
}
 
+   session->target_state = ISCSI_SESSION_TARGET_UNBINDING;
target_id = session->target_id;
session->target_id = ISCSI_MAX_TARGET;
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
 
-   scsi_remove_target(>dev);
+   if (remove_target)
+   scsi_remove_target(>dev);
 
if (session->ida_used)
ida_free(_sess_ida, target_id);
 
-unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
+
+   spin_lock_irqsave(>lock, flags);
+   session->target_state = ISCSI_SESSION_TARGET_UNBOUND;
+   spin_unlock_irqrestore(>lock, flags);
 }
 
 static void __iscsi_destroy_session(struct work_struct *work)
@@ -2062,6 +2083,9 @@ int iscsi_add_session(struct iscsi_cls_session *session, 
unsigned int target_id)
session->ida_used = true;
} else

[PATCH AUTOSEL 5.15 28/31] scsi: iscsi: Fix possible memory leak when device_register() failed

2022-11-23 Thread Sasha Levin
From: Zhou Guanghui 

[ Upstream commit f014165faa7b953b81dcbf18835936e5f8d01f2a ]

If device_register() returns error, the name allocated by the
dev_set_name() need be freed. As described in the comment of
device_register(), we should use put_device() to give up the reference in
the error path.

Fix this by calling put_device(), the name will be freed in the
kobject_cleanup(), and this patch modified resources will be released by
calling the corresponding callback function in the device_release().

Signed-off-by: Zhou Guanghui 
Link: https://lore.kernel.org/r/20221110033729.1555-1-zhouguangh...@huawei.com
Reviewed-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 31 +++--
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index f46ae5391758..cc39cbef9d7f 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -232,7 +232,7 @@ iscsi_create_endpoint(int dd_size)
dev_set_name(>dev, "ep-%d", id);
err = device_register(>dev);
 if (err)
-   goto free_id;
+   goto put_dev;
 
err = sysfs_create_group(>dev.kobj, _endpoint_group);
if (err)
@@ -246,10 +246,12 @@ iscsi_create_endpoint(int dd_size)
device_unregister(>dev);
return NULL;
 
-free_id:
+put_dev:
mutex_lock(_ep_idr_mutex);
idr_remove(_ep_idr, id);
mutex_unlock(_ep_idr_mutex);
+   put_device(>dev);
+   return NULL;
 free_ep:
kfree(ep);
return NULL;
@@ -767,7 +769,7 @@ iscsi_create_iface(struct Scsi_Host *shost, struct 
iscsi_transport *transport,
 
err = device_register(>dev);
if (err)
-   goto free_iface;
+   goto put_dev;
 
err = sysfs_create_group(>dev.kobj, _iface_group);
if (err)
@@ -781,9 +783,8 @@ iscsi_create_iface(struct Scsi_Host *shost, struct 
iscsi_transport *transport,
device_unregister(>dev);
return NULL;
 
-free_iface:
-   put_device(iface->dev.parent);
-   kfree(iface);
+put_dev:
+   put_device(>dev);
return NULL;
 }
 EXPORT_SYMBOL_GPL(iscsi_create_iface);
@@ -1252,15 +1253,15 @@ iscsi_create_flashnode_sess(struct Scsi_Host *shost, 
int index,
 
err = device_register(_sess->dev);
if (err)
-   goto free_fnode_sess;
+   goto put_dev;
 
if (dd_size)
fnode_sess->dd_data = _sess[1];
 
return fnode_sess;
 
-free_fnode_sess:
-   kfree(fnode_sess);
+put_dev:
+   put_device(_sess->dev);
return NULL;
 }
 EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
@@ -1300,15 +1301,15 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,
 
err = device_register(_conn->dev);
if (err)
-   goto free_fnode_conn;
+   goto put_dev;
 
if (dd_size)
fnode_conn->dd_data = _conn[1];
 
return fnode_conn;
 
-free_fnode_conn:
-   kfree(fnode_conn);
+put_dev:
+   put_device(_conn->dev);
return NULL;
 }
 EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
@@ -4838,7 +4839,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
dev_set_name(>dev, "%s", tt->name);
err = device_register(>dev);
if (err)
-   goto free_priv;
+   goto put_dev;
 
err = sysfs_create_group(>dev.kobj, _transport_group);
if (err)
@@ -4873,8 +4874,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
 unregister_dev:
device_unregister(>dev);
return NULL;
-free_priv:
-   kfree(priv);
+put_dev:
+   put_device(>dev);
return NULL;
 }
 EXPORT_SYMBOL_GPL(iscsi_register_transport);
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20221123124234.265396-28-sashal%40kernel.org.


[PATCH AUTOSEL 6.0 41/44] scsi: iscsi: Fix possible memory leak when device_register() failed

2022-11-23 Thread Sasha Levin
From: Zhou Guanghui 

[ Upstream commit f014165faa7b953b81dcbf18835936e5f8d01f2a ]

If device_register() returns error, the name allocated by the
dev_set_name() need be freed. As described in the comment of
device_register(), we should use put_device() to give up the reference in
the error path.

Fix this by calling put_device(), the name will be freed in the
kobject_cleanup(), and this patch modified resources will be released by
calling the corresponding callback function in the device_release().

Signed-off-by: Zhou Guanghui 
Link: https://lore.kernel.org/r/20221110033729.1555-1-zhouguangh...@huawei.com
Reviewed-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 31 +++--
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index cd3db9684e52..f473c002fa4d 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -231,7 +231,7 @@ iscsi_create_endpoint(int dd_size)
dev_set_name(>dev, "ep-%d", id);
err = device_register(>dev);
 if (err)
-   goto free_id;
+   goto put_dev;
 
err = sysfs_create_group(>dev.kobj, _endpoint_group);
if (err)
@@ -245,10 +245,12 @@ iscsi_create_endpoint(int dd_size)
device_unregister(>dev);
return NULL;
 
-free_id:
+put_dev:
mutex_lock(_ep_idr_mutex);
idr_remove(_ep_idr, id);
mutex_unlock(_ep_idr_mutex);
+   put_device(>dev);
+   return NULL;
 free_ep:
kfree(ep);
return NULL;
@@ -766,7 +768,7 @@ iscsi_create_iface(struct Scsi_Host *shost, struct 
iscsi_transport *transport,
 
err = device_register(>dev);
if (err)
-   goto free_iface;
+   goto put_dev;
 
err = sysfs_create_group(>dev.kobj, _iface_group);
if (err)
@@ -780,9 +782,8 @@ iscsi_create_iface(struct Scsi_Host *shost, struct 
iscsi_transport *transport,
device_unregister(>dev);
return NULL;
 
-free_iface:
-   put_device(iface->dev.parent);
-   kfree(iface);
+put_dev:
+   put_device(>dev);
return NULL;
 }
 EXPORT_SYMBOL_GPL(iscsi_create_iface);
@@ -1251,15 +1252,15 @@ iscsi_create_flashnode_sess(struct Scsi_Host *shost, 
int index,
 
err = device_register(_sess->dev);
if (err)
-   goto free_fnode_sess;
+   goto put_dev;
 
if (dd_size)
fnode_sess->dd_data = _sess[1];
 
return fnode_sess;
 
-free_fnode_sess:
-   kfree(fnode_sess);
+put_dev:
+   put_device(_sess->dev);
return NULL;
 }
 EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
@@ -1299,15 +1300,15 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,
 
err = device_register(_conn->dev);
if (err)
-   goto free_fnode_conn;
+   goto put_dev;
 
if (dd_size)
fnode_conn->dd_data = _conn[1];
 
return fnode_conn;
 
-free_fnode_conn:
-   kfree(fnode_conn);
+put_dev:
+   put_device(_conn->dev);
return NULL;
 }
 EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
@@ -4815,7 +4816,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
dev_set_name(>dev, "%s", tt->name);
err = device_register(>dev);
if (err)
-   goto free_priv;
+   goto put_dev;
 
err = sysfs_create_group(>dev.kobj, _transport_group);
if (err)
@@ -4850,8 +4851,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
 unregister_dev:
device_unregister(>dev);
return NULL;
-free_priv:
-   kfree(priv);
+put_dev:
+   put_device(>dev);
return NULL;
 }
 EXPORT_SYMBOL_GPL(iscsi_register_transport);
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20221123124057.264822-41-sashal%40kernel.org.


[PATCH AUTOSEL 5.18 18/56] scsi: iscsi: Fix HW conn removal use after free

2022-08-14 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit c577ab7ba5f3bf9062db8a58b6e89d4fe370447e ]

If qla4xxx doesn't remove the connection before the session, the iSCSI
class tries to remove the connection for it. We were doing a
iscsi_put_conn() in the iter function which is not needed and will result
in a use after free because iscsi_remove_conn() will free the connection.

Link: 
https://lore.kernel.org/r/20220616222738.5722-2-michael.chris...@oracle.com
Tested-by: Nilesh Javali 
Reviewed-by: Lee Duncan 
Reviewed-by: Nilesh Javali 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 5d21f07456c6..6e73f14b9749 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2143,8 +2143,6 @@ static int iscsi_iter_destroy_conn_fn(struct device *dev, 
void *data)
return 0;
 
iscsi_remove_conn(iscsi_dev_to_conn(dev));
-   iscsi_put_conn(iscsi_dev_to_conn(dev));
-
return 0;
 }
 
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220814153026.2377377-18-sashal%40kernel.org.


[PATCH AUTOSEL 5.19 22/64] scsi: iscsi: Fix HW conn removal use after free

2022-08-14 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit c577ab7ba5f3bf9062db8a58b6e89d4fe370447e ]

If qla4xxx doesn't remove the connection before the session, the iSCSI
class tries to remove the connection for it. We were doing a
iscsi_put_conn() in the iter function which is not needed and will result
in a use after free because iscsi_remove_conn() will free the connection.

Link: 
https://lore.kernel.org/r/20220616222738.5722-2-michael.chris...@oracle.com
Tested-by: Nilesh Javali 
Reviewed-by: Lee Duncan 
Reviewed-by: Nilesh Javali 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 5d21f07456c6..6e73f14b9749 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2143,8 +2143,6 @@ static int iscsi_iter_destroy_conn_fn(struct device *dev, 
void *data)
return 0;
 
iscsi_remove_conn(iscsi_dev_to_conn(dev));
-   iscsi_put_conn(iscsi_dev_to_conn(dev));
-
return 0;
 }
 
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220814152437.2374207-22-sashal%40kernel.org.


[PATCH AUTOSEL 5.15 20/27] scsi: iscsi: Merge suspend fields

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit 5bd856256f8c03e329f8ff36d8c8efcb111fe6df ]

Move the tx and rx suspend fields into one flags field.

Link: 
https://lore.kernel.org/r/20220408001314.5014-8-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/bnx2i/bnx2i_hwi.c   |  2 +-
 drivers/scsi/bnx2i/bnx2i_iscsi.c |  2 +-
 drivers/scsi/cxgbi/libcxgbi.c|  6 +++---
 drivers/scsi/libiscsi.c  | 20 ++--
 drivers/scsi/libiscsi_tcp.c  |  2 +-
 include/scsi/libiscsi.h  |  9 +
 6 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 5521469ce678..e16327a4b4c9 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1977,7 +1977,7 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn 
*bnx2i_conn)
if (nopin->cq_req_sn != qp->cqe_exp_seq_sn)
break;
 
-   if (unlikely(test_bit(ISCSI_SUSPEND_BIT, >suspend_rx))) {
+   if (unlikely(test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, 
>flags))) {
if (nopin->op_code == ISCSI_OP_NOOP_IN &&
nopin->itt == (u16) RESERVED_ITT) {
printk(KERN_ALERT "bnx2i: Unsolicited "
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 1b5f3e143f07..2e5241d12dc3 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1721,7 +1721,7 @@ static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
struct iscsi_conn *conn = ep->conn->cls_conn->dd_data;
 
/* Must suspend all rx queue activity for this ep */
-   set_bit(ISCSI_SUSPEND_BIT, >suspend_rx);
+   set_bit(ISCSI_CONN_FLAG_SUSPEND_RX, >flags);
}
/* CONN_DISCONNECT timeout may or may not be an issue depending
 * on what transcribed in TCP layer, different targets behave
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index 8c7d4dda4cf2..4365d52c6430 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -1634,11 +1634,11 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
log_debug(1 << CXGBI_DBG_PDU_RX,
"csk 0x%p, conn 0x%p.\n", csk, conn);
 
-   if (unlikely(!conn || conn->suspend_rx)) {
+   if (unlikely(!conn || test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, 
>flags))) {
log_debug(1 << CXGBI_DBG_PDU_RX,
-   "csk 0x%p, conn 0x%p, id %d, suspend_rx %lu!\n",
+   "csk 0x%p, conn 0x%p, id %d, conn flags 0x%lx!\n",
csk, conn, conn ? conn->id : 0xFF,
-   conn ? conn->suspend_rx : 0xFF);
+   conn ? conn->flags : 0xFF);
return;
}
 
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index cbc263ec9d66..a4f26431b033 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1392,8 +1392,8 @@ static bool iscsi_set_conn_failed(struct iscsi_conn *conn)
if (conn->stop_stage == 0)
session->state = ISCSI_STATE_FAILED;
 
-   set_bit(ISCSI_SUSPEND_BIT, >suspend_tx);
-   set_bit(ISCSI_SUSPEND_BIT, >suspend_rx);
+   set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, >flags);
+   set_bit(ISCSI_CONN_FLAG_SUSPEND_RX, >flags);
return true;
 }
 
@@ -1454,7 +1454,7 @@ static int iscsi_xmit_task(struct iscsi_conn *conn, 
struct iscsi_task *task,
 * Do this after dropping the extra ref because if this was a requeue
 * it's removed from that list and cleanup_queued_task would miss it.
 */
-   if (test_bit(ISCSI_SUSPEND_BIT, >suspend_tx)) {
+   if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, >flags)) {
/*
 * Save the task and ref in case we weren't cleaning up this
 * task and get woken up again.
@@ -1532,7 +1532,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
int rc = 0;
 
spin_lock_bh(>session->frwd_lock);
-   if (test_bit(ISCSI_SUSPEND_BIT, >suspend_tx)) {
+   if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, >flags)) {
ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n");
spin_unlock_bh(>session->frwd_lock);
return -ENODATA;
@@ -1746,7 +1746,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct 
scsi_cmnd *sc)
goto fault;
}
 
-   if (test_bit(ISCSI_SUSPEND_BIT, >suspend_tx)) {
+   if (test_bit(ISCSI_CONN_FLAG_SUSPE

[PATCH AUTOSEL 5.15 21/27] scsi: iscsi: Fix NOP handling during conn recovery

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit 44ac97109e42f87b1a34954704b81b6c8eca80c4 ]

If a offload driver doesn't use the xmit workqueue, then when we are doing
ep_disconnect libiscsi can still inject PDUs to the driver. This adds a
check for if the connection is bound before trying to inject PDUs.

Link: 
https://lore.kernel.org/r/20220408001314.5014-9-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 7 ++-
 include/scsi/libiscsi.h | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index a4f26431b033..0f2c7098f9d6 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -678,7 +678,8 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
struct iscsi_task *task;
itt_t itt;
 
-   if (session->state == ISCSI_STATE_TERMINATE)
+   if (session->state == ISCSI_STATE_TERMINATE ||
+   !test_bit(ISCSI_CONN_FLAG_BOUND, >flags))
return NULL;
 
if (opcode == ISCSI_OP_LOGIN || opcode == ISCSI_OP_TEXT) {
@@ -2214,6 +2215,8 @@ void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, 
bool is_active)
iscsi_suspend_tx(conn);
 
spin_lock_bh(>frwd_lock);
+   clear_bit(ISCSI_CONN_FLAG_BOUND, >flags);
+
if (!is_active) {
/*
 * if logout timed out before userspace could even send a PDU
@@ -3312,6 +3315,8 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
spin_lock_bh(>frwd_lock);
if (is_leading)
session->leadconn = conn;
+
+   set_bit(ISCSI_CONN_FLAG_BOUND, >flags);
spin_unlock_bh(>frwd_lock);
 
/*
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index bdb0ae11682d..d1e282f0d6f1 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -55,7 +55,7 @@ enum {
 /* Connection flags */
 #define ISCSI_CONN_FLAG_SUSPEND_TX BIT(0)
 #define ISCSI_CONN_FLAG_SUSPEND_RX BIT(1)
-
+#define ISCSI_CONN_FLAG_BOUND  BIT(2)
 
 #define ISCSI_ITT_MASK 0x1fff
 #define ISCSI_TOTAL_CMDS_MAX   4096
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220419181242.485308-21-sashal%40kernel.org.


[PATCH AUTOSEL 5.15 19/27] scsi: iscsi: Release endpoint ID when its freed

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit 3c6ae371b8a1ffba1fc415989fd581ebf841ed0a ]

We can't release the endpoint ID until all references to the endpoint have
been dropped or it could be allocated while in use. This has us use an idr
instead of looping over all conns to find a free ID and then free the ID
when all references have been dropped instead of when the device is only
deleted.

Link: 
https://lore.kernel.org/r/20220408001314.5014-4-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Reviewed-by: Wu Bo 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 71 ++---
 include/scsi/scsi_transport_iscsi.h |  2 +-
 2 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 03cda2da80ef..e5f5ec631b55 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -86,6 +86,9 @@ struct iscsi_internal {
struct transport_container session_cont;
 };
 
+static DEFINE_IDR(iscsi_ep_idr);
+static DEFINE_MUTEX(iscsi_ep_idr_mutex);
+
 static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
 static struct workqueue_struct *iscsi_eh_timer_workq;
 
@@ -169,6 +172,11 @@ struct device_attribute dev_attr_##_prefix##_##_name = 
\
 static void iscsi_endpoint_release(struct device *dev)
 {
struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
+
+   mutex_lock(_ep_idr_mutex);
+   idr_remove(_ep_idr, ep->id);
+   mutex_unlock(_ep_idr_mutex);
+
kfree(ep);
 }
 
@@ -181,7 +189,7 @@ static ssize_t
 show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf)
 {
struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
-   return sysfs_emit(buf, "%llu\n", (unsigned long long) ep->id);
+   return sysfs_emit(buf, "%d\n", ep->id);
 }
 static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL);
 
@@ -194,48 +202,32 @@ static struct attribute_group iscsi_endpoint_group = {
.attrs = iscsi_endpoint_attrs,
 };
 
-#define ISCSI_MAX_EPID -1
-
-static int iscsi_match_epid(struct device *dev, const void *data)
-{
-   struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
-   const uint64_t *epid = data;
-
-   return *epid == ep->id;
-}
-
 struct iscsi_endpoint *
 iscsi_create_endpoint(int dd_size)
 {
-   struct device *dev;
struct iscsi_endpoint *ep;
-   uint64_t id;
-   int err;
-
-   for (id = 1; id < ISCSI_MAX_EPID; id++) {
-   dev = class_find_device(_endpoint_class, NULL, ,
-   iscsi_match_epid);
-   if (!dev)
-   break;
-   else
-   put_device(dev);
-   }
-   if (id == ISCSI_MAX_EPID) {
-   printk(KERN_ERR "Too many connections. Max supported %u\n",
-  ISCSI_MAX_EPID - 1);
-   return NULL;
-   }
+   int err, id;
 
ep = kzalloc(sizeof(*ep) + dd_size, GFP_KERNEL);
if (!ep)
return NULL;
 
+   mutex_lock(_ep_idr_mutex);
+   id = idr_alloc(_ep_idr, ep, 0, -1, GFP_NOIO);
+   if (id < 0) {
+   mutex_unlock(_ep_idr_mutex);
+   printk(KERN_ERR "Could not allocate endpoint ID. Error %d.\n",
+  id);
+   goto free_ep;
+   }
+   mutex_unlock(_ep_idr_mutex);
+
ep->id = id;
ep->dev.class = _endpoint_class;
-   dev_set_name(>dev, "ep-%llu", (unsigned long long) id);
+   dev_set_name(>dev, "ep-%d", id);
err = device_register(>dev);
 if (err)
-goto free_ep;
+   goto free_id;
 
err = sysfs_create_group(>dev.kobj, _endpoint_group);
if (err)
@@ -249,6 +241,10 @@ iscsi_create_endpoint(int dd_size)
device_unregister(>dev);
return NULL;
 
+free_id:
+   mutex_lock(_ep_idr_mutex);
+   idr_remove(_ep_idr, id);
+   mutex_unlock(_ep_idr_mutex);
 free_ep:
kfree(ep);
return NULL;
@@ -276,14 +272,17 @@ EXPORT_SYMBOL_GPL(iscsi_put_endpoint);
  */
 struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
 {
-   struct device *dev;
+   struct iscsi_endpoint *ep;
 
-   dev = class_find_device(_endpoint_class, NULL, ,
-   iscsi_match_epid);
-   if (!dev)
-   return NULL;
+   mutex_lock(_ep_idr_mutex);
+   ep = idr_find(_ep_idr, handle);
+   if (!ep)
+   goto unlock;
 
-   return iscsi_dev_to_endpoint(dev);
+   get_device(>dev);
+unlock:
+   mutex_unlock(_ep_idr_mutex);
+   return ep;
 }
 EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
 
diff --git a/include/scsi

[PATCH AUTOSEL 5.15 17/27] scsi: iscsi: Move iscsi_ep_disconnect()

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit c34f95e98d8fb750eefd4f3fe58b4f8b5e89253b ]

This patch moves iscsi_ep_disconnect() so it can be called earlier in the
next patch.

Link: 
https://lore.kernel.org/r/20220408001314.5014-2-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 38 ++---
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 554b6f784223..126f6f23bffa 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2236,6 +2236,25 @@ static void iscsi_stop_conn(struct iscsi_cls_conn *conn, 
int flag)
ISCSI_DBG_TRANS_CONN(conn, "Stopping conn done.\n");
 }
 
+static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
+{
+   struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
+   struct iscsi_endpoint *ep;
+
+   ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n");
+   conn->state = ISCSI_CONN_FAILED;
+
+   if (!conn->ep || !session->transport->ep_disconnect)
+   return;
+
+   ep = conn->ep;
+   conn->ep = NULL;
+
+   session->transport->unbind_conn(conn, is_active);
+   session->transport->ep_disconnect(ep);
+   ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
+}
+
 static int iscsi_if_stop_conn(struct iscsi_transport *transport,
  struct iscsi_uevent *ev)
 {
@@ -2276,25 +2295,6 @@ static int iscsi_if_stop_conn(struct iscsi_transport 
*transport,
return 0;
 }
 
-static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
-{
-   struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
-   struct iscsi_endpoint *ep;
-
-   ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n");
-   conn->state = ISCSI_CONN_FAILED;
-
-   if (!conn->ep || !session->transport->ep_disconnect)
-   return;
-
-   ep = conn->ep;
-   conn->ep = NULL;
-
-   session->transport->unbind_conn(conn, is_active);
-   session->transport->ep_disconnect(ep);
-   ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
-}
-
 static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
 {
struct iscsi_cls_conn *conn = container_of(work, struct iscsi_cls_conn,
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220419181242.485308-17-sashal%40kernel.org.


[PATCH AUTOSEL 5.15 18/27] scsi: iscsi: Fix offload conn cleanup when iscsid restarts

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit cbd2283aaf47fef4ded4b29124b1ef3beb515f3a ]

When userspace restarts during boot or upgrades it won't know about the
offload driver's endpoint and connection mappings. iscsid will start by
cleaning up the old session by doing a stop_conn call. Later, if we are
able to create a new connection, we clean up the old endpoint during the
binding stage. The problem is that if we do stop_conn before doing the
ep_disconnect call offload, drivers can still be executing I/O. We then
might free tasks from the under the card/driver.

This moves the ep_disconnect call to before we do the stop_conn call for
this case. It will then work and look like a normal recovery/cleanup
procedure from the driver's point of view.

Link: 
https://lore.kernel.org/r/20220408001314.5014-3-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 48 +
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 126f6f23bffa..03cda2da80ef 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2255,6 +2255,23 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn 
*conn, bool is_active)
ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
 }
 
+static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
+struct iscsi_endpoint *ep,
+bool is_active)
+{
+   /* Check if this was a conn error and the kernel took ownership */
+   if (!test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, >flags)) {
+   iscsi_ep_disconnect(conn, is_active);
+   } else {
+   ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
+   mutex_unlock(>ep_mutex);
+
+   flush_work(>cleanup_work);
+
+   mutex_lock(>ep_mutex);
+   }
+}
+
 static int iscsi_if_stop_conn(struct iscsi_transport *transport,
  struct iscsi_uevent *ev)
 {
@@ -2275,6 +2292,16 @@ static int iscsi_if_stop_conn(struct iscsi_transport 
*transport,
cancel_work_sync(>cleanup_work);
iscsi_stop_conn(conn, flag);
} else {
+   /*
+* For offload, when iscsid is restarted it won't know about
+* existing endpoints so it can't do a ep_disconnect. We clean
+* it up here for userspace.
+*/
+   mutex_lock(>ep_mutex);
+   if (conn->ep)
+   iscsi_if_disconnect_bound_ep(conn, conn->ep, true);
+   mutex_unlock(>ep_mutex);
+
/*
 * Figure out if it was the kernel or userspace initiating this.
 */
@@ -3003,16 +3030,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport 
*transport,
}
 
mutex_lock(>ep_mutex);
-   /* Check if this was a conn error and the kernel took ownership */
-   if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, >flags)) {
-   ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
-   mutex_unlock(>ep_mutex);
-
-   flush_work(>cleanup_work);
-   goto put_ep;
-   }
-
-   iscsi_ep_disconnect(conn, false);
+   iscsi_if_disconnect_bound_ep(conn, ep, false);
mutex_unlock(>ep_mutex);
 put_ep:
iscsi_put_endpoint(ep);
@@ -3723,16 +3741,6 @@ static int iscsi_if_transport_conn(struct 
iscsi_transport *transport,
 
switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_BIND_CONN:
-   if (conn->ep) {
-   /*
-* For offload boot support where iscsid is restarted
-* during the pivot root stage, the ep will be intact
-* here when the new iscsid instance starts up and
-* reconnects.
-*/
-   iscsi_ep_disconnect(conn, true);
-   }
-
session = iscsi_session_lookup(ev->u.b_conn.sid);
if (!session) {
err = -EINVAL;
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220419181242.485308-18-sashal%40kernel.org.


[PATCH AUTOSEL 5.17 25/34] scsi: iscsi: Merge suspend fields

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit 5bd856256f8c03e329f8ff36d8c8efcb111fe6df ]

Move the tx and rx suspend fields into one flags field.

Link: 
https://lore.kernel.org/r/20220408001314.5014-8-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/bnx2i/bnx2i_hwi.c   |  2 +-
 drivers/scsi/bnx2i/bnx2i_iscsi.c |  2 +-
 drivers/scsi/cxgbi/libcxgbi.c|  6 +++---
 drivers/scsi/libiscsi.c  | 20 ++--
 drivers/scsi/libiscsi_tcp.c  |  2 +-
 include/scsi/libiscsi.h  |  9 +
 6 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 5521469ce678..e16327a4b4c9 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1977,7 +1977,7 @@ static int bnx2i_process_new_cqes(struct bnx2i_conn 
*bnx2i_conn)
if (nopin->cq_req_sn != qp->cqe_exp_seq_sn)
break;
 
-   if (unlikely(test_bit(ISCSI_SUSPEND_BIT, >suspend_rx))) {
+   if (unlikely(test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, 
>flags))) {
if (nopin->op_code == ISCSI_OP_NOOP_IN &&
nopin->itt == (u16) RESERVED_ITT) {
printk(KERN_ALERT "bnx2i: Unsolicited "
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index e21b053b4f3e..a592ca8602f9 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1721,7 +1721,7 @@ static int bnx2i_tear_down_conn(struct bnx2i_hba *hba,
struct iscsi_conn *conn = ep->conn->cls_conn->dd_data;
 
/* Must suspend all rx queue activity for this ep */
-   set_bit(ISCSI_SUSPEND_BIT, >suspend_rx);
+   set_bit(ISCSI_CONN_FLAG_SUSPEND_RX, >flags);
}
/* CONN_DISCONNECT timeout may or may not be an issue depending
 * on what transcribed in TCP layer, different targets behave
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index 8c7d4dda4cf2..4365d52c6430 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -1634,11 +1634,11 @@ void cxgbi_conn_pdu_ready(struct cxgbi_sock *csk)
log_debug(1 << CXGBI_DBG_PDU_RX,
"csk 0x%p, conn 0x%p.\n", csk, conn);
 
-   if (unlikely(!conn || conn->suspend_rx)) {
+   if (unlikely(!conn || test_bit(ISCSI_CONN_FLAG_SUSPEND_RX, 
>flags))) {
log_debug(1 << CXGBI_DBG_PDU_RX,
-   "csk 0x%p, conn 0x%p, id %d, suspend_rx %lu!\n",
+   "csk 0x%p, conn 0x%p, id %d, conn flags 0x%lx!\n",
csk, conn, conn ? conn->id : 0xFF,
-   conn ? conn->suspend_rx : 0xFF);
+   conn ? conn->flags : 0xFF);
return;
}
 
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 059dae8909ee..073c4db79094 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1392,8 +1392,8 @@ static bool iscsi_set_conn_failed(struct iscsi_conn *conn)
if (conn->stop_stage == 0)
session->state = ISCSI_STATE_FAILED;
 
-   set_bit(ISCSI_SUSPEND_BIT, >suspend_tx);
-   set_bit(ISCSI_SUSPEND_BIT, >suspend_rx);
+   set_bit(ISCSI_CONN_FLAG_SUSPEND_TX, >flags);
+   set_bit(ISCSI_CONN_FLAG_SUSPEND_RX, >flags);
return true;
 }
 
@@ -1454,7 +1454,7 @@ static int iscsi_xmit_task(struct iscsi_conn *conn, 
struct iscsi_task *task,
 * Do this after dropping the extra ref because if this was a requeue
 * it's removed from that list and cleanup_queued_task would miss it.
 */
-   if (test_bit(ISCSI_SUSPEND_BIT, >suspend_tx)) {
+   if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, >flags)) {
/*
 * Save the task and ref in case we weren't cleaning up this
 * task and get woken up again.
@@ -1532,7 +1532,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
int rc = 0;
 
spin_lock_bh(>session->frwd_lock);
-   if (test_bit(ISCSI_SUSPEND_BIT, >suspend_tx)) {
+   if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, >flags)) {
ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n");
spin_unlock_bh(>session->frwd_lock);
return -ENODATA;
@@ -1746,7 +1746,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct 
scsi_cmnd *sc)
goto fault;
}
 
-   if (test_bit(ISCSI_SUSPEND_BIT, >suspend_tx)) {
+   if (test_bit(ISCSI_CONN_FLAG_SUSPE

[PATCH AUTOSEL 5.17 26/34] scsi: iscsi: Fix NOP handling during conn recovery

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit 44ac97109e42f87b1a34954704b81b6c8eca80c4 ]

If a offload driver doesn't use the xmit workqueue, then when we are doing
ep_disconnect libiscsi can still inject PDUs to the driver. This adds a
check for if the connection is bound before trying to inject PDUs.

Link: 
https://lore.kernel.org/r/20220408001314.5014-9-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 7 ++-
 include/scsi/libiscsi.h | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 073c4db79094..f228d991038a 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -678,7 +678,8 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
struct iscsi_task *task;
itt_t itt;
 
-   if (session->state == ISCSI_STATE_TERMINATE)
+   if (session->state == ISCSI_STATE_TERMINATE ||
+   !test_bit(ISCSI_CONN_FLAG_BOUND, >flags))
return NULL;
 
if (opcode == ISCSI_OP_LOGIN || opcode == ISCSI_OP_TEXT) {
@@ -2214,6 +2215,8 @@ void iscsi_conn_unbind(struct iscsi_cls_conn *cls_conn, 
bool is_active)
iscsi_suspend_tx(conn);
 
spin_lock_bh(>frwd_lock);
+   clear_bit(ISCSI_CONN_FLAG_BOUND, >flags);
+
if (!is_active) {
/*
 * if logout timed out before userspace could even send a PDU
@@ -3311,6 +3314,8 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
spin_lock_bh(>frwd_lock);
if (is_leading)
session->leadconn = conn;
+
+   set_bit(ISCSI_CONN_FLAG_BOUND, >flags);
spin_unlock_bh(>frwd_lock);
 
/*
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index bdb0ae11682d..d1e282f0d6f1 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -55,7 +55,7 @@ enum {
 /* Connection flags */
 #define ISCSI_CONN_FLAG_SUSPEND_TX BIT(0)
 #define ISCSI_CONN_FLAG_SUSPEND_RX BIT(1)
-
+#define ISCSI_CONN_FLAG_BOUND  BIT(2)
 
 #define ISCSI_ITT_MASK 0x1fff
 #define ISCSI_TOTAL_CMDS_MAX   4096
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220419181104.484667-26-sashal%40kernel.org.


[PATCH AUTOSEL 5.17 23/34] scsi: iscsi: Fix offload conn cleanup when iscsid restarts

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit cbd2283aaf47fef4ded4b29124b1ef3beb515f3a ]

When userspace restarts during boot or upgrades it won't know about the
offload driver's endpoint and connection mappings. iscsid will start by
cleaning up the old session by doing a stop_conn call. Later, if we are
able to create a new connection, we clean up the old endpoint during the
binding stage. The problem is that if we do stop_conn before doing the
ep_disconnect call offload, drivers can still be executing I/O. We then
might free tasks from the under the card/driver.

This moves the ep_disconnect call to before we do the stop_conn call for
this case. It will then work and look like a normal recovery/cleanup
procedure from the driver's point of view.

Link: 
https://lore.kernel.org/r/20220408001314.5014-3-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 48 +
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 126f6f23bffa..03cda2da80ef 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2255,6 +2255,23 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn 
*conn, bool is_active)
ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
 }
 
+static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
+struct iscsi_endpoint *ep,
+bool is_active)
+{
+   /* Check if this was a conn error and the kernel took ownership */
+   if (!test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, >flags)) {
+   iscsi_ep_disconnect(conn, is_active);
+   } else {
+   ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
+   mutex_unlock(>ep_mutex);
+
+   flush_work(>cleanup_work);
+
+   mutex_lock(>ep_mutex);
+   }
+}
+
 static int iscsi_if_stop_conn(struct iscsi_transport *transport,
  struct iscsi_uevent *ev)
 {
@@ -2275,6 +2292,16 @@ static int iscsi_if_stop_conn(struct iscsi_transport 
*transport,
cancel_work_sync(>cleanup_work);
iscsi_stop_conn(conn, flag);
} else {
+   /*
+* For offload, when iscsid is restarted it won't know about
+* existing endpoints so it can't do a ep_disconnect. We clean
+* it up here for userspace.
+*/
+   mutex_lock(>ep_mutex);
+   if (conn->ep)
+   iscsi_if_disconnect_bound_ep(conn, conn->ep, true);
+   mutex_unlock(>ep_mutex);
+
/*
 * Figure out if it was the kernel or userspace initiating this.
 */
@@ -3003,16 +3030,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport 
*transport,
}
 
mutex_lock(>ep_mutex);
-   /* Check if this was a conn error and the kernel took ownership */
-   if (test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, >flags)) {
-   ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
-   mutex_unlock(>ep_mutex);
-
-   flush_work(>cleanup_work);
-   goto put_ep;
-   }
-
-   iscsi_ep_disconnect(conn, false);
+   iscsi_if_disconnect_bound_ep(conn, ep, false);
mutex_unlock(>ep_mutex);
 put_ep:
iscsi_put_endpoint(ep);
@@ -3723,16 +3741,6 @@ static int iscsi_if_transport_conn(struct 
iscsi_transport *transport,
 
switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_BIND_CONN:
-   if (conn->ep) {
-   /*
-* For offload boot support where iscsid is restarted
-* during the pivot root stage, the ep will be intact
-* here when the new iscsid instance starts up and
-* reconnects.
-*/
-   iscsi_ep_disconnect(conn, true);
-   }
-
session = iscsi_session_lookup(ev->u.b_conn.sid);
if (!session) {
err = -EINVAL;
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220419181104.484667-23-sashal%40kernel.org.


[PATCH AUTOSEL 5.17 24/34] scsi: iscsi: Release endpoint ID when its freed

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit 3c6ae371b8a1ffba1fc415989fd581ebf841ed0a ]

We can't release the endpoint ID until all references to the endpoint have
been dropped or it could be allocated while in use. This has us use an idr
instead of looping over all conns to find a free ID and then free the ID
when all references have been dropped instead of when the device is only
deleted.

Link: 
https://lore.kernel.org/r/20220408001314.5014-4-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Reviewed-by: Wu Bo 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 71 ++---
 include/scsi/scsi_transport_iscsi.h |  2 +-
 2 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 03cda2da80ef..e5f5ec631b55 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -86,6 +86,9 @@ struct iscsi_internal {
struct transport_container session_cont;
 };
 
+static DEFINE_IDR(iscsi_ep_idr);
+static DEFINE_MUTEX(iscsi_ep_idr_mutex);
+
 static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
 static struct workqueue_struct *iscsi_eh_timer_workq;
 
@@ -169,6 +172,11 @@ struct device_attribute dev_attr_##_prefix##_##_name = 
\
 static void iscsi_endpoint_release(struct device *dev)
 {
struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
+
+   mutex_lock(_ep_idr_mutex);
+   idr_remove(_ep_idr, ep->id);
+   mutex_unlock(_ep_idr_mutex);
+
kfree(ep);
 }
 
@@ -181,7 +189,7 @@ static ssize_t
 show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf)
 {
struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
-   return sysfs_emit(buf, "%llu\n", (unsigned long long) ep->id);
+   return sysfs_emit(buf, "%d\n", ep->id);
 }
 static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL);
 
@@ -194,48 +202,32 @@ static struct attribute_group iscsi_endpoint_group = {
.attrs = iscsi_endpoint_attrs,
 };
 
-#define ISCSI_MAX_EPID -1
-
-static int iscsi_match_epid(struct device *dev, const void *data)
-{
-   struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
-   const uint64_t *epid = data;
-
-   return *epid == ep->id;
-}
-
 struct iscsi_endpoint *
 iscsi_create_endpoint(int dd_size)
 {
-   struct device *dev;
struct iscsi_endpoint *ep;
-   uint64_t id;
-   int err;
-
-   for (id = 1; id < ISCSI_MAX_EPID; id++) {
-   dev = class_find_device(_endpoint_class, NULL, ,
-   iscsi_match_epid);
-   if (!dev)
-   break;
-   else
-   put_device(dev);
-   }
-   if (id == ISCSI_MAX_EPID) {
-   printk(KERN_ERR "Too many connections. Max supported %u\n",
-  ISCSI_MAX_EPID - 1);
-   return NULL;
-   }
+   int err, id;
 
ep = kzalloc(sizeof(*ep) + dd_size, GFP_KERNEL);
if (!ep)
return NULL;
 
+   mutex_lock(_ep_idr_mutex);
+   id = idr_alloc(_ep_idr, ep, 0, -1, GFP_NOIO);
+   if (id < 0) {
+   mutex_unlock(_ep_idr_mutex);
+   printk(KERN_ERR "Could not allocate endpoint ID. Error %d.\n",
+  id);
+   goto free_ep;
+   }
+   mutex_unlock(_ep_idr_mutex);
+
ep->id = id;
ep->dev.class = _endpoint_class;
-   dev_set_name(>dev, "ep-%llu", (unsigned long long) id);
+   dev_set_name(>dev, "ep-%d", id);
err = device_register(>dev);
 if (err)
-goto free_ep;
+   goto free_id;
 
err = sysfs_create_group(>dev.kobj, _endpoint_group);
if (err)
@@ -249,6 +241,10 @@ iscsi_create_endpoint(int dd_size)
device_unregister(>dev);
return NULL;
 
+free_id:
+   mutex_lock(_ep_idr_mutex);
+   idr_remove(_ep_idr, id);
+   mutex_unlock(_ep_idr_mutex);
 free_ep:
kfree(ep);
return NULL;
@@ -276,14 +272,17 @@ EXPORT_SYMBOL_GPL(iscsi_put_endpoint);
  */
 struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
 {
-   struct device *dev;
+   struct iscsi_endpoint *ep;
 
-   dev = class_find_device(_endpoint_class, NULL, ,
-   iscsi_match_epid);
-   if (!dev)
-   return NULL;
+   mutex_lock(_ep_idr_mutex);
+   ep = idr_find(_ep_idr, handle);
+   if (!ep)
+   goto unlock;
 
-   return iscsi_dev_to_endpoint(dev);
+   get_device(>dev);
+unlock:
+   mutex_unlock(_ep_idr_mutex);
+   return ep;
 }
 EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
 
diff --git a/include/scsi

[PATCH AUTOSEL 5.17 22/34] scsi: iscsi: Move iscsi_ep_disconnect()

2022-04-19 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit c34f95e98d8fb750eefd4f3fe58b4f8b5e89253b ]

This patch moves iscsi_ep_disconnect() so it can be called earlier in the
next patch.

Link: 
https://lore.kernel.org/r/20220408001314.5014-2-michael.chris...@oracle.com
Tested-by: Manish Rangankar 
Reviewed-by: Lee Duncan 
Reviewed-by: Chris Leech 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 38 ++---
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 554b6f784223..126f6f23bffa 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2236,6 +2236,25 @@ static void iscsi_stop_conn(struct iscsi_cls_conn *conn, 
int flag)
ISCSI_DBG_TRANS_CONN(conn, "Stopping conn done.\n");
 }
 
+static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
+{
+   struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
+   struct iscsi_endpoint *ep;
+
+   ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n");
+   conn->state = ISCSI_CONN_FAILED;
+
+   if (!conn->ep || !session->transport->ep_disconnect)
+   return;
+
+   ep = conn->ep;
+   conn->ep = NULL;
+
+   session->transport->unbind_conn(conn, is_active);
+   session->transport->ep_disconnect(ep);
+   ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
+}
+
 static int iscsi_if_stop_conn(struct iscsi_transport *transport,
  struct iscsi_uevent *ev)
 {
@@ -2276,25 +2295,6 @@ static int iscsi_if_stop_conn(struct iscsi_transport 
*transport,
return 0;
 }
 
-static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
-{
-   struct iscsi_cls_session *session = iscsi_conn_to_session(conn);
-   struct iscsi_endpoint *ep;
-
-   ISCSI_DBG_TRANS_CONN(conn, "disconnect ep.\n");
-   conn->state = ISCSI_CONN_FAILED;
-
-   if (!conn->ep || !session->transport->ep_disconnect)
-   return;
-
-   ep = conn->ep;
-   conn->ep = NULL;
-
-   session->transport->unbind_conn(conn, is_active);
-   session->transport->ep_disconnect(ep);
-   ISCSI_DBG_TRANS_CONN(conn, "disconnect ep done.\n");
-}
-
 static void iscsi_cleanup_conn_work_fn(struct work_struct *work)
 {
struct iscsi_cls_conn *conn = container_of(work, struct iscsi_cls_conn,
-- 
2.35.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220419181104.484667-22-sashal%40kernel.org.


[PATCH AUTOSEL 4.4 1/4] scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown()

2022-01-03 Thread Sasha Levin
From: Lixiaokeng 

[ Upstream commit 1b8d0300a3e9f216ae4901bab886db7299899ec6 ]

|- iscsi_if_destroy_conn|-dev_attr_show
 |-iscsi_conn_teardown
  |-spin_lock_bh |-iscsi_sw_tcp_conn_get_param

  |-kfree(conn->persistent_address)   |-iscsi_conn_get_param
  |-kfree(conn->local_ipaddr)
   ==>|-read persistent_address
   ==>|-read local_ipaddr
  |-spin_unlock_bh

When iscsi_conn_teardown() and iscsi_conn_get_param() happen in parallel, a
UAF may be triggered.

Link: https://lore.kernel.org/r/046ec8a0-ce95-d3fc-3235-666a7c65b...@huawei.com
Reported-by: Lu Tixiong 
Reviewed-by: Mike Christie 
Reviewed-by: Lee Duncan 
Signed-off-by: Lixiaokeng 
Signed-off-by: Linfeilong 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 0713d02cf1126..b1ef1aa4dd44b 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2994,6 +2994,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
 {
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
+   char *tmp_persistent_address = conn->persistent_address;
+   char *tmp_local_ipaddr = conn->local_ipaddr;
 
del_timer_sync(>transport_timer);
 
@@ -3015,8 +3017,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
spin_lock_bh(>frwd_lock);
free_pages((unsigned long) conn->data,
   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
-   kfree(conn->persistent_address);
-   kfree(conn->local_ipaddr);
/* regular RX path uses back_lock */
spin_lock_bh(>back_lock);
kfifo_in(>cmdpool.queue, (void*)>login_task,
@@ -3028,6 +3028,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
mutex_unlock(>eh_mutex);
 
iscsi_destroy_conn(cls_conn);
+   kfree(tmp_persistent_address);
+   kfree(tmp_local_ipaddr);
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
 
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220103173105.1613707-1-sashal%40kernel.org.


[PATCH AUTOSEL 4.9 1/4] scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown()

2022-01-03 Thread Sasha Levin
From: Lixiaokeng 

[ Upstream commit 1b8d0300a3e9f216ae4901bab886db7299899ec6 ]

|- iscsi_if_destroy_conn|-dev_attr_show
 |-iscsi_conn_teardown
  |-spin_lock_bh |-iscsi_sw_tcp_conn_get_param

  |-kfree(conn->persistent_address)   |-iscsi_conn_get_param
  |-kfree(conn->local_ipaddr)
   ==>|-read persistent_address
   ==>|-read local_ipaddr
  |-spin_unlock_bh

When iscsi_conn_teardown() and iscsi_conn_get_param() happen in parallel, a
UAF may be triggered.

Link: https://lore.kernel.org/r/046ec8a0-ce95-d3fc-3235-666a7c65b...@huawei.com
Reported-by: Lu Tixiong 
Reviewed-by: Mike Christie 
Reviewed-by: Lee Duncan 
Signed-off-by: Lixiaokeng 
Signed-off-by: Linfeilong 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 30e954bb6c81e..8d1a05d5eb4dd 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2991,6 +2991,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
 {
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
+   char *tmp_persistent_address = conn->persistent_address;
+   char *tmp_local_ipaddr = conn->local_ipaddr;
 
del_timer_sync(>transport_timer);
 
@@ -3012,8 +3014,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
spin_lock_bh(>frwd_lock);
free_pages((unsigned long) conn->data,
   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
-   kfree(conn->persistent_address);
-   kfree(conn->local_ipaddr);
/* regular RX path uses back_lock */
spin_lock_bh(>back_lock);
kfifo_in(>cmdpool.queue, (void*)>login_task,
@@ -3025,6 +3025,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
mutex_unlock(>eh_mutex);
 
iscsi_destroy_conn(cls_conn);
+   kfree(tmp_persistent_address);
+   kfree(tmp_local_ipaddr);
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
 
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220103173047.1613630-1-sashal%40kernel.org.


[PATCH AUTOSEL 4.14 1/4] scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown()

2022-01-03 Thread Sasha Levin
From: Lixiaokeng 

[ Upstream commit 1b8d0300a3e9f216ae4901bab886db7299899ec6 ]

|- iscsi_if_destroy_conn|-dev_attr_show
 |-iscsi_conn_teardown
  |-spin_lock_bh |-iscsi_sw_tcp_conn_get_param

  |-kfree(conn->persistent_address)   |-iscsi_conn_get_param
  |-kfree(conn->local_ipaddr)
   ==>|-read persistent_address
   ==>|-read local_ipaddr
  |-spin_unlock_bh

When iscsi_conn_teardown() and iscsi_conn_get_param() happen in parallel, a
UAF may be triggered.

Link: https://lore.kernel.org/r/046ec8a0-ce95-d3fc-3235-666a7c65b...@huawei.com
Reported-by: Lu Tixiong 
Reviewed-by: Mike Christie 
Reviewed-by: Lee Duncan 
Signed-off-by: Lixiaokeng 
Signed-off-by: Linfeilong 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index f3dfec02abecc..ebf3a277d8bba 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2991,6 +2991,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
 {
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
+   char *tmp_persistent_address = conn->persistent_address;
+   char *tmp_local_ipaddr = conn->local_ipaddr;
 
del_timer_sync(>transport_timer);
 
@@ -3012,8 +3014,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
spin_lock_bh(>frwd_lock);
free_pages((unsigned long) conn->data,
   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
-   kfree(conn->persistent_address);
-   kfree(conn->local_ipaddr);
/* regular RX path uses back_lock */
spin_lock_bh(>back_lock);
kfifo_in(>cmdpool.queue, (void*)>login_task,
@@ -3025,6 +3025,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
mutex_unlock(>eh_mutex);
 
iscsi_destroy_conn(cls_conn);
+   kfree(tmp_persistent_address);
+   kfree(tmp_local_ipaddr);
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
 
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220103173039.1613564-1-sashal%40kernel.org.


[PATCH AUTOSEL 4.19 2/5] scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown()

2022-01-03 Thread Sasha Levin
From: Lixiaokeng 

[ Upstream commit 1b8d0300a3e9f216ae4901bab886db7299899ec6 ]

|- iscsi_if_destroy_conn|-dev_attr_show
 |-iscsi_conn_teardown
  |-spin_lock_bh |-iscsi_sw_tcp_conn_get_param

  |-kfree(conn->persistent_address)   |-iscsi_conn_get_param
  |-kfree(conn->local_ipaddr)
   ==>|-read persistent_address
   ==>|-read local_ipaddr
  |-spin_unlock_bh

When iscsi_conn_teardown() and iscsi_conn_get_param() happen in parallel, a
UAF may be triggered.

Link: https://lore.kernel.org/r/046ec8a0-ce95-d3fc-3235-666a7c65b...@huawei.com
Reported-by: Lu Tixiong 
Reviewed-by: Mike Christie 
Reviewed-by: Lee Duncan 
Signed-off-by: Lixiaokeng 
Signed-off-by: Linfeilong 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 5607fe8541c3a..cb314e3a0fc7a 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2986,6 +2986,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
 {
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
+   char *tmp_persistent_address = conn->persistent_address;
+   char *tmp_local_ipaddr = conn->local_ipaddr;
 
del_timer_sync(>transport_timer);
 
@@ -3007,8 +3009,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
spin_lock_bh(>frwd_lock);
free_pages((unsigned long) conn->data,
   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
-   kfree(conn->persistent_address);
-   kfree(conn->local_ipaddr);
/* regular RX path uses back_lock */
spin_lock_bh(>back_lock);
kfifo_in(>cmdpool.queue, (void*)>login_task,
@@ -3020,6 +3020,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
mutex_unlock(>eh_mutex);
 
iscsi_destroy_conn(cls_conn);
+   kfree(tmp_persistent_address);
+   kfree(tmp_local_ipaddr);
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
 
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220103173029.1613474-2-sashal%40kernel.org.


[PATCH AUTOSEL 5.4 2/6] scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown()

2022-01-03 Thread Sasha Levin
From: Lixiaokeng 

[ Upstream commit 1b8d0300a3e9f216ae4901bab886db7299899ec6 ]

|- iscsi_if_destroy_conn|-dev_attr_show
 |-iscsi_conn_teardown
  |-spin_lock_bh |-iscsi_sw_tcp_conn_get_param

  |-kfree(conn->persistent_address)   |-iscsi_conn_get_param
  |-kfree(conn->local_ipaddr)
   ==>|-read persistent_address
   ==>|-read local_ipaddr
  |-spin_unlock_bh

When iscsi_conn_teardown() and iscsi_conn_get_param() happen in parallel, a
UAF may be triggered.

Link: https://lore.kernel.org/r/046ec8a0-ce95-d3fc-3235-666a7c65b...@huawei.com
Reported-by: Lu Tixiong 
Reviewed-by: Mike Christie 
Reviewed-by: Lee Duncan 
Signed-off-by: Lixiaokeng 
Signed-off-by: Linfeilong 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index eeba6180711cd..f3cee64c6d12f 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2948,6 +2948,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
 {
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
+   char *tmp_persistent_address = conn->persistent_address;
+   char *tmp_local_ipaddr = conn->local_ipaddr;
 
del_timer_sync(>transport_timer);
 
@@ -2969,8 +2971,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
spin_lock_bh(>frwd_lock);
free_pages((unsigned long) conn->data,
   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
-   kfree(conn->persistent_address);
-   kfree(conn->local_ipaddr);
/* regular RX path uses back_lock */
spin_lock_bh(>back_lock);
kfifo_in(>cmdpool.queue, (void*)>login_task,
@@ -2982,6 +2982,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
mutex_unlock(>eh_mutex);
 
iscsi_destroy_conn(cls_conn);
+   kfree(tmp_persistent_address);
+   kfree(tmp_local_ipaddr);
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
 
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220103173018.1613394-2-sashal%40kernel.org.


[PATCH AUTOSEL 5.10 2/8] scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown()

2022-01-03 Thread Sasha Levin
From: Lixiaokeng 

[ Upstream commit 1b8d0300a3e9f216ae4901bab886db7299899ec6 ]

|- iscsi_if_destroy_conn|-dev_attr_show
 |-iscsi_conn_teardown
  |-spin_lock_bh |-iscsi_sw_tcp_conn_get_param

  |-kfree(conn->persistent_address)   |-iscsi_conn_get_param
  |-kfree(conn->local_ipaddr)
   ==>|-read persistent_address
   ==>|-read local_ipaddr
  |-spin_unlock_bh

When iscsi_conn_teardown() and iscsi_conn_get_param() happen in parallel, a
UAF may be triggered.

Link: https://lore.kernel.org/r/046ec8a0-ce95-d3fc-3235-666a7c65b...@huawei.com
Reported-by: Lu Tixiong 
Reviewed-by: Mike Christie 
Reviewed-by: Lee Duncan 
Signed-off-by: Lixiaokeng 
Signed-off-by: Linfeilong 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 30d27b6706746..d4e66c595eb87 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2950,6 +2950,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
 {
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
+   char *tmp_persistent_address = conn->persistent_address;
+   char *tmp_local_ipaddr = conn->local_ipaddr;
 
del_timer_sync(>transport_timer);
 
@@ -2971,8 +2973,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
spin_lock_bh(>frwd_lock);
free_pages((unsigned long) conn->data,
   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
-   kfree(conn->persistent_address);
-   kfree(conn->local_ipaddr);
/* regular RX path uses back_lock */
spin_lock_bh(>back_lock);
kfifo_in(>cmdpool.queue, (void*)>login_task,
@@ -2984,6 +2984,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
mutex_unlock(>eh_mutex);
 
iscsi_destroy_conn(cls_conn);
+   kfree(tmp_persistent_address);
+   kfree(tmp_local_ipaddr);
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
 
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220103173001.1613277-2-sashal%40kernel.org.


[PATCH AUTOSEL 5.15 05/16] scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown()

2022-01-03 Thread Sasha Levin
From: Lixiaokeng 

[ Upstream commit 1b8d0300a3e9f216ae4901bab886db7299899ec6 ]

|- iscsi_if_destroy_conn|-dev_attr_show
 |-iscsi_conn_teardown
  |-spin_lock_bh |-iscsi_sw_tcp_conn_get_param

  |-kfree(conn->persistent_address)   |-iscsi_conn_get_param
  |-kfree(conn->local_ipaddr)
   ==>|-read persistent_address
   ==>|-read local_ipaddr
  |-spin_unlock_bh

When iscsi_conn_teardown() and iscsi_conn_get_param() happen in parallel, a
UAF may be triggered.

Link: https://lore.kernel.org/r/046ec8a0-ce95-d3fc-3235-666a7c65b...@huawei.com
Reported-by: Lu Tixiong 
Reviewed-by: Mike Christie 
Reviewed-by: Lee Duncan 
Signed-off-by: Lixiaokeng 
Signed-off-by: Linfeilong 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 5bc91d34df634..cbc263ec9d661 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -3101,6 +3101,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
 {
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_session *session = conn->session;
+   char *tmp_persistent_address = conn->persistent_address;
+   char *tmp_local_ipaddr = conn->local_ipaddr;
 
del_timer_sync(>transport_timer);
 
@@ -3122,8 +3124,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
spin_lock_bh(>frwd_lock);
free_pages((unsigned long) conn->data,
   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
-   kfree(conn->persistent_address);
-   kfree(conn->local_ipaddr);
/* regular RX path uses back_lock */
spin_lock_bh(>back_lock);
kfifo_in(>cmdpool.queue, (void*)>login_task,
@@ -3135,6 +3135,8 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
mutex_unlock(>eh_mutex);
 
iscsi_destroy_conn(cls_conn);
+   kfree(tmp_persistent_address);
+   kfree(tmp_local_ipaddr);
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
 
-- 
2.34.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20220103172849.1612731-5-sashal%40kernel.org.


[PATCH AUTOSEL 4.4 4/6] scsi: iscsi: Unblock session then wake up error handler

2021-11-25 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit a0c2f8b6709a9a4af175497ca65f93804f57b248 ]

We can race where iscsi_session_recovery_timedout() has woken up the error
handler thread and it's now setting the devices to offline, and
session_recovery_timedout()'s call to scsi_target_unblock() is also trying
to set the device's state to transport-offline. We can then get a mix of
states.

For the case where we can't relogin we want the devices to be in
transport-offline so when we have repaired the connection
__iscsi_unblock_session() can set the state back to running.

Set the device state then call into libiscsi to wake up the error handler.

Link: 
https://lore.kernel.org/r/20211105221048.6541-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 9906a3b562e93..269277c1d9dcc 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1896,12 +1896,12 @@ static void session_recovery_timedout(struct 
work_struct *work)
}
spin_unlock_irqrestore(>lock, flags);
 
-   if (session->transport->session_recovery_timedout)
-   session->transport->session_recovery_timedout(session);
-
ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
scsi_target_unblock(>dev, SDEV_TRANSPORT_OFFLINE);
ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
+
+   if (session->transport->session_recovery_timedout)
+   session->transport->session_recovery_timedout(session);
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
-- 
2.33.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20211126023701.443472-4-sashal%40kernel.org.


[PATCH AUTOSEL 4.9 5/8] scsi: iscsi: Unblock session then wake up error handler

2021-11-25 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit a0c2f8b6709a9a4af175497ca65f93804f57b248 ]

We can race where iscsi_session_recovery_timedout() has woken up the error
handler thread and it's now setting the devices to offline, and
session_recovery_timedout()'s call to scsi_target_unblock() is also trying
to set the device's state to transport-offline. We can then get a mix of
states.

For the case where we can't relogin we want the devices to be in
transport-offline so when we have repaired the connection
__iscsi_unblock_session() can set the state back to running.

Set the device state then call into libiscsi to wake up the error handler.

Link: 
https://lore.kernel.org/r/20211105221048.6541-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index aed17f958448d..acd8eb8c94cf7 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1898,12 +1898,12 @@ static void session_recovery_timedout(struct 
work_struct *work)
}
spin_unlock_irqrestore(>lock, flags);
 
-   if (session->transport->session_recovery_timedout)
-   session->transport->session_recovery_timedout(session);
-
ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
scsi_target_unblock(>dev, SDEV_TRANSPORT_OFFLINE);
ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
+
+   if (session->transport->session_recovery_timedout)
+   session->transport->session_recovery_timedout(session);
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
-- 
2.33.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20211126023640.443271-5-sashal%40kernel.org.


[PATCH AUTOSEL 4.14 08/12] scsi: iscsi: Unblock session then wake up error handler

2021-11-25 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit a0c2f8b6709a9a4af175497ca65f93804f57b248 ]

We can race where iscsi_session_recovery_timedout() has woken up the error
handler thread and it's now setting the devices to offline, and
session_recovery_timedout()'s call to scsi_target_unblock() is also trying
to set the device's state to transport-offline. We can then get a mix of
states.

For the case where we can't relogin we want the devices to be in
transport-offline so when we have repaired the connection
__iscsi_unblock_session() can set the state back to running.

Set the device state then call into libiscsi to wake up the error handler.

Link: 
https://lore.kernel.org/r/20211105221048.6541-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index d276d84c0f7a2..26c6f1b288013 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1892,12 +1892,12 @@ static void session_recovery_timedout(struct 
work_struct *work)
}
spin_unlock_irqrestore(>lock, flags);
 
-   if (session->transport->session_recovery_timedout)
-   session->transport->session_recovery_timedout(session);
-
ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
scsi_target_unblock(>dev, SDEV_TRANSPORT_OFFLINE);
ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
+
+   if (session->transport->session_recovery_timedout)
+   session->transport->session_recovery_timedout(session);
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
-- 
2.33.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20211126023611.443098-8-sashal%40kernel.org.


[PATCH AUTOSEL 4.19 10/15] scsi: iscsi: Unblock session then wake up error handler

2021-11-25 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit a0c2f8b6709a9a4af175497ca65f93804f57b248 ]

We can race where iscsi_session_recovery_timedout() has woken up the error
handler thread and it's now setting the devices to offline, and
session_recovery_timedout()'s call to scsi_target_unblock() is also trying
to set the device's state to transport-offline. We can then get a mix of
states.

For the case where we can't relogin we want the devices to be in
transport-offline so when we have repaired the connection
__iscsi_unblock_session() can set the state back to running.

Set the device state then call into libiscsi to wake up the error handler.

Link: 
https://lore.kernel.org/r/20211105221048.6541-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index c06e648a415b5..79581771e6f61 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1892,12 +1892,12 @@ static void session_recovery_timedout(struct 
work_struct *work)
}
spin_unlock_irqrestore(>lock, flags);
 
-   if (session->transport->session_recovery_timedout)
-   session->transport->session_recovery_timedout(session);
-
ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
scsi_target_unblock(>dev, SDEV_TRANSPORT_OFFLINE);
ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
+
+   if (session->transport->session_recovery_timedout)
+   session->transport->session_recovery_timedout(session);
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
-- 
2.33.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20211126023533.442895-10-sashal%40kernel.org.


[PATCH AUTOSEL 5.4 13/19] scsi: iscsi: Unblock session then wake up error handler

2021-11-25 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit a0c2f8b6709a9a4af175497ca65f93804f57b248 ]

We can race where iscsi_session_recovery_timedout() has woken up the error
handler thread and it's now setting the devices to offline, and
session_recovery_timedout()'s call to scsi_target_unblock() is also trying
to set the device's state to transport-offline. We can then get a mix of
states.

For the case where we can't relogin we want the devices to be in
transport-offline so when we have repaired the connection
__iscsi_unblock_session() can set the state back to running.

Set the device state then call into libiscsi to wake up the error handler.

Link: 
https://lore.kernel.org/r/20211105221048.6541-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 6f21cb75d95fd..f6cce0befa7de 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1894,12 +1894,12 @@ static void session_recovery_timedout(struct 
work_struct *work)
}
spin_unlock_irqrestore(>lock, flags);
 
-   if (session->transport->session_recovery_timedout)
-   session->transport->session_recovery_timedout(session);
-
ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
scsi_target_unblock(>dev, SDEV_TRANSPORT_OFFLINE);
ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
+
+   if (session->transport->session_recovery_timedout)
+   session->transport->session_recovery_timedout(session);
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
-- 
2.33.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20211126023448.442529-13-sashal%40kernel.org.


[PATCH AUTOSEL 5.10 17/28] scsi: iscsi: Unblock session then wake up error handler

2021-11-25 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit a0c2f8b6709a9a4af175497ca65f93804f57b248 ]

We can race where iscsi_session_recovery_timedout() has woken up the error
handler thread and it's now setting the devices to offline, and
session_recovery_timedout()'s call to scsi_target_unblock() is also trying
to set the device's state to transport-offline. We can then get a mix of
states.

For the case where we can't relogin we want the devices to be in
transport-offline so when we have repaired the connection
__iscsi_unblock_session() can set the state back to running.

Set the device state then call into libiscsi to wake up the error handler.

Link: 
https://lore.kernel.org/r/20211105221048.6541-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 3f7fa8de36427..a5759d0e388a8 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1909,12 +1909,12 @@ static void session_recovery_timedout(struct 
work_struct *work)
}
spin_unlock_irqrestore(>lock, flags);
 
-   if (session->transport->session_recovery_timedout)
-   session->transport->session_recovery_timedout(session);
-
ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
scsi_target_unblock(>dev, SDEV_TRANSPORT_OFFLINE);
ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
+
+   if (session->transport->session_recovery_timedout)
+   session->transport->session_recovery_timedout(session);
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
-- 
2.33.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20211126023343.442045-17-sashal%40kernel.org.


[PATCH AUTOSEL 5.15 22/39] scsi: iscsi: Unblock session then wake up error handler

2021-11-25 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit a0c2f8b6709a9a4af175497ca65f93804f57b248 ]

We can race where iscsi_session_recovery_timedout() has woken up the error
handler thread and it's now setting the devices to offline, and
session_recovery_timedout()'s call to scsi_target_unblock() is also trying
to set the device's state to transport-offline. We can then get a mix of
states.

For the case where we can't relogin we want the devices to be in
transport-offline so when we have repaired the connection
__iscsi_unblock_session() can set the state back to running.

Set the device state then call into libiscsi to wake up the error handler.

Link: 
https://lore.kernel.org/r/20211105221048.6541-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 78343d3f93857..554b6f7842236 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1899,12 +1899,12 @@ static void session_recovery_timedout(struct 
work_struct *work)
}
spin_unlock_irqrestore(>lock, flags);
 
-   if (session->transport->session_recovery_timedout)
-   session->transport->session_recovery_timedout(session);
-
ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
scsi_target_unblock(>dev, SDEV_TRANSPORT_OFFLINE);
ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
+
+   if (session->transport->session_recovery_timedout)
+   session->transport->session_recovery_timedout(session);
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
-- 
2.33.0

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20211126023156.441292-22-sashal%40kernel.org.


[PATCH AUTOSEL 4.4 07/23] scsi: iscsi: Add iscsi_cls_conn refcount helpers

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit b1d19e8c92cfb0ded180ef3376c20e130414e067 ]

There are a couple places where we could free the iscsi_cls_conn while it's
still in use. This adds some helpers to get/put a refcount on the struct
and converts an exiting user. Subsequent commits will then use the helpers
to fix 2 bugs in the eh code.

Link: 
https://lore.kernel.org/r/20210525181821.7617-11-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c |  7 ++-
 drivers/scsi/scsi_transport_iscsi.c | 12 
 include/scsi/scsi_transport_iscsi.h |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 18b8d86ef74b..0713d02cf112 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1384,7 +1384,6 @@ void iscsi_session_failure(struct iscsi_session *session,
   enum iscsi_err err)
 {
struct iscsi_conn *conn;
-   struct device *dev;
 
spin_lock_bh(>frwd_lock);
conn = session->leadconn;
@@ -1393,10 +1392,8 @@ void iscsi_session_failure(struct iscsi_session *session,
return;
}
 
-   dev = get_device(>cls_conn->dev);
+   iscsi_get_conn(conn->cls_conn);
spin_unlock_bh(>frwd_lock);
-   if (!dev)
-   return;
/*
 * if the host is being removed bypass the connection
 * recovery initialization because we are going to kill
@@ -1406,7 +1403,7 @@ void iscsi_session_failure(struct iscsi_session *session,
iscsi_conn_error_event(conn->cls_conn, err);
else
iscsi_conn_failure(conn, err);
-   put_device(dev);
+   iscsi_put_conn(conn->cls_conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 42bc4b71b0ba..e0159e6a1065 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2328,6 +2328,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
 }
 EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
 
+void iscsi_put_conn(struct iscsi_cls_conn *conn)
+{
+   put_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_put_conn);
+
+void iscsi_get_conn(struct iscsi_cls_conn *conn)
+{
+   get_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_get_conn);
+
 /*
  * iscsi interface functions
  */
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 6183d20a01fb..e673c7c9c5fb 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -437,6 +437,8 @@ extern void iscsi_free_session(struct iscsi_cls_session 
*session);
 extern int iscsi_destroy_session(struct iscsi_cls_session *session);
 extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid);
+extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
 extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
 extern void iscsi_unblock_session(struct iscsi_cls_session *session);
 extern void iscsi_block_session(struct iscsi_cls_session *session);
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210710023912.3172972-7-sashal%40kernel.org.


[PATCH AUTOSEL 4.9 08/26] scsi: iscsi: Add iscsi_cls_conn refcount helpers

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit b1d19e8c92cfb0ded180ef3376c20e130414e067 ]

There are a couple places where we could free the iscsi_cls_conn while it's
still in use. This adds some helpers to get/put a refcount on the struct
and converts an exiting user. Subsequent commits will then use the helpers
to fix 2 bugs in the eh code.

Link: 
https://lore.kernel.org/r/20210525181821.7617-11-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c |  7 ++-
 drivers/scsi/scsi_transport_iscsi.c | 12 
 include/scsi/scsi_transport_iscsi.h |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 50e2943c3337..30e954bb6c81 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1384,7 +1384,6 @@ void iscsi_session_failure(struct iscsi_session *session,
   enum iscsi_err err)
 {
struct iscsi_conn *conn;
-   struct device *dev;
 
spin_lock_bh(>frwd_lock);
conn = session->leadconn;
@@ -1393,10 +1392,8 @@ void iscsi_session_failure(struct iscsi_session *session,
return;
}
 
-   dev = get_device(>cls_conn->dev);
+   iscsi_get_conn(conn->cls_conn);
spin_unlock_bh(>frwd_lock);
-   if (!dev)
-   return;
/*
 * if the host is being removed bypass the connection
 * recovery initialization because we are going to kill
@@ -1406,7 +1403,7 @@ void iscsi_session_failure(struct iscsi_session *session,
iscsi_conn_error_event(conn->cls_conn, err);
else
iscsi_conn_failure(conn, err);
-   put_device(dev);
+   iscsi_put_conn(conn->cls_conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 4f4d2d65a4a7..337aad0660fa 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2327,6 +2327,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
 }
 EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
 
+void iscsi_put_conn(struct iscsi_cls_conn *conn)
+{
+   put_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_put_conn);
+
+void iscsi_get_conn(struct iscsi_cls_conn *conn)
+{
+   get_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_get_conn);
+
 /*
  * iscsi interface functions
  */
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 6183d20a01fb..e673c7c9c5fb 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -437,6 +437,8 @@ extern void iscsi_free_session(struct iscsi_cls_session 
*session);
 extern int iscsi_destroy_session(struct iscsi_cls_session *session);
 extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid);
+extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
 extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
 extern void iscsi_unblock_session(struct iscsi_cls_session *session);
 extern void iscsi_block_session(struct iscsi_cls_session *session);
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210710023604.3172486-8-sashal%40kernel.org.


[PATCH AUTOSEL 4.14 11/33] scsi: iscsi: Add iscsi_cls_conn refcount helpers

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit b1d19e8c92cfb0ded180ef3376c20e130414e067 ]

There are a couple places where we could free the iscsi_cls_conn while it's
still in use. This adds some helpers to get/put a refcount on the struct
and converts an exiting user. Subsequent commits will then use the helpers
to fix 2 bugs in the eh code.

Link: 
https://lore.kernel.org/r/20210525181821.7617-11-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c |  7 ++-
 drivers/scsi/scsi_transport_iscsi.c | 12 
 include/scsi/scsi_transport_iscsi.h |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 21efe27ebfcc..f3dfec02abec 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1385,7 +1385,6 @@ void iscsi_session_failure(struct iscsi_session *session,
   enum iscsi_err err)
 {
struct iscsi_conn *conn;
-   struct device *dev;
 
spin_lock_bh(>frwd_lock);
conn = session->leadconn;
@@ -1394,10 +1393,8 @@ void iscsi_session_failure(struct iscsi_session *session,
return;
}
 
-   dev = get_device(>cls_conn->dev);
+   iscsi_get_conn(conn->cls_conn);
spin_unlock_bh(>frwd_lock);
-   if (!dev)
-   return;
/*
 * if the host is being removed bypass the connection
 * recovery initialization because we are going to kill
@@ -1407,7 +1404,7 @@ void iscsi_session_failure(struct iscsi_session *session,
iscsi_conn_error_event(conn->cls_conn, err);
else
iscsi_conn_failure(conn, err);
-   put_device(dev);
+   iscsi_put_conn(conn->cls_conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index d385eddb1a43..95c61fb4b81b 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2306,6 +2306,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
 }
 EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
 
+void iscsi_put_conn(struct iscsi_cls_conn *conn)
+{
+   put_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_put_conn);
+
+void iscsi_get_conn(struct iscsi_cls_conn *conn)
+{
+   get_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_get_conn);
+
 /*
  * iscsi interface functions
  */
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index b266d2a3bcb1..484e9787d817 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -436,6 +436,8 @@ extern void iscsi_remove_session(struct iscsi_cls_session 
*session);
 extern void iscsi_free_session(struct iscsi_cls_session *session);
 extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid);
+extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
 extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
 extern void iscsi_unblock_session(struct iscsi_cls_session *session);
 extern void iscsi_block_session(struct iscsi_cls_session *session);
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210710023516.3172075-11-sashal%40kernel.org.


[PATCH AUTOSEL 4.19 14/39] scsi: iscsi: Fix conn use after free during resets

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit ec29d0ac29be366450a7faffbcf8cba3a6a3b506 ]

If we haven't done a unbind target call we can race where
iscsi_conn_teardown wakes up the EH thread and then frees the conn while
those threads are still accessing the conn ehwait.

We can only do one TMF per session so this just moves the TMF fields from
the conn to the session. We can then rely on the
iscsi_session_teardown->iscsi_remove_session->__iscsi_unbind_session call
to remove the target and it's devices, and know after that point there is
no device or scsi-ml callout trying to access the session.

Link: 
https://lore.kernel.org/r/20210525181821.7617-14-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 115 +++-
 include/scsi/libiscsi.h |  11 ++--
 2 files changed, 60 insertions(+), 66 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 52521b68f0a7..5607fe8541c3 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -259,11 +259,11 @@ static int iscsi_prep_bidi_ahs(struct iscsi_task *task)
  */
 static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
 {
-   struct iscsi_conn *conn = task->conn;
-   struct iscsi_tm *tmf = >tmhdr;
+   struct iscsi_session *session = task->conn->session;
+   struct iscsi_tm *tmf = >tmhdr;
u64 hdr_lun;
 
-   if (conn->tmf_state == TMF_INITIAL)
+   if (session->tmf_state == TMF_INITIAL)
return 0;
 
if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC)
@@ -283,24 +283,19 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 * Fail all SCSI cmd PDUs
 */
if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] "
- "rejected.\n",
- opcode, task->itt,
- task->hdr_itt);
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] 
rejected.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
/*
 * And also all data-out PDUs in response to R2T
 * if fast_abort is set.
 */
-   if (conn->session->fast_abort) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] fast abort.\n",
- opcode, task->itt,
- task->hdr_itt);
+   if (session->fast_abort) {
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] fast 
abort.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
break;
@@ -313,7 +308,7 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 */
if (opcode == ISCSI_OP_SCSI_DATA_OUT &&
task->hdr_itt == tmf->rtt) {
-   ISCSI_DBG_SESSION(conn->session,
+   ISCSI_DBG_SESSION(session,
  "Preventing task %x/%x from sending "
  "data-out due to abort task in "
  "progress\n", task->itt,
@@ -970,20 +965,21 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
 static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 {
struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr;
+   struct iscsi_session *session = conn->session;
 
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
conn->tmfrsp_pdus_cnt++;
 
-   if (conn->tmf_state != TMF_QUEUED)
+   if (session->tmf_state != TMF_QUEUED)
return;
 
if (tmf->response == ISCSI_TMF_RSP_COMPLETE)
-   conn->tmf_state = TMF_SUCCESS;
+   session->tmf_state = TMF_SUCCESS;
else if (tmf->response == ISCSI_TMF_RSP_NO_TASK)
-   conn->tmf_state = TMF_NOT_FOUND;
+   session->tmf_state = TMF_NOT_FOUND;
   

[PATCH AUTOSEL 4.19 13/39] scsi: iscsi: Add iscsi_cls_conn refcount helpers

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit b1d19e8c92cfb0ded180ef3376c20e130414e067 ]

There are a couple places where we could free the iscsi_cls_conn while it's
still in use. This adds some helpers to get/put a refcount on the struct
and converts an exiting user. Subsequent commits will then use the helpers
to fix 2 bugs in the eh code.

Link: 
https://lore.kernel.org/r/20210525181821.7617-11-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c |  7 ++-
 drivers/scsi/scsi_transport_iscsi.c | 12 
 include/scsi/scsi_transport_iscsi.h |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 81471c304991..52521b68f0a7 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1385,7 +1385,6 @@ void iscsi_session_failure(struct iscsi_session *session,
   enum iscsi_err err)
 {
struct iscsi_conn *conn;
-   struct device *dev;
 
spin_lock_bh(>frwd_lock);
conn = session->leadconn;
@@ -1394,10 +1393,8 @@ void iscsi_session_failure(struct iscsi_session *session,
return;
}
 
-   dev = get_device(>cls_conn->dev);
+   iscsi_get_conn(conn->cls_conn);
spin_unlock_bh(>frwd_lock);
-   if (!dev)
-   return;
/*
 * if the host is being removed bypass the connection
 * recovery initialization because we are going to kill
@@ -1407,7 +1404,7 @@ void iscsi_session_failure(struct iscsi_session *session,
iscsi_conn_error_event(conn->cls_conn, err);
else
iscsi_conn_failure(conn, err);
-   put_device(dev);
+   iscsi_put_conn(conn->cls_conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index e340b05278b6..2aaa5a2bd613 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2306,6 +2306,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
 }
 EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
 
+void iscsi_put_conn(struct iscsi_cls_conn *conn)
+{
+   put_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_put_conn);
+
+void iscsi_get_conn(struct iscsi_cls_conn *conn)
+{
+   get_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_get_conn);
+
 /*
  * iscsi interface functions
  */
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index b266d2a3bcb1..484e9787d817 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -436,6 +436,8 @@ extern void iscsi_remove_session(struct iscsi_cls_session 
*session);
 extern void iscsi_free_session(struct iscsi_cls_session *session);
 extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid);
+extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
 extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
 extern void iscsi_unblock_session(struct iscsi_cls_session *session);
 extern void iscsi_block_session(struct iscsi_cls_session *session);
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210710023204.3171428-13-sashal%40kernel.org.


[PATCH AUTOSEL 5.4 24/63] scsi: iscsi: Fix conn use after free during resets

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit ec29d0ac29be366450a7faffbcf8cba3a6a3b506 ]

If we haven't done a unbind target call we can race where
iscsi_conn_teardown wakes up the EH thread and then frees the conn while
those threads are still accessing the conn ehwait.

We can only do one TMF per session so this just moves the TMF fields from
the conn to the session. We can then rely on the
iscsi_session_teardown->iscsi_remove_session->__iscsi_unbind_session call
to remove the target and it's devices, and know after that point there is
no device or scsi-ml callout trying to access the session.

Link: 
https://lore.kernel.org/r/20210525181821.7617-14-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 115 +++-
 include/scsi/libiscsi.h |  11 ++--
 2 files changed, 60 insertions(+), 66 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index b9981078375d..eeba6180711c 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -230,11 +230,11 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
  */
 static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
 {
-   struct iscsi_conn *conn = task->conn;
-   struct iscsi_tm *tmf = >tmhdr;
+   struct iscsi_session *session = task->conn->session;
+   struct iscsi_tm *tmf = >tmhdr;
u64 hdr_lun;
 
-   if (conn->tmf_state == TMF_INITIAL)
+   if (session->tmf_state == TMF_INITIAL)
return 0;
 
if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC)
@@ -254,24 +254,19 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 * Fail all SCSI cmd PDUs
 */
if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] "
- "rejected.\n",
- opcode, task->itt,
- task->hdr_itt);
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] 
rejected.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
/*
 * And also all data-out PDUs in response to R2T
 * if fast_abort is set.
 */
-   if (conn->session->fast_abort) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] fast abort.\n",
- opcode, task->itt,
- task->hdr_itt);
+   if (session->fast_abort) {
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] fast 
abort.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
break;
@@ -284,7 +279,7 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 */
if (opcode == ISCSI_OP_SCSI_DATA_OUT &&
task->hdr_itt == tmf->rtt) {
-   ISCSI_DBG_SESSION(conn->session,
+   ISCSI_DBG_SESSION(session,
  "Preventing task %x/%x from sending "
  "data-out due to abort task in "
  "progress\n", task->itt,
@@ -923,20 +918,21 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
 static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 {
struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr;
+   struct iscsi_session *session = conn->session;
 
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
conn->tmfrsp_pdus_cnt++;
 
-   if (conn->tmf_state != TMF_QUEUED)
+   if (session->tmf_state != TMF_QUEUED)
return;
 
if (tmf->response == ISCSI_TMF_RSP_COMPLETE)
-   conn->tmf_state = TMF_SUCCESS;
+   session->tmf_state = TMF_SUCCESS;
else if (tmf->response == ISCSI_TMF_RSP_NO_TASK)
-   conn->tmf_state = TMF_NOT_FOUND;
+   session->tmf_state = TMF_NOT_FOUND;
   

[PATCH AUTOSEL 5.4 23/63] scsi: iscsi: Add iscsi_cls_conn refcount helpers

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit b1d19e8c92cfb0ded180ef3376c20e130414e067 ]

There are a couple places where we could free the iscsi_cls_conn while it's
still in use. This adds some helpers to get/put a refcount on the struct
and converts an exiting user. Subsequent commits will then use the helpers
to fix 2 bugs in the eh code.

Link: 
https://lore.kernel.org/r/20210525181821.7617-11-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c |  7 ++-
 drivers/scsi/scsi_transport_iscsi.c | 12 
 include/scsi/scsi_transport_iscsi.h |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c5b7d18513b6..b9981078375d 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1348,7 +1348,6 @@ void iscsi_session_failure(struct iscsi_session *session,
   enum iscsi_err err)
 {
struct iscsi_conn *conn;
-   struct device *dev;
 
spin_lock_bh(>frwd_lock);
conn = session->leadconn;
@@ -1357,10 +1356,8 @@ void iscsi_session_failure(struct iscsi_session *session,
return;
}
 
-   dev = get_device(>cls_conn->dev);
+   iscsi_get_conn(conn->cls_conn);
spin_unlock_bh(>frwd_lock);
-   if (!dev)
-   return;
/*
 * if the host is being removed bypass the connection
 * recovery initialization because we are going to kill
@@ -1370,7 +1367,7 @@ void iscsi_session_failure(struct iscsi_session *session,
iscsi_conn_error_event(conn->cls_conn, err);
else
iscsi_conn_failure(conn, err);
-   put_device(dev);
+   iscsi_put_conn(conn->cls_conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index a26df7d6d5d1..2f1553d0a10e 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2308,6 +2308,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
 }
 EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
 
+void iscsi_put_conn(struct iscsi_cls_conn *conn)
+{
+   put_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_put_conn);
+
+void iscsi_get_conn(struct iscsi_cls_conn *conn)
+{
+   get_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_get_conn);
+
 /*
  * iscsi interface functions
  */
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 325ae731d9ad..71c78410e6ab 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -423,6 +423,8 @@ extern void iscsi_remove_session(struct iscsi_cls_session 
*session);
 extern void iscsi_free_session(struct iscsi_cls_session *session);
 extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid);
+extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
 extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
 extern void iscsi_unblock_session(struct iscsi_cls_session *session);
 extern void iscsi_block_session(struct iscsi_cls_session *session);
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210710022709.3170675-23-sashal%40kernel.org.


[PATCH AUTOSEL 5.10 38/93] scsi: iscsi: Fix conn use after free during resets

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit ec29d0ac29be366450a7faffbcf8cba3a6a3b506 ]

If we haven't done a unbind target call we can race where
iscsi_conn_teardown wakes up the EH thread and then frees the conn while
those threads are still accessing the conn ehwait.

We can only do one TMF per session so this just moves the TMF fields from
the conn to the session. We can then rely on the
iscsi_session_teardown->iscsi_remove_session->__iscsi_unbind_session call
to remove the target and it's devices, and know after that point there is
no device or scsi-ml callout trying to access the session.

Link: 
https://lore.kernel.org/r/20210525181821.7617-14-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 115 +++-
 include/scsi/libiscsi.h |  11 ++--
 2 files changed, 60 insertions(+), 66 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 67ac0a46889c..bd050befbafb 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -230,11 +230,11 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
  */
 static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
 {
-   struct iscsi_conn *conn = task->conn;
-   struct iscsi_tm *tmf = >tmhdr;
+   struct iscsi_session *session = task->conn->session;
+   struct iscsi_tm *tmf = >tmhdr;
u64 hdr_lun;
 
-   if (conn->tmf_state == TMF_INITIAL)
+   if (session->tmf_state == TMF_INITIAL)
return 0;
 
if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC)
@@ -254,24 +254,19 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 * Fail all SCSI cmd PDUs
 */
if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] "
- "rejected.\n",
- opcode, task->itt,
- task->hdr_itt);
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] 
rejected.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
/*
 * And also all data-out PDUs in response to R2T
 * if fast_abort is set.
 */
-   if (conn->session->fast_abort) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] fast abort.\n",
- opcode, task->itt,
- task->hdr_itt);
+   if (session->fast_abort) {
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] fast 
abort.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
break;
@@ -284,7 +279,7 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 */
if (opcode == ISCSI_OP_SCSI_DATA_OUT &&
task->hdr_itt == tmf->rtt) {
-   ISCSI_DBG_SESSION(conn->session,
+   ISCSI_DBG_SESSION(session,
  "Preventing task %x/%x from sending "
  "data-out due to abort task in "
  "progress\n", task->itt,
@@ -923,20 +918,21 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
 static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 {
struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr;
+   struct iscsi_session *session = conn->session;
 
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
conn->tmfrsp_pdus_cnt++;
 
-   if (conn->tmf_state != TMF_QUEUED)
+   if (session->tmf_state != TMF_QUEUED)
return;
 
if (tmf->response == ISCSI_TMF_RSP_COMPLETE)
-   conn->tmf_state = TMF_SUCCESS;
+   session->tmf_state = TMF_SUCCESS;
else if (tmf->response == ISCSI_TMF_RSP_NO_TASK)
-   conn->tmf_state = TMF_NOT_FOUND;
+   session->tmf_state = TMF_NOT_FOUND;
   

[PATCH AUTOSEL 5.10 37/93] scsi: iscsi: Add iscsi_cls_conn refcount helpers

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit b1d19e8c92cfb0ded180ef3376c20e130414e067 ]

There are a couple places where we could free the iscsi_cls_conn while it's
still in use. This adds some helpers to get/put a refcount on the struct
and converts an exiting user. Subsequent commits will then use the helpers
to fix 2 bugs in the eh code.

Link: 
https://lore.kernel.org/r/20210525181821.7617-11-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c |  7 ++-
 drivers/scsi/scsi_transport_iscsi.c | 12 
 include/scsi/scsi_transport_iscsi.h |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 41b8192d207d..67ac0a46889c 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1348,7 +1348,6 @@ void iscsi_session_failure(struct iscsi_session *session,
   enum iscsi_err err)
 {
struct iscsi_conn *conn;
-   struct device *dev;
 
spin_lock_bh(>frwd_lock);
conn = session->leadconn;
@@ -1357,10 +1356,8 @@ void iscsi_session_failure(struct iscsi_session *session,
return;
}
 
-   dev = get_device(>cls_conn->dev);
+   iscsi_get_conn(conn->cls_conn);
spin_unlock_bh(>frwd_lock);
-   if (!dev)
-   return;
/*
 * if the host is being removed bypass the connection
 * recovery initialization because we are going to kill
@@ -1370,7 +1367,7 @@ void iscsi_session_failure(struct iscsi_session *session,
iscsi_conn_error_event(conn->cls_conn, err);
else
iscsi_conn_failure(conn, err);
-   put_device(dev);
+   iscsi_put_conn(conn->cls_conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index c53c3f9fa526..a7db7c06f21c 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2351,6 +2351,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
 }
 EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
 
+void iscsi_put_conn(struct iscsi_cls_conn *conn)
+{
+   put_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_put_conn);
+
+void iscsi_get_conn(struct iscsi_cls_conn *conn)
+{
+   get_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_get_conn);
+
 /*
  * iscsi interface functions
  */
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 8a26a2ffa952..600f12105791 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -433,6 +433,8 @@ extern void iscsi_remove_session(struct iscsi_cls_session 
*session);
 extern void iscsi_free_session(struct iscsi_cls_session *session);
 extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid);
+extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
 extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
 extern void iscsi_unblock_session(struct iscsi_cls_session *session);
 extern void iscsi_block_session(struct iscsi_cls_session *session);
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210710022428.3169839-37-sashal%40kernel.org.


[PATCH AUTOSEL 5.12 041/104] scsi: iscsi: Fix conn use after free during resets

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit ec29d0ac29be366450a7faffbcf8cba3a6a3b506 ]

If we haven't done a unbind target call we can race where
iscsi_conn_teardown wakes up the EH thread and then frees the conn while
those threads are still accessing the conn ehwait.

We can only do one TMF per session so this just moves the TMF fields from
the conn to the session. We can then rely on the
iscsi_session_teardown->iscsi_remove_session->__iscsi_unbind_session call
to remove the target and it's devices, and know after that point there is
no device or scsi-ml callout trying to access the session.

Link: 
https://lore.kernel.org/r/20210525181821.7617-14-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 115 +++-
 include/scsi/libiscsi.h |  11 ++--
 2 files changed, 60 insertions(+), 66 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index ab39d7f65bbb..dfe906307e55 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -230,11 +230,11 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
  */
 static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
 {
-   struct iscsi_conn *conn = task->conn;
-   struct iscsi_tm *tmf = >tmhdr;
+   struct iscsi_session *session = task->conn->session;
+   struct iscsi_tm *tmf = >tmhdr;
u64 hdr_lun;
 
-   if (conn->tmf_state == TMF_INITIAL)
+   if (session->tmf_state == TMF_INITIAL)
return 0;
 
if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC)
@@ -254,24 +254,19 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 * Fail all SCSI cmd PDUs
 */
if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] "
- "rejected.\n",
- opcode, task->itt,
- task->hdr_itt);
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] 
rejected.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
/*
 * And also all data-out PDUs in response to R2T
 * if fast_abort is set.
 */
-   if (conn->session->fast_abort) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] fast abort.\n",
- opcode, task->itt,
- task->hdr_itt);
+   if (session->fast_abort) {
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] fast 
abort.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
break;
@@ -284,7 +279,7 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 */
if (opcode == ISCSI_OP_SCSI_DATA_OUT &&
task->hdr_itt == tmf->rtt) {
-   ISCSI_DBG_SESSION(conn->session,
+   ISCSI_DBG_SESSION(session,
  "Preventing task %x/%x from sending "
  "data-out due to abort task in "
  "progress\n", task->itt,
@@ -936,20 +931,21 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
 static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 {
struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr;
+   struct iscsi_session *session = conn->session;
 
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
conn->tmfrsp_pdus_cnt++;
 
-   if (conn->tmf_state != TMF_QUEUED)
+   if (session->tmf_state != TMF_QUEUED)
return;
 
if (tmf->response == ISCSI_TMF_RSP_COMPLETE)
-   conn->tmf_state = TMF_SUCCESS;
+   session->tmf_state = TMF_SUCCESS;
else if (tmf->response == ISCSI_TMF_RSP_NO_TASK)
-   conn->tmf_state = TMF_NOT_FOUND;
+   session->tmf_state = TMF_NOT_FOUND;
   

[PATCH AUTOSEL 5.12 039/104] scsi: iscsi: Stop queueing during ep_disconnect

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit 891e2639deae721dc43764a44fa255890dc34313 ]

During ep_disconnect we have been doing iscsi_suspend_tx/queue to block new
I/O but every driver except cxgbi and iscsi_tcp can still get I/O from
__iscsi_conn_send_pdu() if we haven't called iscsi_conn_failure() before
ep_disconnect. This could happen if we were terminating the session, and
the logout timed out before it was even sent to libiscsi.

Fix the issue by adding a helper which reverses the bind_conn call that
allows new I/O to be queued. Drivers implementing ep_disconnect can use this
to make sure new I/O is not queued to them when handling the disconnect.

Link: 
https://lore.kernel.org/r/20210525181821.7617-3-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/infiniband/ulp/iser/iscsi_iser.c |  1 +
 drivers/scsi/be2iscsi/be_main.c  |  1 +
 drivers/scsi/bnx2i/bnx2i_iscsi.c |  1 +
 drivers/scsi/cxgbi/cxgb3i/cxgb3i.c   |  1 +
 drivers/scsi/cxgbi/cxgb4i/cxgb4i.c   |  1 +
 drivers/scsi/libiscsi.c  | 70 +---
 drivers/scsi/qedi/qedi_iscsi.c   |  1 +
 drivers/scsi/qla4xxx/ql4_os.c|  1 +
 drivers/scsi/scsi_transport_iscsi.c  | 10 +++-
 include/scsi/libiscsi.h  |  1 +
 include/scsi/scsi_transport_iscsi.h  |  1 +
 11 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c 
b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 8fcaa1136f2c..6baebcb6d14d 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -1002,6 +1002,7 @@ static struct iscsi_transport iscsi_iser_transport = {
/* connection management */
.create_conn= iscsi_iser_conn_create,
.bind_conn  = iscsi_iser_conn_bind,
+   .unbind_conn= iscsi_conn_unbind,
.destroy_conn   = iscsi_conn_teardown,
.attr_is_visible= iser_attr_is_visible,
.set_param  = iscsi_iser_set_param,
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 90fcddb76f46..e9658a67d9da 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5809,6 +5809,7 @@ struct iscsi_transport beiscsi_iscsi_transport = {
.destroy_session = beiscsi_session_destroy,
.create_conn = beiscsi_conn_create,
.bind_conn = beiscsi_conn_bind,
+   .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_conn_teardown,
.attr_is_visible = beiscsi_attr_is_visible,
.set_iface_param = beiscsi_iface_set_param,
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 1e6d8f62ea3c..b6c1da46d582 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -2276,6 +2276,7 @@ struct iscsi_transport bnx2i_iscsi_transport = {
.destroy_session= bnx2i_session_destroy,
.create_conn= bnx2i_conn_create,
.bind_conn  = bnx2i_conn_bind,
+   .unbind_conn= iscsi_conn_unbind,
.destroy_conn   = bnx2i_conn_destroy,
.attr_is_visible= bnx2i_attr_is_visible,
.set_param  = iscsi_set_param,
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c 
b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index 37d99357120f..edcd3fab6973 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -117,6 +117,7 @@ static struct iscsi_transport cxgb3i_iscsi_transport = {
/* connection management */
.create_conn= cxgbi_create_conn,
.bind_conn  = cxgbi_bind_conn,
+   .unbind_conn= iscsi_conn_unbind,
.destroy_conn   = iscsi_tcp_conn_teardown,
.start_conn = iscsi_conn_start,
.stop_conn  = iscsi_conn_stop,
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c 
b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index 2c3491528d42..efb3e2b3398e 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -134,6 +134,7 @@ static struct iscsi_transport cxgb4i_iscsi_transport = {
/* connection management */
.create_conn= cxgbi_create_conn,
.bind_conn  = cxgbi_bind_conn,
+   .unbind_conn= iscsi_conn_unbind,
.destroy_conn   = iscsi_tcp_conn_teardown,
.start_conn = iscsi_conn_start,
.stop_conn  = iscsi_conn_stop,
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 4834219497ee..2aaf83678654 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1387,23 +1387,32 @@ void iscsi_session_failure(struct iscsi_session 
*session,
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
-void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
+static bool

[PATCH AUTOSEL 5.13 045/114] scsi: iscsi: Fix conn use after free during resets

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit ec29d0ac29be366450a7faffbcf8cba3a6a3b506 ]

If we haven't done a unbind target call we can race where
iscsi_conn_teardown wakes up the EH thread and then frees the conn while
those threads are still accessing the conn ehwait.

We can only do one TMF per session so this just moves the TMF fields from
the conn to the session. We can then rely on the
iscsi_session_teardown->iscsi_remove_session->__iscsi_unbind_session call
to remove the target and it's devices, and know after that point there is
no device or scsi-ml callout trying to access the session.

Link: 
https://lore.kernel.org/r/20210525181821.7617-14-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 115 +++-
 include/scsi/libiscsi.h |  11 ++--
 2 files changed, 60 insertions(+), 66 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index ab39d7f65bbb..dfe906307e55 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -230,11 +230,11 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
  */
 static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
 {
-   struct iscsi_conn *conn = task->conn;
-   struct iscsi_tm *tmf = >tmhdr;
+   struct iscsi_session *session = task->conn->session;
+   struct iscsi_tm *tmf = >tmhdr;
u64 hdr_lun;
 
-   if (conn->tmf_state == TMF_INITIAL)
+   if (session->tmf_state == TMF_INITIAL)
return 0;
 
if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC)
@@ -254,24 +254,19 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 * Fail all SCSI cmd PDUs
 */
if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] "
- "rejected.\n",
- opcode, task->itt,
- task->hdr_itt);
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] 
rejected.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
/*
 * And also all data-out PDUs in response to R2T
 * if fast_abort is set.
 */
-   if (conn->session->fast_abort) {
-   iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x itt "
- "0x%x/0x%x] fast abort.\n",
- opcode, task->itt,
- task->hdr_itt);
+   if (session->fast_abort) {
+   iscsi_session_printk(KERN_INFO, session,
+"task [op %x itt 0x%x/0x%x] fast 
abort.\n",
+opcode, task->itt, task->hdr_itt);
return -EACCES;
}
break;
@@ -284,7 +279,7 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task 
*task, int opcode)
 */
if (opcode == ISCSI_OP_SCSI_DATA_OUT &&
task->hdr_itt == tmf->rtt) {
-   ISCSI_DBG_SESSION(conn->session,
+   ISCSI_DBG_SESSION(session,
  "Preventing task %x/%x from sending "
  "data-out due to abort task in "
  "progress\n", task->itt,
@@ -936,20 +931,21 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
 static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 {
struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr;
+   struct iscsi_session *session = conn->session;
 
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
conn->tmfrsp_pdus_cnt++;
 
-   if (conn->tmf_state != TMF_QUEUED)
+   if (session->tmf_state != TMF_QUEUED)
return;
 
if (tmf->response == ISCSI_TMF_RSP_COMPLETE)
-   conn->tmf_state = TMF_SUCCESS;
+   session->tmf_state = TMF_SUCCESS;
else if (tmf->response == ISCSI_TMF_RSP_NO_TASK)
-   conn->tmf_state = TMF_NOT_FOUND;
+   session->tmf_state = TMF_NOT_FOUND;
   

[PATCH AUTOSEL 5.13 044/114] scsi: iscsi: Add iscsi_cls_conn refcount helpers

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit b1d19e8c92cfb0ded180ef3376c20e130414e067 ]

There are a couple places where we could free the iscsi_cls_conn while it's
still in use. This adds some helpers to get/put a refcount on the struct
and converts an exiting user. Subsequent commits will then use the helpers
to fix 2 bugs in the eh code.

Link: 
https://lore.kernel.org/r/20210525181821.7617-11-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c |  7 ++-
 drivers/scsi/scsi_transport_iscsi.c | 12 
 include/scsi/scsi_transport_iscsi.h |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 2aaf83678654..ab39d7f65bbb 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1361,7 +1361,6 @@ void iscsi_session_failure(struct iscsi_session *session,
   enum iscsi_err err)
 {
struct iscsi_conn *conn;
-   struct device *dev;
 
spin_lock_bh(>frwd_lock);
conn = session->leadconn;
@@ -1370,10 +1369,8 @@ void iscsi_session_failure(struct iscsi_session *session,
return;
}
 
-   dev = get_device(>cls_conn->dev);
+   iscsi_get_conn(conn->cls_conn);
spin_unlock_bh(>frwd_lock);
-   if (!dev)
-   return;
/*
 * if the host is being removed bypass the connection
 * recovery initialization because we are going to kill
@@ -1383,7 +1380,7 @@ void iscsi_session_failure(struct iscsi_session *session,
iscsi_conn_error_event(conn->cls_conn, err);
else
iscsi_conn_failure(conn, err);
-   put_device(dev);
+   iscsi_put_conn(conn->cls_conn);
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 82491343e94a..869cfc329da9 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2348,6 +2348,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
 }
 EXPORT_SYMBOL_GPL(iscsi_destroy_conn);
 
+void iscsi_put_conn(struct iscsi_cls_conn *conn)
+{
+   put_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_put_conn);
+
+void iscsi_get_conn(struct iscsi_cls_conn *conn)
+{
+   get_device(>dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_get_conn);
+
 /*
  * iscsi interface functions
  */
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 8874016b3c9a..eb6ed499324d 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -435,6 +435,8 @@ extern void iscsi_remove_session(struct iscsi_cls_session 
*session);
 extern void iscsi_free_session(struct iscsi_cls_session *session);
 extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
int dd_size, uint32_t cid);
+extern void iscsi_put_conn(struct iscsi_cls_conn *conn);
+extern void iscsi_get_conn(struct iscsi_cls_conn *conn);
 extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
 extern void iscsi_unblock_session(struct iscsi_cls_session *session);
 extern void iscsi_block_session(struct iscsi_cls_session *session);
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210710021748.3167666-44-sashal%40kernel.org.


[PATCH AUTOSEL 5.13 043/114] scsi: iscsi: Stop queueing during ep_disconnect

2021-07-09 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit 891e2639deae721dc43764a44fa255890dc34313 ]

During ep_disconnect we have been doing iscsi_suspend_tx/queue to block new
I/O but every driver except cxgbi and iscsi_tcp can still get I/O from
__iscsi_conn_send_pdu() if we haven't called iscsi_conn_failure() before
ep_disconnect. This could happen if we were terminating the session, and
the logout timed out before it was even sent to libiscsi.

Fix the issue by adding a helper which reverses the bind_conn call that
allows new I/O to be queued. Drivers implementing ep_disconnect can use this
to make sure new I/O is not queued to them when handling the disconnect.

Link: 
https://lore.kernel.org/r/20210525181821.7617-3-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/infiniband/ulp/iser/iscsi_iser.c |  1 +
 drivers/scsi/be2iscsi/be_main.c  |  1 +
 drivers/scsi/bnx2i/bnx2i_iscsi.c |  1 +
 drivers/scsi/cxgbi/cxgb3i/cxgb3i.c   |  1 +
 drivers/scsi/cxgbi/cxgb4i/cxgb4i.c   |  1 +
 drivers/scsi/libiscsi.c  | 70 +---
 drivers/scsi/qedi/qedi_iscsi.c   |  1 +
 drivers/scsi/qla4xxx/ql4_os.c|  1 +
 drivers/scsi/scsi_transport_iscsi.c  | 10 +++-
 include/scsi/libiscsi.h  |  1 +
 include/scsi/scsi_transport_iscsi.h  |  1 +
 11 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c 
b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 8fcaa1136f2c..6baebcb6d14d 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -1002,6 +1002,7 @@ static struct iscsi_transport iscsi_iser_transport = {
/* connection management */
.create_conn= iscsi_iser_conn_create,
.bind_conn  = iscsi_iser_conn_bind,
+   .unbind_conn= iscsi_conn_unbind,
.destroy_conn   = iscsi_conn_teardown,
.attr_is_visible= iser_attr_is_visible,
.set_param  = iscsi_iser_set_param,
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 22cf7f4b8d8c..27c4f1598f76 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5809,6 +5809,7 @@ struct iscsi_transport beiscsi_iscsi_transport = {
.destroy_session = beiscsi_session_destroy,
.create_conn = beiscsi_conn_create,
.bind_conn = beiscsi_conn_bind,
+   .unbind_conn = iscsi_conn_unbind,
.destroy_conn = iscsi_conn_teardown,
.attr_is_visible = beiscsi_attr_is_visible,
.set_iface_param = beiscsi_iface_set_param,
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 1e6d8f62ea3c..b6c1da46d582 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -2276,6 +2276,7 @@ struct iscsi_transport bnx2i_iscsi_transport = {
.destroy_session= bnx2i_session_destroy,
.create_conn= bnx2i_conn_create,
.bind_conn  = bnx2i_conn_bind,
+   .unbind_conn= iscsi_conn_unbind,
.destroy_conn   = bnx2i_conn_destroy,
.attr_is_visible= bnx2i_attr_is_visible,
.set_param  = iscsi_set_param,
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c 
b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index 203f938fca7e..f949a4e00783 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -117,6 +117,7 @@ static struct iscsi_transport cxgb3i_iscsi_transport = {
/* connection management */
.create_conn= cxgbi_create_conn,
.bind_conn  = cxgbi_bind_conn,
+   .unbind_conn= iscsi_conn_unbind,
.destroy_conn   = iscsi_tcp_conn_teardown,
.start_conn = iscsi_conn_start,
.stop_conn  = iscsi_conn_stop,
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c 
b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index 2c3491528d42..efb3e2b3398e 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -134,6 +134,7 @@ static struct iscsi_transport cxgb4i_iscsi_transport = {
/* connection management */
.create_conn= cxgbi_create_conn,
.bind_conn  = cxgbi_bind_conn,
+   .unbind_conn= iscsi_conn_unbind,
.destroy_conn   = iscsi_tcp_conn_teardown,
.start_conn = iscsi_conn_start,
.stop_conn  = iscsi_conn_stop,
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 4834219497ee..2aaf83678654 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1387,23 +1387,32 @@ void iscsi_session_failure(struct iscsi_session 
*session,
 }
 EXPORT_SYMBOL_GPL(iscsi_session_failure);
 
-void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
+static bool

Re: [PATCH AUTOSEL 5.10 07/22] scsi: iscsi: Fix race condition between login and sync thread

2021-04-14 Thread Sasha Levin

On Tue, Apr 06, 2021 at 12:24:32PM -0500, Mike Christie wrote:

On 4/5/21 11:04 AM, Sasha Levin wrote:

From: Gulam Mohamed 

[ Upstream commit 9e67600ed6b8565da4b85698ec659b5879a6c1c6 ]

A kernel panic was observed due to a timing issue between the sync thread
and the initiator processing a login response from the target. The session
reopen can be invoked both from the session sync thread when iscsid
restarts and from iscsid through the error handler. Before the initiator
receives the response to a login, another reopen request can be sent from
the error handler/sync session. When the initial login response is
subsequently processed, the connection has been closed and the socket has
been released.

To fix this a new connection state, ISCSI_CONN_BOUND, is added:

 - Set the connection state value to ISCSI_CONN_DOWN upon
   iscsi_if_ep_disconnect() and iscsi_if_stop_conn()

 - Set the connection state to the newly created value ISCSI_CONN_BOUND
   after bind connection (transport->bind_conn())

 - In iscsi_set_param(), return -ENOTCONN if the connection state is not
   either ISCSI_CONN_BOUND or ISCSI_CONN_UP

Link: 
https://urldefense.com/v3/__https://lore.kernel.org/r/20210325093248.284678-1-gulam.mohamed@oracle.com__;!!GqivPVa7Brio!Jiqrc6pu3EgrquzpG-KpNQkNebwKUgctkE0MN1MloQ2y5Y4OVOkKN0yCr2_W_CX2oRet$
Reviewed-by: Mike Christie 



There was a mistake in my review of this patch. It will also require
this "[PATCH 1/1] scsi: iscsi: fix iscsi cls conn state":

https://lore.kernel.org/linux-scsi/20210406171746.5016-1-michael.chris...@oracle.com/T/#u


As the fix isn't upstream yet, I'll drop 9e67600ed6b for now and
re-queue it for the next round. Thanks!

--
Thanks,
Sasha

--
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/YHbcsA22Ag3o4QAZ%40sashalap.


[PATCH AUTOSEL 5.10 07/22] scsi: iscsi: Fix race condition between login and sync thread

2021-04-05 Thread Sasha Levin
From: Gulam Mohamed 

[ Upstream commit 9e67600ed6b8565da4b85698ec659b5879a6c1c6 ]

A kernel panic was observed due to a timing issue between the sync thread
and the initiator processing a login response from the target. The session
reopen can be invoked both from the session sync thread when iscsid
restarts and from iscsid through the error handler. Before the initiator
receives the response to a login, another reopen request can be sent from
the error handler/sync session. When the initial login response is
subsequently processed, the connection has been closed and the socket has
been released.

To fix this a new connection state, ISCSI_CONN_BOUND, is added:

 - Set the connection state value to ISCSI_CONN_DOWN upon
   iscsi_if_ep_disconnect() and iscsi_if_stop_conn()

 - Set the connection state to the newly created value ISCSI_CONN_BOUND
   after bind connection (transport->bind_conn())

 - In iscsi_set_param(), return -ENOTCONN if the connection state is not
   either ISCSI_CONN_BOUND or ISCSI_CONN_UP

Link: https://lore.kernel.org/r/20210325093248.284678-1-gulam.moha...@oracle.com
Reviewed-by: Mike Christie 
Signed-off-by: Gulam Mohamed 
Signed-off-by: Martin K. Petersen 

index 91074fd97f64..f4bf62b007a0 100644

Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 14 +-
 include/scsi/scsi_transport_iscsi.h |  1 +
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index c53c3f9fa526..f648452d8d66 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2478,6 +2478,7 @@ static void iscsi_if_stop_conn(struct iscsi_cls_conn 
*conn, int flag)
 */
mutex_lock(_mutex);
conn->transport->stop_conn(conn, flag);
+   conn->state = ISCSI_CONN_DOWN;
mutex_unlock(_mutex);
 
 }
@@ -2904,6 +2905,13 @@ iscsi_set_param(struct iscsi_transport *transport, 
struct iscsi_uevent *ev)
default:
err = transport->set_param(conn, ev->u.set_param.param,
   data, ev->u.set_param.len);
+   if ((conn->state == ISCSI_CONN_BOUND) ||
+   (conn->state == ISCSI_CONN_UP)) {
+   err = transport->set_param(conn, ev->u.set_param.param,
+   data, ev->u.set_param.len);
+   } else {
+   return -ENOTCONN;
+   }
}
 
return err;
@@ -2963,6 +2971,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport 
*transport,
mutex_lock(>ep_mutex);
conn->ep = NULL;
mutex_unlock(>ep_mutex);
+   conn->state = ISCSI_CONN_DOWN;
}
 
transport->ep_disconnect(ep);
@@ -3730,6 +3739,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
ev->r.retcode = transport->bind_conn(session, conn,
ev->u.b_conn.transport_eph,
ev->u.b_conn.is_leading);
+   if (!ev->r.retcode)
+   conn->state = ISCSI_CONN_BOUND;
mutex_unlock(_mutex);
 
if (ev->r.retcode || !transport->ep_connect)
@@ -3969,7 +3980,8 @@ iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR);
 static const char *const connection_state_names[] = {
[ISCSI_CONN_UP] = "up",
[ISCSI_CONN_DOWN] = "down",
-   [ISCSI_CONN_FAILED] = "failed"
+   [ISCSI_CONN_FAILED] = "failed",
+   [ISCSI_CONN_BOUND] = "bound"
 };
 
 static ssize_t show_conn_state(struct device *dev,
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 8a26a2ffa952..fc5a39839b4b 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -193,6 +193,7 @@ enum iscsi_connection_state {
ISCSI_CONN_UP = 0,
ISCSI_CONN_DOWN,
ISCSI_CONN_FAILED,
+   ISCSI_CONN_BOUND,
 };
 
 struct iscsi_cls_conn {
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210405160432.268374-7-sashal%40kernel.org.


[PATCH AUTOSEL 5.11 07/22] scsi: iscsi: Fix race condition between login and sync thread

2021-04-05 Thread Sasha Levin
From: Gulam Mohamed 

[ Upstream commit 9e67600ed6b8565da4b85698ec659b5879a6c1c6 ]

A kernel panic was observed due to a timing issue between the sync thread
and the initiator processing a login response from the target. The session
reopen can be invoked both from the session sync thread when iscsid
restarts and from iscsid through the error handler. Before the initiator
receives the response to a login, another reopen request can be sent from
the error handler/sync session. When the initial login response is
subsequently processed, the connection has been closed and the socket has
been released.

To fix this a new connection state, ISCSI_CONN_BOUND, is added:

 - Set the connection state value to ISCSI_CONN_DOWN upon
   iscsi_if_ep_disconnect() and iscsi_if_stop_conn()

 - Set the connection state to the newly created value ISCSI_CONN_BOUND
   after bind connection (transport->bind_conn())

 - In iscsi_set_param(), return -ENOTCONN if the connection state is not
   either ISCSI_CONN_BOUND or ISCSI_CONN_UP

Link: https://lore.kernel.org/r/20210325093248.284678-1-gulam.moha...@oracle.com
Reviewed-by: Mike Christie 
Signed-off-by: Gulam Mohamed 
Signed-off-by: Martin K. Petersen 

index 91074fd97f64..f4bf62b007a0 100644

Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 14 +-
 include/scsi/scsi_transport_iscsi.h |  1 +
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index c53c3f9fa526..f648452d8d66 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2478,6 +2478,7 @@ static void iscsi_if_stop_conn(struct iscsi_cls_conn 
*conn, int flag)
 */
mutex_lock(_mutex);
conn->transport->stop_conn(conn, flag);
+   conn->state = ISCSI_CONN_DOWN;
mutex_unlock(_mutex);
 
 }
@@ -2904,6 +2905,13 @@ iscsi_set_param(struct iscsi_transport *transport, 
struct iscsi_uevent *ev)
default:
err = transport->set_param(conn, ev->u.set_param.param,
   data, ev->u.set_param.len);
+   if ((conn->state == ISCSI_CONN_BOUND) ||
+   (conn->state == ISCSI_CONN_UP)) {
+   err = transport->set_param(conn, ev->u.set_param.param,
+   data, ev->u.set_param.len);
+   } else {
+   return -ENOTCONN;
+   }
}
 
return err;
@@ -2963,6 +2971,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport 
*transport,
mutex_lock(>ep_mutex);
conn->ep = NULL;
mutex_unlock(>ep_mutex);
+   conn->state = ISCSI_CONN_DOWN;
}
 
transport->ep_disconnect(ep);
@@ -3730,6 +3739,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
ev->r.retcode = transport->bind_conn(session, conn,
ev->u.b_conn.transport_eph,
ev->u.b_conn.is_leading);
+   if (!ev->r.retcode)
+   conn->state = ISCSI_CONN_BOUND;
mutex_unlock(_mutex);
 
if (ev->r.retcode || !transport->ep_connect)
@@ -3969,7 +3980,8 @@ iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR);
 static const char *const connection_state_names[] = {
[ISCSI_CONN_UP] = "up",
[ISCSI_CONN_DOWN] = "down",
-   [ISCSI_CONN_FAILED] = "failed"
+   [ISCSI_CONN_FAILED] = "failed",
+   [ISCSI_CONN_BOUND] = "bound"
 };
 
 static ssize_t show_conn_state(struct device *dev,
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 8a26a2ffa952..fc5a39839b4b 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -193,6 +193,7 @@ enum iscsi_connection_state {
ISCSI_CONN_UP = 0,
ISCSI_CONN_DOWN,
ISCSI_CONN_FAILED,
+   ISCSI_CONN_BOUND,
 };
 
 struct iscsi_cls_conn {
-- 
2.30.2

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210405160406.268132-7-sashal%40kernel.org.


[PATCH AUTOSEL 4.4 8/8] scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling

2021-03-02 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit d28d48c699779973ab9a3bd0e5acfa112bd4fdef ]

If iscsi_prep_scsi_cmd_pdu() fails we try to add it back to the cmdqueue,
but we leave it partially setup. We don't have functions that can undo the
pdu and init task setup. We only have cleanup_task which can clean up both
parts. So this has us just fail the cmd and go through the standard cleanup
routine and then have the SCSI midlayer retry it like is done when it fails
in the queuecommand path.

Link: 
https://lore.kernel.org/r/20210207044608.27585-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 36e415487fe5..444f58589f33 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1568,14 +1568,9 @@ check_mgmt:
}
rc = iscsi_prep_scsi_cmd_pdu(conn->task);
if (rc) {
-   if (rc == -ENOMEM || rc == -EACCES) {
-   spin_lock_bh(>taskqueuelock);
-   list_add_tail(>task->running,
- >cmdqueue);
-   conn->task = NULL;
-   spin_unlock_bh(>taskqueuelock);
-   goto done;
-   } else
+   if (rc == -ENOMEM || rc == -EACCES)
+   fail_scsi_task(conn->task, DID_IMM_RETRY);
+   else
fail_scsi_task(conn->task, DID_ABORT);
spin_lock_bh(>taskqueuelock);
continue;
-- 
2.30.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210302115935.63777-8-sashal%40kernel.org.


[PATCH AUTOSEL 4.9 10/10] scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling

2021-03-02 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit d28d48c699779973ab9a3bd0e5acfa112bd4fdef ]

If iscsi_prep_scsi_cmd_pdu() fails we try to add it back to the cmdqueue,
but we leave it partially setup. We don't have functions that can undo the
pdu and init task setup. We only have cleanup_task which can clean up both
parts. So this has us just fail the cmd and go through the standard cleanup
routine and then have the SCSI midlayer retry it like is done when it fails
in the queuecommand path.

Link: 
https://lore.kernel.org/r/20210207044608.27585-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index a84b473d4a08..c0c8b97f6e90 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1568,14 +1568,9 @@ check_mgmt:
}
rc = iscsi_prep_scsi_cmd_pdu(conn->task);
if (rc) {
-   if (rc == -ENOMEM || rc == -EACCES) {
-   spin_lock_bh(>taskqueuelock);
-   list_add_tail(>task->running,
- >cmdqueue);
-   conn->task = NULL;
-   spin_unlock_bh(>taskqueuelock);
-   goto done;
-   } else
+   if (rc == -ENOMEM || rc == -EACCES)
+   fail_scsi_task(conn->task, DID_IMM_RETRY);
+   else
fail_scsi_task(conn->task, DID_ABORT);
spin_lock_bh(>taskqueuelock);
continue;
-- 
2.30.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210302115921.63636-10-sashal%40kernel.org.


[PATCH AUTOSEL 4.14 13/13] scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling

2021-03-02 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit d28d48c699779973ab9a3bd0e5acfa112bd4fdef ]

If iscsi_prep_scsi_cmd_pdu() fails we try to add it back to the cmdqueue,
but we leave it partially setup. We don't have functions that can undo the
pdu and init task setup. We only have cleanup_task which can clean up both
parts. So this has us just fail the cmd and go through the standard cleanup
routine and then have the SCSI midlayer retry it like is done when it fails
in the queuecommand path.

Link: 
https://lore.kernel.org/r/20210207044608.27585-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index f7e1af90849b..fffaf9b3476d 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1569,14 +1569,9 @@ check_mgmt:
}
rc = iscsi_prep_scsi_cmd_pdu(conn->task);
if (rc) {
-   if (rc == -ENOMEM || rc == -EACCES) {
-   spin_lock_bh(>taskqueuelock);
-   list_add_tail(>task->running,
- >cmdqueue);
-   conn->task = NULL;
-   spin_unlock_bh(>taskqueuelock);
-   goto done;
-   } else
+   if (rc == -ENOMEM || rc == -EACCES)
+   fail_scsi_task(conn->task, DID_IMM_RETRY);
+   else
fail_scsi_task(conn->task, DID_ABORT);
spin_lock_bh(>taskqueuelock);
continue;
-- 
2.30.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210302115903.63458-13-sashal%40kernel.org.


[PATCH AUTOSEL 4.19 19/21] scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling

2021-03-02 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit d28d48c699779973ab9a3bd0e5acfa112bd4fdef ]

If iscsi_prep_scsi_cmd_pdu() fails we try to add it back to the cmdqueue,
but we leave it partially setup. We don't have functions that can undo the
pdu and init task setup. We only have cleanup_task which can clean up both
parts. So this has us just fail the cmd and go through the standard cleanup
routine and then have the SCSI midlayer retry it like is done when it fails
in the queuecommand path.

Link: 
https://lore.kernel.org/r/20210207044608.27585-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 1c69515e870c..5e373a3752ba 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1569,14 +1569,9 @@ check_mgmt:
}
rc = iscsi_prep_scsi_cmd_pdu(conn->task);
if (rc) {
-   if (rc == -ENOMEM || rc == -EACCES) {
-   spin_lock_bh(>taskqueuelock);
-   list_add_tail(>task->running,
- >cmdqueue);
-   conn->task = NULL;
-   spin_unlock_bh(>taskqueuelock);
-   goto done;
-   } else
+   if (rc == -ENOMEM || rc == -EACCES)
+   fail_scsi_task(conn->task, DID_IMM_RETRY);
+   else
fail_scsi_task(conn->task, DID_ABORT);
spin_lock_bh(>taskqueuelock);
continue;
-- 
2.30.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210302115835.63269-19-sashal%40kernel.org.


[PATCH AUTOSEL 5.4 30/33] scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling

2021-03-02 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit d28d48c699779973ab9a3bd0e5acfa112bd4fdef ]

If iscsi_prep_scsi_cmd_pdu() fails we try to add it back to the cmdqueue,
but we leave it partially setup. We don't have functions that can undo the
pdu and init task setup. We only have cleanup_task which can clean up both
parts. So this has us just fail the cmd and go through the standard cleanup
routine and then have the SCSI midlayer retry it like is done when it fails
in the queuecommand path.

Link: 
https://lore.kernel.org/r/20210207044608.27585-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index f954be3d5ee2..0b7449de1b53 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1532,14 +1532,9 @@ check_mgmt:
}
rc = iscsi_prep_scsi_cmd_pdu(conn->task);
if (rc) {
-   if (rc == -ENOMEM || rc == -EACCES) {
-   spin_lock_bh(>taskqueuelock);
-   list_add_tail(>task->running,
- >cmdqueue);
-   conn->task = NULL;
-   spin_unlock_bh(>taskqueuelock);
-   goto done;
-   } else
+   if (rc == -ENOMEM || rc == -EACCES)
+   fail_scsi_task(conn->task, DID_IMM_RETRY);
+   else
fail_scsi_task(conn->task, DID_ABORT);
spin_lock_bh(>taskqueuelock);
continue;
-- 
2.30.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210302115749.62653-30-sashal%40kernel.org.


[PATCH AUTOSEL 5.10 44/47] scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling

2021-03-02 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit d28d48c699779973ab9a3bd0e5acfa112bd4fdef ]

If iscsi_prep_scsi_cmd_pdu() fails we try to add it back to the cmdqueue,
but we leave it partially setup. We don't have functions that can undo the
pdu and init task setup. We only have cleanup_task which can clean up both
parts. So this has us just fail the cmd and go through the standard cleanup
routine and then have the SCSI midlayer retry it like is done when it fails
in the queuecommand path.

Link: 
https://lore.kernel.org/r/20210207044608.27585-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index f9314f1393fb..ee0786bab4fc 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1532,14 +1532,9 @@ check_mgmt:
}
rc = iscsi_prep_scsi_cmd_pdu(conn->task);
if (rc) {
-   if (rc == -ENOMEM || rc == -EACCES) {
-   spin_lock_bh(>taskqueuelock);
-   list_add_tail(>task->running,
- >cmdqueue);
-   conn->task = NULL;
-   spin_unlock_bh(>taskqueuelock);
-   goto done;
-   } else
+   if (rc == -ENOMEM || rc == -EACCES)
+   fail_scsi_task(conn->task, DID_IMM_RETRY);
+   else
fail_scsi_task(conn->task, DID_ABORT);
spin_lock_bh(>taskqueuelock);
continue;
-- 
2.30.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210302115646.62291-44-sashal%40kernel.org.


[PATCH AUTOSEL 5.11 49/52] scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling

2021-03-02 Thread Sasha Levin
From: Mike Christie 

[ Upstream commit d28d48c699779973ab9a3bd0e5acfa112bd4fdef ]

If iscsi_prep_scsi_cmd_pdu() fails we try to add it back to the cmdqueue,
but we leave it partially setup. We don't have functions that can undo the
pdu and init task setup. We only have cleanup_task which can clean up both
parts. So this has us just fail the cmd and go through the standard cleanup
routine and then have the SCSI midlayer retry it like is done when it fails
in the queuecommand path.

Link: 
https://lore.kernel.org/r/20210207044608.27585-2-michael.chris...@oracle.com
Reviewed-by: Lee Duncan 
Signed-off-by: Mike Christie 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 4e668aafbcca..cee1dbaa1b93 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1532,14 +1532,9 @@ check_mgmt:
}
rc = iscsi_prep_scsi_cmd_pdu(conn->task);
if (rc) {
-   if (rc == -ENOMEM || rc == -EACCES) {
-   spin_lock_bh(>taskqueuelock);
-   list_add_tail(>task->running,
- >cmdqueue);
-   conn->task = NULL;
-   spin_unlock_bh(>taskqueuelock);
-   goto done;
-   } else
+   if (rc == -ENOMEM || rc == -EACCES)
+   fail_scsi_task(conn->task, DID_IMM_RETRY);
+   else
fail_scsi_task(conn->task, DID_ABORT);
spin_lock_bh(>taskqueuelock);
continue;
-- 
2.30.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20210302115534.61800-49-sashal%40kernel.org.


[PATCH AUTOSEL 4.4 7/8] scsi: libiscsi: Fix NOP race condition

2020-11-25 Thread Sasha Levin
From: Lee Duncan 

[ Upstream commit fe0a8a95e7134d0b44cd407bc0085b9ba8d8fe31 ]

iSCSI NOPs are sometimes "lost", mistakenly sent to the user-land iscsid
daemon instead of handled in the kernel, as they should be, resulting in a
message from the daemon like:

  iscsid: Got nop in, but kernel supports nop handling.

This can occur because of the new forward- and back-locks, and the fact
that an iSCSI NOP response can occur before processing of the NOP send is
complete. This can result in "conn->ping_task" being NULL in
iscsi_nop_out_rsp(), when the pointer is actually in the process of being
set.

To work around this, we add a new state to the "ping_task" pointer. In
addition to NULL (not assigned) and a pointer (assigned), we add the state
"being set", which is signaled with an INVALID pointer (using "-1").

Link: https://lore.kernel.org/r/20201106193317.16993-1-leeman.dun...@gmail.com
Reviewed-by: Mike Christie 
Signed-off-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 23 +++
 include/scsi/libiscsi.h |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index b4fbcf4cade8f..36e415487fe53 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -570,8 +570,8 @@ static void iscsi_complete_task(struct iscsi_task *task, 
int state)
if (conn->task == task)
conn->task = NULL;
 
-   if (conn->ping_task == task)
-   conn->ping_task = NULL;
+   if (READ_ONCE(conn->ping_task) == task)
+   WRITE_ONCE(conn->ping_task, NULL);
 
/* release get from queueing */
__iscsi_put_task(task);
@@ -780,6 +780,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
   task->conn->session->age);
}
 
+   if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
+   WRITE_ONCE(conn->ping_task, task);
+
if (!ihost->workq) {
if (iscsi_prep_mgmt_task(conn, task))
goto free_task;
@@ -987,8 +990,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 struct iscsi_nopout hdr;
struct iscsi_task *task;
 
-   if (!rhdr && conn->ping_task)
-   return -EINVAL;
+   if (!rhdr) {
+   if (READ_ONCE(conn->ping_task))
+   return -EINVAL;
+   WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK);
+   }
 
memset(, 0, sizeof(struct iscsi_nopout));
hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -1003,11 +1009,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 
task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *), NULL, 0);
if (!task) {
+   if (!rhdr)
+   WRITE_ONCE(conn->ping_task, NULL);
iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
return -EIO;
} else if (!rhdr) {
/* only track our nops */
-   conn->ping_task = task;
conn->last_ping = jiffies;
}
 
@@ -1020,7 +1027,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
struct iscsi_conn *conn = task->conn;
int rc = 0;
 
-   if (conn->ping_task != task) {
+   if (READ_ONCE(conn->ping_task) != task) {
/*
 * If this is not in response to one of our
 * nops then it must be from userspace.
@@ -1960,7 +1967,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
  */
 static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
 {
-   if (conn->ping_task &&
+   if (READ_ONCE(conn->ping_task) &&
time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
   (conn->ping_timeout * HZ), jiffies))
return 1;
@@ -2095,7 +2102,7 @@ static enum blk_eh_timer_return 
iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 * Checking the transport already or nop from a cmd timeout still
 * running
 */
-   if (conn->ping_task) {
+   if (READ_ONCE(conn->ping_task)) {
task->have_checked_conn = true;
rc = BLK_EH_RESET_TIMER;
goto done;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c7b1dc713cdd7..9c7f4aad6db66 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -144,6 +144,9 @@ struct iscsi_task {
void*dd_data;   /* driver/transport data */
 };
 
+/* invalid scsi_task pointer */
+#defineINVALID_SCSI_TASK   (struct iscsi_task *)-1l
+
 static inline int iscsi_task_has_

[PATCH AUTOSEL 4.9 08/10] scsi: libiscsi: Fix NOP race condition

2020-11-25 Thread Sasha Levin
From: Lee Duncan 

[ Upstream commit fe0a8a95e7134d0b44cd407bc0085b9ba8d8fe31 ]

iSCSI NOPs are sometimes "lost", mistakenly sent to the user-land iscsid
daemon instead of handled in the kernel, as they should be, resulting in a
message from the daemon like:

  iscsid: Got nop in, but kernel supports nop handling.

This can occur because of the new forward- and back-locks, and the fact
that an iSCSI NOP response can occur before processing of the NOP send is
complete. This can result in "conn->ping_task" being NULL in
iscsi_nop_out_rsp(), when the pointer is actually in the process of being
set.

To work around this, we add a new state to the "ping_task" pointer. In
addition to NULL (not assigned) and a pointer (assigned), we add the state
"being set", which is signaled with an INVALID pointer (using "-1").

Link: https://lore.kernel.org/r/20201106193317.16993-1-leeman.dun...@gmail.com
Reviewed-by: Mike Christie 
Signed-off-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 23 +++
 include/scsi/libiscsi.h |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index c4336b01db23c..a84b473d4a08b 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -570,8 +570,8 @@ static void iscsi_complete_task(struct iscsi_task *task, 
int state)
if (conn->task == task)
conn->task = NULL;
 
-   if (conn->ping_task == task)
-   conn->ping_task = NULL;
+   if (READ_ONCE(conn->ping_task) == task)
+   WRITE_ONCE(conn->ping_task, NULL);
 
/* release get from queueing */
__iscsi_put_task(task);
@@ -780,6 +780,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
   task->conn->session->age);
}
 
+   if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
+   WRITE_ONCE(conn->ping_task, task);
+
if (!ihost->workq) {
if (iscsi_prep_mgmt_task(conn, task))
goto free_task;
@@ -987,8 +990,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 struct iscsi_nopout hdr;
struct iscsi_task *task;
 
-   if (!rhdr && conn->ping_task)
-   return -EINVAL;
+   if (!rhdr) {
+   if (READ_ONCE(conn->ping_task))
+   return -EINVAL;
+   WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK);
+   }
 
memset(, 0, sizeof(struct iscsi_nopout));
hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -1003,11 +1009,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 
task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *), NULL, 0);
if (!task) {
+   if (!rhdr)
+   WRITE_ONCE(conn->ping_task, NULL);
iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
return -EIO;
} else if (!rhdr) {
/* only track our nops */
-   conn->ping_task = task;
conn->last_ping = jiffies;
}
 
@@ -1020,7 +1027,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
struct iscsi_conn *conn = task->conn;
int rc = 0;
 
-   if (conn->ping_task != task) {
+   if (READ_ONCE(conn->ping_task) != task) {
/*
 * If this is not in response to one of our
 * nops then it must be from userspace.
@@ -1960,7 +1967,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
  */
 static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
 {
-   if (conn->ping_task &&
+   if (READ_ONCE(conn->ping_task) &&
time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
   (conn->ping_timeout * HZ), jiffies))
return 1;
@@ -2095,7 +2102,7 @@ static enum blk_eh_timer_return 
iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 * Checking the transport already or nop from a cmd timeout still
 * running
 */
-   if (conn->ping_task) {
+   if (READ_ONCE(conn->ping_task)) {
task->have_checked_conn = true;
rc = BLK_EH_RESET_TIMER;
goto done;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c7b1dc713cdd7..9c7f4aad6db66 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -144,6 +144,9 @@ struct iscsi_task {
void*dd_data;   /* driver/transport data */
 };
 
+/* invalid scsi_task pointer */
+#defineINVALID_SCSI_TASK   (struct iscsi_task *)-1l
+
 static inline int iscsi_task_has_

[PATCH AUTOSEL 4.14 10/12] scsi: libiscsi: Fix NOP race condition

2020-11-25 Thread Sasha Levin
From: Lee Duncan 

[ Upstream commit fe0a8a95e7134d0b44cd407bc0085b9ba8d8fe31 ]

iSCSI NOPs are sometimes "lost", mistakenly sent to the user-land iscsid
daemon instead of handled in the kernel, as they should be, resulting in a
message from the daemon like:

  iscsid: Got nop in, but kernel supports nop handling.

This can occur because of the new forward- and back-locks, and the fact
that an iSCSI NOP response can occur before processing of the NOP send is
complete. This can result in "conn->ping_task" being NULL in
iscsi_nop_out_rsp(), when the pointer is actually in the process of being
set.

To work around this, we add a new state to the "ping_task" pointer. In
addition to NULL (not assigned) and a pointer (assigned), we add the state
"being set", which is signaled with an INVALID pointer (using "-1").

Link: https://lore.kernel.org/r/20201106193317.16993-1-leeman.dun...@gmail.com
Reviewed-by: Mike Christie 
Signed-off-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 23 +++
 include/scsi/libiscsi.h |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 662df16b07a40..f7e1af90849b3 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -571,8 +571,8 @@ static void iscsi_complete_task(struct iscsi_task *task, 
int state)
if (conn->task == task)
conn->task = NULL;
 
-   if (conn->ping_task == task)
-   conn->ping_task = NULL;
+   if (READ_ONCE(conn->ping_task) == task)
+   WRITE_ONCE(conn->ping_task, NULL);
 
/* release get from queueing */
__iscsi_put_task(task);
@@ -781,6 +781,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
   task->conn->session->age);
}
 
+   if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
+   WRITE_ONCE(conn->ping_task, task);
+
if (!ihost->workq) {
if (iscsi_prep_mgmt_task(conn, task))
goto free_task;
@@ -988,8 +991,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 struct iscsi_nopout hdr;
struct iscsi_task *task;
 
-   if (!rhdr && conn->ping_task)
-   return -EINVAL;
+   if (!rhdr) {
+   if (READ_ONCE(conn->ping_task))
+   return -EINVAL;
+   WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK);
+   }
 
memset(, 0, sizeof(struct iscsi_nopout));
hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -1004,11 +1010,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 
task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *), NULL, 0);
if (!task) {
+   if (!rhdr)
+   WRITE_ONCE(conn->ping_task, NULL);
iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
return -EIO;
} else if (!rhdr) {
/* only track our nops */
-   conn->ping_task = task;
conn->last_ping = jiffies;
}
 
@@ -1021,7 +1028,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
struct iscsi_conn *conn = task->conn;
int rc = 0;
 
-   if (conn->ping_task != task) {
+   if (READ_ONCE(conn->ping_task) != task) {
/*
 * If this is not in response to one of our
 * nops then it must be from userspace.
@@ -1961,7 +1968,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
  */
 static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
 {
-   if (conn->ping_task &&
+   if (READ_ONCE(conn->ping_task) &&
time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
   (conn->ping_timeout * HZ), jiffies))
return 1;
@@ -2096,7 +2103,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct 
scsi_cmnd *sc)
 * Checking the transport already or nop from a cmd timeout still
 * running
 */
-   if (conn->ping_task) {
+   if (READ_ONCE(conn->ping_task)) {
task->have_checked_conn = true;
rc = BLK_EH_RESET_TIMER;
goto done;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c9bd935f4fd1c..1ee0f30ae190b 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -145,6 +145,9 @@ struct iscsi_task {
void*dd_data;   /* driver/transport data */
 };
 
+/* invalid scsi_task pointer */
+#defineINVALID_SCSI_TASK   (struct iscsi_task *)-1l
+
 static inline int iscsi_task_has_

[PATCH AUTOSEL 4.19 12/15] scsi: libiscsi: Fix NOP race condition

2020-11-25 Thread Sasha Levin
From: Lee Duncan 

[ Upstream commit fe0a8a95e7134d0b44cd407bc0085b9ba8d8fe31 ]

iSCSI NOPs are sometimes "lost", mistakenly sent to the user-land iscsid
daemon instead of handled in the kernel, as they should be, resulting in a
message from the daemon like:

  iscsid: Got nop in, but kernel supports nop handling.

This can occur because of the new forward- and back-locks, and the fact
that an iSCSI NOP response can occur before processing of the NOP send is
complete. This can result in "conn->ping_task" being NULL in
iscsi_nop_out_rsp(), when the pointer is actually in the process of being
set.

To work around this, we add a new state to the "ping_task" pointer. In
addition to NULL (not assigned) and a pointer (assigned), we add the state
"being set", which is signaled with an INVALID pointer (using "-1").

Link: https://lore.kernel.org/r/20201106193317.16993-1-leeman.dun...@gmail.com
Reviewed-by: Mike Christie 
Signed-off-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 23 +++
 include/scsi/libiscsi.h |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 7a05c72717666..1c69515e870cb 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -571,8 +571,8 @@ static void iscsi_complete_task(struct iscsi_task *task, 
int state)
if (conn->task == task)
conn->task = NULL;
 
-   if (conn->ping_task == task)
-   conn->ping_task = NULL;
+   if (READ_ONCE(conn->ping_task) == task)
+   WRITE_ONCE(conn->ping_task, NULL);
 
/* release get from queueing */
__iscsi_put_task(task);
@@ -781,6 +781,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
   task->conn->session->age);
}
 
+   if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
+   WRITE_ONCE(conn->ping_task, task);
+
if (!ihost->workq) {
if (iscsi_prep_mgmt_task(conn, task))
goto free_task;
@@ -988,8 +991,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 struct iscsi_nopout hdr;
struct iscsi_task *task;
 
-   if (!rhdr && conn->ping_task)
-   return -EINVAL;
+   if (!rhdr) {
+   if (READ_ONCE(conn->ping_task))
+   return -EINVAL;
+   WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK);
+   }
 
memset(, 0, sizeof(struct iscsi_nopout));
hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -1004,11 +1010,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 
task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *), NULL, 0);
if (!task) {
+   if (!rhdr)
+   WRITE_ONCE(conn->ping_task, NULL);
iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
return -EIO;
} else if (!rhdr) {
/* only track our nops */
-   conn->ping_task = task;
conn->last_ping = jiffies;
}
 
@@ -1021,7 +1028,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
struct iscsi_conn *conn = task->conn;
int rc = 0;
 
-   if (conn->ping_task != task) {
+   if (READ_ONCE(conn->ping_task) != task) {
/*
 * If this is not in response to one of our
 * nops then it must be from userspace.
@@ -1961,7 +1968,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
  */
 static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
 {
-   if (conn->ping_task &&
+   if (READ_ONCE(conn->ping_task) &&
time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
   (conn->ping_timeout * HZ), jiffies))
return 1;
@@ -2096,7 +2103,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct 
scsi_cmnd *sc)
 * Checking the transport already or nop from a cmd timeout still
 * running
 */
-   if (conn->ping_task) {
+   if (READ_ONCE(conn->ping_task)) {
task->have_checked_conn = true;
rc = BLK_EH_RESET_TIMER;
goto done;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c9bd935f4fd1c..1ee0f30ae190b 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -145,6 +145,9 @@ struct iscsi_task {
void*dd_data;   /* driver/transport data */
 };
 
+/* invalid scsi_task pointer */
+#defineINVALID_SCSI_TASK   (struct iscsi_task *)-1l
+
 static inline int iscsi_task_has_

[PATCH AUTOSEL 5.4 19/23] scsi: libiscsi: Fix NOP race condition

2020-11-25 Thread Sasha Levin
From: Lee Duncan 

[ Upstream commit fe0a8a95e7134d0b44cd407bc0085b9ba8d8fe31 ]

iSCSI NOPs are sometimes "lost", mistakenly sent to the user-land iscsid
daemon instead of handled in the kernel, as they should be, resulting in a
message from the daemon like:

  iscsid: Got nop in, but kernel supports nop handling.

This can occur because of the new forward- and back-locks, and the fact
that an iSCSI NOP response can occur before processing of the NOP send is
complete. This can result in "conn->ping_task" being NULL in
iscsi_nop_out_rsp(), when the pointer is actually in the process of being
set.

To work around this, we add a new state to the "ping_task" pointer. In
addition to NULL (not assigned) and a pointer (assigned), we add the state
"being set", which is signaled with an INVALID pointer (using "-1").

Link: https://lore.kernel.org/r/20201106193317.16993-1-leeman.dun...@gmail.com
Reviewed-by: Mike Christie 
Signed-off-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 23 +++
 include/scsi/libiscsi.h |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 70b99c0e2e678..f954be3d5ee22 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -533,8 +533,8 @@ static void iscsi_complete_task(struct iscsi_task *task, 
int state)
if (conn->task == task)
conn->task = NULL;
 
-   if (conn->ping_task == task)
-   conn->ping_task = NULL;
+   if (READ_ONCE(conn->ping_task) == task)
+   WRITE_ONCE(conn->ping_task, NULL);
 
/* release get from queueing */
__iscsi_put_task(task);
@@ -738,6 +738,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
   task->conn->session->age);
}
 
+   if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
+   WRITE_ONCE(conn->ping_task, task);
+
if (!ihost->workq) {
if (iscsi_prep_mgmt_task(conn, task))
goto free_task;
@@ -941,8 +944,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 struct iscsi_nopout hdr;
struct iscsi_task *task;
 
-   if (!rhdr && conn->ping_task)
-   return -EINVAL;
+   if (!rhdr) {
+   if (READ_ONCE(conn->ping_task))
+   return -EINVAL;
+   WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK);
+   }
 
memset(, 0, sizeof(struct iscsi_nopout));
hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -957,11 +963,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 
task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *), NULL, 0);
if (!task) {
+   if (!rhdr)
+   WRITE_ONCE(conn->ping_task, NULL);
iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
return -EIO;
} else if (!rhdr) {
/* only track our nops */
-   conn->ping_task = task;
conn->last_ping = jiffies;
}
 
@@ -984,7 +991,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
struct iscsi_conn *conn = task->conn;
int rc = 0;
 
-   if (conn->ping_task != task) {
+   if (READ_ONCE(conn->ping_task) != task) {
/*
 * If this is not in response to one of our
 * nops then it must be from userspace.
@@ -1923,7 +1930,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
  */
 static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
 {
-   if (conn->ping_task &&
+   if (READ_ONCE(conn->ping_task) &&
time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
   (conn->ping_timeout * HZ), jiffies))
return 1;
@@ -2058,7 +2065,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct 
scsi_cmnd *sc)
 * Checking the transport already or nop from a cmd timeout still
 * running
 */
-   if (conn->ping_task) {
+   if (READ_ONCE(conn->ping_task)) {
task->have_checked_conn = true;
rc = BLK_EH_RESET_TIMER;
goto done;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c25fb86ffae95..b3bbd10eb3f07 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -132,6 +132,9 @@ struct iscsi_task {
void*dd_data;   /* driver/transport data */
 };
 
+/* invalid scsi_task pointer */
+#defineINVALID_SCSI_TASK   (struct iscsi_task *)-1l
+
 static inline int iscsi_task_has_

[PATCH AUTOSEL 5.9 26/33] scsi: libiscsi: Fix NOP race condition

2020-11-25 Thread Sasha Levin
From: Lee Duncan 

[ Upstream commit fe0a8a95e7134d0b44cd407bc0085b9ba8d8fe31 ]

iSCSI NOPs are sometimes "lost", mistakenly sent to the user-land iscsid
daemon instead of handled in the kernel, as they should be, resulting in a
message from the daemon like:

  iscsid: Got nop in, but kernel supports nop handling.

This can occur because of the new forward- and back-locks, and the fact
that an iSCSI NOP response can occur before processing of the NOP send is
complete. This can result in "conn->ping_task" being NULL in
iscsi_nop_out_rsp(), when the pointer is actually in the process of being
set.

To work around this, we add a new state to the "ping_task" pointer. In
addition to NULL (not assigned) and a pointer (assigned), we add the state
"being set", which is signaled with an INVALID pointer (using "-1").

Link: https://lore.kernel.org/r/20201106193317.16993-1-leeman.dun...@gmail.com
Reviewed-by: Mike Christie 
Signed-off-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/libiscsi.c | 23 +++
 include/scsi/libiscsi.h |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 1e9c3171fa9f4..f9314f1393fbd 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -533,8 +533,8 @@ static void iscsi_complete_task(struct iscsi_task *task, 
int state)
if (conn->task == task)
conn->task = NULL;
 
-   if (conn->ping_task == task)
-   conn->ping_task = NULL;
+   if (READ_ONCE(conn->ping_task) == task)
+   WRITE_ONCE(conn->ping_task, NULL);
 
/* release get from queueing */
__iscsi_put_task(task);
@@ -738,6 +738,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct 
iscsi_hdr *hdr,
   task->conn->session->age);
}
 
+   if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
+   WRITE_ONCE(conn->ping_task, task);
+
if (!ihost->workq) {
if (iscsi_prep_mgmt_task(conn, task))
goto free_task;
@@ -941,8 +944,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 struct iscsi_nopout hdr;
struct iscsi_task *task;
 
-   if (!rhdr && conn->ping_task)
-   return -EINVAL;
+   if (!rhdr) {
+   if (READ_ONCE(conn->ping_task))
+   return -EINVAL;
+   WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK);
+   }
 
memset(, 0, sizeof(struct iscsi_nopout));
hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -957,11 +963,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, 
struct iscsi_nopin *rhdr)
 
task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *), NULL, 0);
if (!task) {
+   if (!rhdr)
+   WRITE_ONCE(conn->ping_task, NULL);
iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
return -EIO;
} else if (!rhdr) {
/* only track our nops */
-   conn->ping_task = task;
conn->last_ping = jiffies;
}
 
@@ -984,7 +991,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
struct iscsi_conn *conn = task->conn;
int rc = 0;
 
-   if (conn->ping_task != task) {
+   if (READ_ONCE(conn->ping_task) != task) {
/*
 * If this is not in response to one of our
 * nops then it must be from userspace.
@@ -1923,7 +1930,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
  */
 static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
 {
-   if (conn->ping_task &&
+   if (READ_ONCE(conn->ping_task) &&
time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
   (conn->ping_timeout * HZ), jiffies))
return 1;
@@ -2058,7 +2065,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct 
scsi_cmnd *sc)
 * Checking the transport already or nop from a cmd timeout still
 * running
 */
-   if (conn->ping_task) {
+   if (READ_ONCE(conn->ping_task)) {
task->have_checked_conn = true;
rc = BLK_EH_RESET_TIMER;
goto done;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c25fb86ffae95..b3bbd10eb3f07 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -132,6 +132,9 @@ struct iscsi_task {
void*dd_data;   /* driver/transport data */
 };
 
+/* invalid scsi_task pointer */
+#defineINVALID_SCSI_TASK   (struct iscsi_task *)-1l
+
 static inline int iscsi_task_has_

[PATCH AUTOSEL 4.4 19/22] scsi: iscsi: Do not put host in iscsi_set_flashnode_param()

2020-08-21 Thread Sasha Levin
From: Jing Xiangfeng 

[ Upstream commit 68e12e5f61354eb42cfffbc20a693153fc39738e ]

If scsi_host_lookup() fails we will jump to put_host which may cause a
panic. Jump to exit_set_fnode instead.

Link: https://lore.kernel.org/r/20200615081226.183068-1-jingxiangf...@huawei.com
Reviewed-by: Mike Christie 
Signed-off-by: Jing Xiangfeng 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index de10b461ec7ef..4903640316480 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3192,7 +3192,7 @@ static int iscsi_set_flashnode_param(struct 
iscsi_transport *transport,
pr_err("%s could not find host no %u\n",
   __func__, ev->u.set_flashnode.host_no);
err = -ENODEV;
-   goto put_host;
+   goto exit_set_fnode;
}
 
idx = ev->u.set_flashnode.flashnode_idx;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200821162014.349506-19-sashal%40kernel.org.


[PATCH AUTOSEL 4.9 23/26] scsi: iscsi: Do not put host in iscsi_set_flashnode_param()

2020-08-21 Thread Sasha Levin
From: Jing Xiangfeng 

[ Upstream commit 68e12e5f61354eb42cfffbc20a693153fc39738e ]

If scsi_host_lookup() fails we will jump to put_host which may cause a
panic. Jump to exit_set_fnode instead.

Link: https://lore.kernel.org/r/20200615081226.183068-1-jingxiangf...@huawei.com
Reviewed-by: Mike Christie 
Signed-off-by: Jing Xiangfeng 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 42b97f1196232..c2bce3f6eaace 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3191,7 +3191,7 @@ static int iscsi_set_flashnode_param(struct 
iscsi_transport *transport,
pr_err("%s could not find host no %u\n",
   __func__, ev->u.set_flashnode.host_no);
err = -ENODEV;
-   goto put_host;
+   goto exit_set_fnode;
}
 
idx = ev->u.set_flashnode.flashnode_idx;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200821161938.349246-23-sashal%40kernel.org.


[PATCH AUTOSEL 4.14 27/30] scsi: iscsi: Do not put host in iscsi_set_flashnode_param()

2020-08-21 Thread Sasha Levin
From: Jing Xiangfeng 

[ Upstream commit 68e12e5f61354eb42cfffbc20a693153fc39738e ]

If scsi_host_lookup() fails we will jump to put_host which may cause a
panic. Jump to exit_set_fnode instead.

Link: https://lore.kernel.org/r/20200615081226.183068-1-jingxiangf...@huawei.com
Reviewed-by: Mike Christie 
Signed-off-by: Jing Xiangfeng 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 9589015234693..c3170500a1a1d 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3172,7 +3172,7 @@ static int iscsi_set_flashnode_param(struct 
iscsi_transport *transport,
pr_err("%s could not find host no %u\n",
   __func__, ev->u.set_flashnode.host_no);
err = -ENODEV;
-   goto put_host;
+   goto exit_set_fnode;
}
 
idx = ev->u.set_flashnode.flashnode_idx;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200821161857.348955-27-sashal%40kernel.org.


[PATCH AUTOSEL 4.19 35/38] scsi: iscsi: Do not put host in iscsi_set_flashnode_param()

2020-08-21 Thread Sasha Levin
From: Jing Xiangfeng 

[ Upstream commit 68e12e5f61354eb42cfffbc20a693153fc39738e ]

If scsi_host_lookup() fails we will jump to put_host which may cause a
panic. Jump to exit_set_fnode instead.

Link: https://lore.kernel.org/r/20200615081226.183068-1-jingxiangf...@huawei.com
Reviewed-by: Mike Christie 
Signed-off-by: Jing Xiangfeng 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 04d095488c764..6983473011980 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3172,7 +3172,7 @@ static int iscsi_set_flashnode_param(struct 
iscsi_transport *transport,
pr_err("%s could not find host no %u\n",
   __func__, ev->u.set_flashnode.host_no);
err = -ENODEV;
-   goto put_host;
+   goto exit_set_fnode;
}
 
idx = ev->u.set_flashnode.flashnode_idx;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200821161807.348600-35-sashal%40kernel.org.


[PATCH AUTOSEL 5.4 42/48] scsi: iscsi: Do not put host in iscsi_set_flashnode_param()

2020-08-21 Thread Sasha Levin
From: Jing Xiangfeng 

[ Upstream commit 68e12e5f61354eb42cfffbc20a693153fc39738e ]

If scsi_host_lookup() fails we will jump to put_host which may cause a
panic. Jump to exit_set_fnode instead.

Link: https://lore.kernel.org/r/20200615081226.183068-1-jingxiangf...@huawei.com
Reviewed-by: Mike Christie 
Signed-off-by: Jing Xiangfeng 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index a5c78b38d3022..dbad926e8f87f 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3174,7 +3174,7 @@ static int iscsi_set_flashnode_param(struct 
iscsi_transport *transport,
pr_err("%s could not find host no %u\n",
   __func__, ev->u.set_flashnode.host_no);
err = -ENODEV;
-   goto put_host;
+   goto exit_set_fnode;
}
 
idx = ev->u.set_flashnode.flashnode_idx;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200821161704.348164-42-sashal%40kernel.org.


[PATCH AUTOSEL 5.8 54/62] scsi: iscsi: Do not put host in iscsi_set_flashnode_param()

2020-08-21 Thread Sasha Levin
From: Jing Xiangfeng 

[ Upstream commit 68e12e5f61354eb42cfffbc20a693153fc39738e ]

If scsi_host_lookup() fails we will jump to put_host which may cause a
panic. Jump to exit_set_fnode instead.

Link: https://lore.kernel.org/r/20200615081226.183068-1-jingxiangf...@huawei.com
Reviewed-by: Mike Christie 
Signed-off-by: Jing Xiangfeng 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 7ae5024e78243..df07ecd94793a 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -3291,7 +3291,7 @@ static int iscsi_set_flashnode_param(struct 
iscsi_transport *transport,
pr_err("%s could not find host no %u\n",
   __func__, ev->u.set_flashnode.host_no);
err = -ENODEV;
-   goto put_host;
+   goto exit_set_fnode;
}
 
idx = ev->u.set_flashnode.flashnode_idx;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200821161423.347071-54-sashal%40kernel.org.


[PATCH AUTOSEL 4.4 55/60] scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj

2020-06-17 Thread Sasha Levin
From: Qiushi Wu 

[ Upstream commit 0267ffce562c8bbf9b57ebe0e38445ad04972890 ]

kobject_init_and_add() takes reference even when it fails. If this
function returns an error, kobject_put() must be called to properly
clean up the memory associated with the object.

Link: https://lore.kernel.org/r/20200528201353.14849-1-wu000...@umn.edu
Reviewed-by: Lee Duncan 
Signed-off-by: Qiushi Wu 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_boot_sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index 680bf6f0ce76..476f46aad54c 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -319,7 +319,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
boot_kobj->kobj.kset = boot_kset->kset;
if (kobject_init_and_add(_kobj->kobj, _boot_ktype,
 NULL, name, index)) {
-   kfree(boot_kobj);
+   kobject_put(_kobj->kobj);
return NULL;
}
boot_kobj->data = data;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200618013004.610532-55-sashal%40kernel.org.


[PATCH AUTOSEL 4.9 72/80] scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj

2020-06-17 Thread Sasha Levin
From: Qiushi Wu 

[ Upstream commit 0267ffce562c8bbf9b57ebe0e38445ad04972890 ]

kobject_init_and_add() takes reference even when it fails. If this
function returns an error, kobject_put() must be called to properly
clean up the memory associated with the object.

Link: https://lore.kernel.org/r/20200528201353.14849-1-wu000...@umn.edu
Reviewed-by: Lee Duncan 
Signed-off-by: Qiushi Wu 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_boot_sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index d453667612f8..15d64f96e623 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -360,7 +360,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
boot_kobj->kobj.kset = boot_kset->kset;
if (kobject_init_and_add(_kobj->kobj, _boot_ktype,
 NULL, name, index)) {
-   kfree(boot_kobj);
+   kobject_put(_kobj->kobj);
return NULL;
}
boot_kobj->data = data;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200618012819.609778-72-sashal%40kernel.org.


[PATCH AUTOSEL 4.14 091/108] scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj

2020-06-17 Thread Sasha Levin
From: Qiushi Wu 

[ Upstream commit 0267ffce562c8bbf9b57ebe0e38445ad04972890 ]

kobject_init_and_add() takes reference even when it fails. If this
function returns an error, kobject_put() must be called to properly
clean up the memory associated with the object.

Link: https://lore.kernel.org/r/20200528201353.14849-1-wu000...@umn.edu
Reviewed-by: Lee Duncan 
Signed-off-by: Qiushi Wu 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_boot_sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index d453667612f8..15d64f96e623 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -360,7 +360,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
boot_kobj->kobj.kset = boot_kset->kset;
if (kobject_init_and_add(_kobj->kobj, _boot_ktype,
 NULL, name, index)) {
-   kfree(boot_kobj);
+   kobject_put(_kobj->kobj);
return NULL;
}
boot_kobj->data = data;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200618012600.608744-91-sashal%40kernel.org.


[PATCH AUTOSEL 4.19 139/172] scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj

2020-06-17 Thread Sasha Levin
From: Qiushi Wu 

[ Upstream commit 0267ffce562c8bbf9b57ebe0e38445ad04972890 ]

kobject_init_and_add() takes reference even when it fails. If this
function returns an error, kobject_put() must be called to properly
clean up the memory associated with the object.

Link: https://lore.kernel.org/r/20200528201353.14849-1-wu000...@umn.edu
Reviewed-by: Lee Duncan 
Signed-off-by: Qiushi Wu 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_boot_sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index d453667612f8..15d64f96e623 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -360,7 +360,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
boot_kobj->kobj.kset = boot_kset->kset;
if (kobject_init_and_add(_kobj->kobj, _boot_ktype,
 NULL, name, index)) {
-   kfree(boot_kobj);
+   kobject_put(_kobj->kobj);
return NULL;
}
boot_kobj->data = data;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200618012218.607130-139-sashal%40kernel.org.


[PATCH AUTOSEL 5.4 220/266] scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj

2020-06-17 Thread Sasha Levin
From: Qiushi Wu 

[ Upstream commit 0267ffce562c8bbf9b57ebe0e38445ad04972890 ]

kobject_init_and_add() takes reference even when it fails. If this
function returns an error, kobject_put() must be called to properly
clean up the memory associated with the object.

Link: https://lore.kernel.org/r/20200528201353.14849-1-wu000...@umn.edu
Reviewed-by: Lee Duncan 
Signed-off-by: Qiushi Wu 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_boot_sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index e4857b728033..a64abe38db2d 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -352,7 +352,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
boot_kobj->kobj.kset = boot_kset->kset;
if (kobject_init_and_add(_kobj->kobj, _boot_ktype,
 NULL, name, index)) {
-   kfree(boot_kobj);
+   kobject_put(_kobj->kobj);
return NULL;
}
boot_kobj->data = data;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200618011631.604574-220-sashal%40kernel.org.


[PATCH AUTOSEL 5.7 320/388] scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj

2020-06-17 Thread Sasha Levin
From: Qiushi Wu 

[ Upstream commit 0267ffce562c8bbf9b57ebe0e38445ad04972890 ]

kobject_init_and_add() takes reference even when it fails. If this
function returns an error, kobject_put() must be called to properly
clean up the memory associated with the object.

Link: https://lore.kernel.org/r/20200528201353.14849-1-wu000...@umn.edu
Reviewed-by: Lee Duncan 
Signed-off-by: Qiushi Wu 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_boot_sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c
index e4857b728033..a64abe38db2d 100644
--- a/drivers/scsi/iscsi_boot_sysfs.c
+++ b/drivers/scsi/iscsi_boot_sysfs.c
@@ -352,7 +352,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset,
boot_kobj->kobj.kset = boot_kset->kset;
if (kobject_init_and_add(_kobj->kobj, _boot_ktype,
 NULL, name, index)) {
-   kfree(boot_kobj);
+   kobject_put(_kobj->kobj);
return NULL;
}
boot_kobj->data = data;
-- 
2.25.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200618010805.600873-320-sashal%40kernel.org.


[PATCH AUTOSEL 5.7 285/388] scsi: iscsi: Fix deadlock on recovery path during GFP_IO reclaim

2020-06-17 Thread Sasha Levin
by: Gabriel Krisman Bertazi 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 64 +
 1 file changed, 47 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index b2a803c51288..ea6d498fa923 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1616,6 +1616,12 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
 static struct sock *nls;
 static DEFINE_MUTEX(rx_queue_mutex);
 
+/*
+ * conn_mutex protects the {start,bind,stop,destroy}_conn from racing
+ * against the kernel stop_connection recovery mechanism
+ */
+static DEFINE_MUTEX(conn_mutex);
+
 static LIST_HEAD(sesslist);
 static LIST_HEAD(sessdestroylist);
 static DEFINE_SPINLOCK(sesslock);
@@ -2445,6 +2451,32 @@ int iscsi_offload_mesg(struct Scsi_Host *shost,
 }
 EXPORT_SYMBOL_GPL(iscsi_offload_mesg);
 
+/*
+ * This can be called without the rx_queue_mutex, if invoked by the kernel
+ * stop work. But, in that case, it is guaranteed not to race with
+ * iscsi_destroy by conn_mutex.
+ */
+static void iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag)
+{
+   /*
+* It is important that this path doesn't rely on
+* rx_queue_mutex, otherwise, a thread doing allocation on a
+* start_session/start_connection could sleep waiting on a
+* writeback to a failed iscsi device, that cannot be recovered
+* because the lock is held.  If we don't hold it here, the
+* kernel stop_conn_work_fn has a chance to stop the broken
+* session and resolve the allocation.
+*
+* Still, the user invoked .stop_conn() needs to be serialized
+* with stop_conn_work_fn by a private mutex.  Not pretty, but
+* it works.
+*/
+   mutex_lock(_mutex);
+   conn->transport->stop_conn(conn, flag);
+   mutex_unlock(_mutex);
+
+}
+
 static void stop_conn_work_fn(struct work_struct *work)
 {
struct iscsi_cls_conn *conn, *tmp;
@@ -2463,30 +2495,17 @@ static void stop_conn_work_fn(struct work_struct *work)
uint32_t sid = iscsi_conn_get_sid(conn);
struct iscsi_cls_session *session;
 
-   mutex_lock(_queue_mutex);
-
session = iscsi_session_lookup(sid);
if (session) {
if (system_state != SYSTEM_RUNNING) {
session->recovery_tmo = 0;
-   conn->transport->stop_conn(conn,
-  STOP_CONN_TERM);
+   iscsi_if_stop_conn(conn, STOP_CONN_TERM);
} else {
-   conn->transport->stop_conn(conn,
-  STOP_CONN_RECOVER);
+   iscsi_if_stop_conn(conn, STOP_CONN_RECOVER);
}
}
 
list_del_init(>conn_list_err);
-
-   mutex_unlock(_queue_mutex);
-
-   /* we don't want to hold rx_queue_mutex for too long,
-* for instance if many conns failed at the same time,
-* since this stall other iscsi maintenance operations.
-* Give other users a chance to proceed.
-*/
-   cond_resched();
}
 }
 
@@ -2846,8 +2865,11 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, 
struct iscsi_uevent *ev
spin_unlock_irqrestore(, flags);
 
ISCSI_DBG_TRANS_CONN(conn, "Destroying transport conn\n");
+
+   mutex_lock(_mutex);
if (transport->destroy_conn)
transport->destroy_conn(conn);
+   mutex_unlock(_mutex);
 
return 0;
 }
@@ -3689,9 +3711,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
break;
}
 
+   mutex_lock(_mutex);
ev->r.retcode = transport->bind_conn(session, conn,
ev->u.b_conn.transport_eph,
ev->u.b_conn.is_leading);
+   mutex_unlock(_mutex);
+
if (ev->r.retcode || !transport->ep_connect)
break;
 
@@ -3713,9 +3738,11 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
case ISCSI_UEVENT_START_CONN:
conn = iscsi_conn_lookup(ev->u.start_conn.sid, 
ev->u.start_conn.cid);
if (conn) {
+   mutex_lock(_mutex);
ev->r.retcode = transport->start_conn(conn);
if (!ev->r.retcode)
conn->state = ISCSI_CONN_UP;
+   mutex_unlock(_mutex);
  

[PATCH AUTOSEL 4.4 07/19] scsi: iscsi: Report unbind session event when the target has been removed

2020-04-18 Thread Sasha Levin
From: Wu Bo 

[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]

If the daemon is restarted or crashes while logging out of a session, the
unbind session event sent by the kernel is not processed and is lost.  When
the daemon starts again, the session can't be unbound because the daemon is
waiting for the event message. However, the kernel has already logged out
and the event will not be resent.

When iscsid restart is complete, logout session reports error:

Logging out of session [sid: 6, target: iqn.x, portal: xx.xx.xx.xx,3260]
iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.x, 
portal: xx.xx.xx.xx,3260].
iscsiadm: initiator reported error (9 - internal error)
iscsiadm: Could not logout of all requested sessions

Make sure the unbind event is emitted.

[mkp: commit desc and applied by hand since patch was mangled]

Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340...@huawei.com
Reviewed-by: Lee Duncan 
Signed-off-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 20cf01d6ded7e..de10b461ec7ef 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2014,7 +2014,7 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
if (session->target_id == ISCSI_MAX_TARGET) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   return;
+   goto unbind_session_exit;
}
 
target_id = session->target_id;
@@ -2026,6 +2026,8 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
ida_simple_remove(_sess_ida, target_id);
 
scsi_remove_target(>dev);
+
+unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
 }
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200418144436.10818-7-sashal%40kernel.org.


[PATCH AUTOSEL 4.9 08/23] scsi: iscsi: Report unbind session event when the target has been removed

2020-04-18 Thread Sasha Levin
From: Wu Bo 

[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]

If the daemon is restarted or crashes while logging out of a session, the
unbind session event sent by the kernel is not processed and is lost.  When
the daemon starts again, the session can't be unbound because the daemon is
waiting for the event message. However, the kernel has already logged out
and the event will not be resent.

When iscsid restart is complete, logout session reports error:

Logging out of session [sid: 6, target: iqn.x, portal: xx.xx.xx.xx,3260]
iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.x, 
portal: xx.xx.xx.xx,3260].
iscsiadm: initiator reported error (9 - internal error)
iscsiadm: Could not logout of all requested sessions

Make sure the unbind event is emitted.

[mkp: commit desc and applied by hand since patch was mangled]

Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340...@huawei.com
Reviewed-by: Lee Duncan 
Signed-off-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index fff9c4d0f7c80..42b97f1196232 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2016,7 +2016,7 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
if (session->target_id == ISCSI_MAX_TARGET) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   return;
+   goto unbind_session_exit;
}
 
target_id = session->target_id;
@@ -2028,6 +2028,8 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
ida_simple_remove(_sess_ida, target_id);
 
scsi_remove_target(>dev);
+
+unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
 }
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200418144405.10565-8-sashal%40kernel.org.


[PATCH AUTOSEL 4.14 09/28] scsi: iscsi: Report unbind session event when the target has been removed

2020-04-18 Thread Sasha Levin
From: Wu Bo 

[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]

If the daemon is restarted or crashes while logging out of a session, the
unbind session event sent by the kernel is not processed and is lost.  When
the daemon starts again, the session can't be unbound because the daemon is
waiting for the event message. However, the kernel has already logged out
and the event will not be resent.

When iscsid restart is complete, logout session reports error:

Logging out of session [sid: 6, target: iqn.x, portal: xx.xx.xx.xx,3260]
iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.x, 
portal: xx.xx.xx.xx,3260].
iscsiadm: initiator reported error (9 - internal error)
iscsiadm: Could not logout of all requested sessions

Make sure the unbind event is emitted.

[mkp: commit desc and applied by hand since patch was mangled]

Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340...@huawei.com
Reviewed-by: Lee Duncan 
Signed-off-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index aecb563a2b4e3..9589015234693 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2010,7 +2010,7 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
if (session->target_id == ISCSI_MAX_TARGET) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   return;
+   goto unbind_session_exit;
}
 
target_id = session->target_id;
@@ -2022,6 +2022,8 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
ida_simple_remove(_sess_ida, target_id);
 
scsi_remove_target(>dev);
+
+unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
 }
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200418144328.10265-9-sashal%40kernel.org.


[PATCH AUTOSEL 4.19 11/47] scsi: iscsi: Report unbind session event when the target has been removed

2020-04-18 Thread Sasha Levin
From: Wu Bo 

[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]

If the daemon is restarted or crashes while logging out of a session, the
unbind session event sent by the kernel is not processed and is lost.  When
the daemon starts again, the session can't be unbound because the daemon is
waiting for the event message. However, the kernel has already logged out
and the event will not be resent.

When iscsid restart is complete, logout session reports error:

Logging out of session [sid: 6, target: iqn.x, portal: xx.xx.xx.xx,3260]
iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.x, 
portal: xx.xx.xx.xx,3260].
iscsiadm: initiator reported error (9 - internal error)
iscsiadm: Could not logout of all requested sessions

Make sure the unbind event is emitted.

[mkp: commit desc and applied by hand since patch was mangled]

Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340...@huawei.com
Reviewed-by: Lee Duncan 
Signed-off-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index c0fb9e7890807..04d095488c764 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2010,7 +2010,7 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
if (session->target_id == ISCSI_MAX_TARGET) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   return;
+   goto unbind_session_exit;
}
 
target_id = session->target_id;
@@ -2022,6 +2022,8 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
ida_simple_remove(_sess_ida, target_id);
 
scsi_remove_target(>dev);
+
+unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
 }
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200418144227.9802-11-sashal%40kernel.org.


[PATCH AUTOSEL 5.4 17/78] scsi: iscsi: Report unbind session event when the target has been removed

2020-04-18 Thread Sasha Levin
From: Wu Bo 

[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]

If the daemon is restarted or crashes while logging out of a session, the
unbind session event sent by the kernel is not processed and is lost.  When
the daemon starts again, the session can't be unbound because the daemon is
waiting for the event message. However, the kernel has already logged out
and the event will not be resent.

When iscsid restart is complete, logout session reports error:

Logging out of session [sid: 6, target: iqn.x, portal: xx.xx.xx.xx,3260]
iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.x, 
portal: xx.xx.xx.xx,3260].
iscsiadm: initiator reported error (9 - internal error)
iscsiadm: Could not logout of all requested sessions

Make sure the unbind event is emitted.

[mkp: commit desc and applied by hand since patch was mangled]

Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340...@huawei.com
Reviewed-by: Lee Duncan 
Signed-off-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 271afea654e2b..a5c78b38d3022 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2012,7 +2012,7 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
if (session->target_id == ISCSI_MAX_TARGET) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   return;
+   goto unbind_session_exit;
}
 
target_id = session->target_id;
@@ -2024,6 +2024,8 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
ida_simple_remove(_sess_ida, target_id);
 
scsi_remove_target(>dev);
+
+unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
 }
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200418144047.9013-17-sashal%40kernel.org.


[PATCH AUTOSEL 5.5 18/75] scsi: iscsi: Report unbind session event when the target has been removed

2020-04-18 Thread Sasha Levin
From: Wu Bo 

[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]

If the daemon is restarted or crashes while logging out of a session, the
unbind session event sent by the kernel is not processed and is lost.  When
the daemon starts again, the session can't be unbound because the daemon is
waiting for the event message. However, the kernel has already logged out
and the event will not be resent.

When iscsid restart is complete, logout session reports error:

Logging out of session [sid: 6, target: iqn.x, portal: xx.xx.xx.xx,3260]
iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.x, 
portal: xx.xx.xx.xx,3260].
iscsiadm: initiator reported error (9 - internal error)
iscsiadm: Could not logout of all requested sessions

Make sure the unbind event is emitted.

[mkp: commit desc and applied by hand since patch was mangled]

Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340...@huawei.com
Reviewed-by: Lee Duncan 
Signed-off-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 271afea654e2b..a5c78b38d3022 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2012,7 +2012,7 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
if (session->target_id == ISCSI_MAX_TARGET) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   return;
+   goto unbind_session_exit;
}
 
target_id = session->target_id;
@@ -2024,6 +2024,8 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
ida_simple_remove(_sess_ida, target_id);
 
scsi_remove_target(>dev);
+
+unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
 }
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200418140910.8280-18-sashal%40kernel.org.


[PATCH AUTOSEL 5.6 20/73] scsi: iscsi: Report unbind session event when the target has been removed

2020-04-18 Thread Sasha Levin
From: Wu Bo 

[ Upstream commit 13e60d3ba287d96eeaf1deaadba51f71578119a3 ]

If the daemon is restarted or crashes while logging out of a session, the
unbind session event sent by the kernel is not processed and is lost.  When
the daemon starts again, the session can't be unbound because the daemon is
waiting for the event message. However, the kernel has already logged out
and the event will not be resent.

When iscsid restart is complete, logout session reports error:

Logging out of session [sid: 6, target: iqn.x, portal: xx.xx.xx.xx,3260]
iscsiadm: Could not logout of [sid: 6, target: iscsiadm -m node iqn.x, 
portal: xx.xx.xx.xx,3260].
iscsiadm: initiator reported error (9 - internal error)
iscsiadm: Could not logout of all requested sessions

Make sure the unbind event is emitted.

[mkp: commit desc and applied by hand since patch was mangled]

Link: https://lore.kernel.org/r/4eab1771-2cb3-8e79-b31c-923652340...@huawei.com
Reviewed-by: Lee Duncan 
Signed-off-by: Wu Bo 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index dfc726fa34e34..443ace019852f 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2012,7 +2012,7 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
if (session->target_id == ISCSI_MAX_TARGET) {
spin_unlock_irqrestore(>lock, flags);
mutex_unlock(>mutex);
-   return;
+   goto unbind_session_exit;
}
 
target_id = session->target_id;
@@ -2024,6 +2024,8 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
ida_simple_remove(_sess_ida, target_id);
 
scsi_remove_target(>dev);
+
+unbind_session_exit:
iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
 }
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20200418134815.6519-20-sashal%40kernel.org.


[PATCH AUTOSEL 4.4 073/100] scsi: iscsi: Don't destroy session if there are outstanding connections

2020-02-14 Thread Sasha Levin
From: Nick Black 

[ Upstream commit 54155ed4199c7aa3fd20866648024ab63c96d579 ]

A faulty userspace that calls destroy_session() before destroying the
connections can trigger the failure.  This patch prevents the issue by
refusing to destroy the session if there are outstanding connections.

[ cut here ]
kernel BUG at mm/slub.c:306!
invalid opcode:  [#1] SMP PTI
CPU: 1 PID: 1224 Comm: iscsid Not tainted 5.4.0-rc2.iscsi+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
RIP: 0010:__slab_free+0x181/0x350
[...]
[ 1209.686056] RSP: 0018:a93d4074fae0 EFLAGS: 00010246
[ 1209.686694] RAX: 934efa5ad800 RBX: 801a RCX: 934efa5ad800
[ 1209.687651] RDX: 934efa5ad800 RSI: eb4041e96b00 RDI: 934efd402c40
[ 1209.688582] RBP: a93d4074fb80 R08: 0001 R09: bb5dfa26
[ 1209.689425] R10: 934efa5ad800 R11: 0001 R12: eb4041e96b00
[ 1209.690285] R13: 934efa5ad800 R14: 934efd402c40 R15: 
[ 1209.691213] FS:  7f7945dfb540() GS:934efda8() 
knlGS:
[ 1209.692316] CS:  0010 DS:  ES:  CR0: 80050033
[ 1209.693013] CR2: 55877fd3da80 CR3: 77384000 CR4: 06e0
[ 1209.693897] DR0:  DR1:  DR2: 
[ 1209.694773] DR3:  DR6: fffe0ff0 DR7: 0400
[ 1209.695631] Call Trace:
[ 1209.695957]  ? __wake_up_common_lock+0x8a/0xc0
[ 1209.696712]  iscsi_pool_free+0x26/0x40
[ 1209.697263]  iscsi_session_teardown+0x2f/0xf0
[ 1209.698117]  iscsi_sw_tcp_session_destroy+0x45/0x60
[ 1209.698831]  iscsi_if_rx+0xd88/0x14e0
[ 1209.699370]  netlink_unicast+0x16f/0x200
[ 1209.699932]  netlink_sendmsg+0x21a/0x3e0
[ 1209.700446]  sock_sendmsg+0x4f/0x60
[ 1209.700902]  ___sys_sendmsg+0x2ae/0x320
[ 1209.701451]  ? cp_new_stat+0x150/0x180
[ 1209.701922]  __sys_sendmsg+0x59/0xa0
[ 1209.702357]  do_syscall_64+0x52/0x160
[ 1209.702812]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1209.703419] RIP: 0033:0x7f7946433914
[...]
[ 1209.706084] RSP: 002b:7fffb99f2378 EFLAGS: 0246 ORIG_RAX: 
002e
[ 1209.706994] RAX: ffda RBX: 55bc869eac20 RCX: 7f7946433914
[ 1209.708082] RDX:  RSI: 7fffb99f2390 RDI: 0005
[ 1209.709120] RBP: 7fffb99f2390 R08: 55bc84fe9320 R09: 7fffb99f1f07
[ 1209.710110] R10:  R11: 0246 R12: 0038
[ 1209.711085] R13: 55bc8502306e R14:  R15: 
 Modules linked in:
 ---[ end trace a2d933ede7f730d8 ]---

Link: https://lore.kernel.org/r/20191226203148.2172200-1-kris...@collabora.com
Signed-off-by: Nick Black 
Co-developed-by: Salman Qazi 
Signed-off-by: Salman Qazi 
Co-developed-by: Junho Ryu 
Signed-off-by: Junho Ryu 
Co-developed-by: Khazhismel Kumykov 
Signed-off-by: Khazhismel Kumykov 
Co-developed-by: Gabriel Krisman Bertazi 
Signed-off-by: Gabriel Krisman Bertazi 
Reviewed-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c|  4 
 drivers/scsi/scsi_transport_iscsi.c | 26 +++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index fccb8991bd5b7..64a49dccb0b63 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -872,6 +872,10 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
 static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
 {
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+   struct iscsi_session *session = cls_session->dd_data;
+
+   if (WARN_ON_ONCE(session->leadconn))
+   return;
 
iscsi_tcp_r2tpool_free(cls_session->dd_data);
iscsi_session_teardown(cls_session);
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index ab32e60736424..20cf01d6ded7e 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2965,6 +2965,24 @@ iscsi_set_path(struct iscsi_transport *transport, struct 
iscsi_uevent *ev)
return err;
 }
 
+static int iscsi_session_has_conns(int sid)
+{
+   struct iscsi_cls_conn *conn;
+   unsigned long flags;
+   int found = 0;
+
+   spin_lock_irqsave(, flags);
+   list_for_each_entry(conn, , conn_list) {
+   if (iscsi_conn_get_sid(conn) == sid) {
+   found = 1;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(, flags);
+
+   return found;
+}
+
 static int
 iscsi_set_iface_params(struct iscsi_transport *transport,
   struct iscsi_uevent *ev, uint32_t len)
@@ -3539,10 +3557,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
break;
   

[PATCH AUTOSEL 4.9 103/141] scsi: iscsi: Don't destroy session if there are outstanding connections

2020-02-14 Thread Sasha Levin
From: Nick Black 

[ Upstream commit 54155ed4199c7aa3fd20866648024ab63c96d579 ]

A faulty userspace that calls destroy_session() before destroying the
connections can trigger the failure.  This patch prevents the issue by
refusing to destroy the session if there are outstanding connections.

[ cut here ]
kernel BUG at mm/slub.c:306!
invalid opcode:  [#1] SMP PTI
CPU: 1 PID: 1224 Comm: iscsid Not tainted 5.4.0-rc2.iscsi+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
RIP: 0010:__slab_free+0x181/0x350
[...]
[ 1209.686056] RSP: 0018:a93d4074fae0 EFLAGS: 00010246
[ 1209.686694] RAX: 934efa5ad800 RBX: 801a RCX: 934efa5ad800
[ 1209.687651] RDX: 934efa5ad800 RSI: eb4041e96b00 RDI: 934efd402c40
[ 1209.688582] RBP: a93d4074fb80 R08: 0001 R09: bb5dfa26
[ 1209.689425] R10: 934efa5ad800 R11: 0001 R12: eb4041e96b00
[ 1209.690285] R13: 934efa5ad800 R14: 934efd402c40 R15: 
[ 1209.691213] FS:  7f7945dfb540() GS:934efda8() 
knlGS:
[ 1209.692316] CS:  0010 DS:  ES:  CR0: 80050033
[ 1209.693013] CR2: 55877fd3da80 CR3: 77384000 CR4: 06e0
[ 1209.693897] DR0:  DR1:  DR2: 
[ 1209.694773] DR3:  DR6: fffe0ff0 DR7: 0400
[ 1209.695631] Call Trace:
[ 1209.695957]  ? __wake_up_common_lock+0x8a/0xc0
[ 1209.696712]  iscsi_pool_free+0x26/0x40
[ 1209.697263]  iscsi_session_teardown+0x2f/0xf0
[ 1209.698117]  iscsi_sw_tcp_session_destroy+0x45/0x60
[ 1209.698831]  iscsi_if_rx+0xd88/0x14e0
[ 1209.699370]  netlink_unicast+0x16f/0x200
[ 1209.699932]  netlink_sendmsg+0x21a/0x3e0
[ 1209.700446]  sock_sendmsg+0x4f/0x60
[ 1209.700902]  ___sys_sendmsg+0x2ae/0x320
[ 1209.701451]  ? cp_new_stat+0x150/0x180
[ 1209.701922]  __sys_sendmsg+0x59/0xa0
[ 1209.702357]  do_syscall_64+0x52/0x160
[ 1209.702812]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1209.703419] RIP: 0033:0x7f7946433914
[...]
[ 1209.706084] RSP: 002b:7fffb99f2378 EFLAGS: 0246 ORIG_RAX: 
002e
[ 1209.706994] RAX: ffda RBX: 55bc869eac20 RCX: 7f7946433914
[ 1209.708082] RDX:  RSI: 7fffb99f2390 RDI: 0005
[ 1209.709120] RBP: 7fffb99f2390 R08: 55bc84fe9320 R09: 7fffb99f1f07
[ 1209.710110] R10:  R11: 0246 R12: 0038
[ 1209.711085] R13: 55bc8502306e R14:  R15: 
 Modules linked in:
 ---[ end trace a2d933ede7f730d8 ]---

Link: https://lore.kernel.org/r/20191226203148.2172200-1-kris...@collabora.com
Signed-off-by: Nick Black 
Co-developed-by: Salman Qazi 
Signed-off-by: Salman Qazi 
Co-developed-by: Junho Ryu 
Signed-off-by: Junho Ryu 
Co-developed-by: Khazhismel Kumykov 
Signed-off-by: Khazhismel Kumykov 
Co-developed-by: Gabriel Krisman Bertazi 
Signed-off-by: Gabriel Krisman Bertazi 
Reviewed-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c|  4 
 drivers/scsi/scsi_transport_iscsi.c | 26 +++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index d60564397be54..60c3e2bf87619 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -882,6 +882,10 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
 static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
 {
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+   struct iscsi_session *session = cls_session->dd_data;
+
+   if (WARN_ON_ONCE(session->leadconn))
+   return;
 
iscsi_tcp_r2tpool_free(cls_session->dd_data);
iscsi_session_teardown(cls_session);
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index ab7bc4e634251..fff9c4d0f7c80 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2964,6 +2964,24 @@ iscsi_set_path(struct iscsi_transport *transport, struct 
iscsi_uevent *ev)
return err;
 }
 
+static int iscsi_session_has_conns(int sid)
+{
+   struct iscsi_cls_conn *conn;
+   unsigned long flags;
+   int found = 0;
+
+   spin_lock_irqsave(, flags);
+   list_for_each_entry(conn, , conn_list) {
+   if (iscsi_conn_get_sid(conn) == sid) {
+   found = 1;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(, flags);
+
+   return found;
+}
+
 static int
 iscsi_set_iface_params(struct iscsi_transport *transport,
   struct iscsi_uevent *ev, uint32_t len)
@@ -3538,10 +3556,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
break;
   

[PATCH AUTOSEL 4.14 133/186] scsi: iscsi: Don't destroy session if there are outstanding connections

2020-02-14 Thread Sasha Levin
From: Nick Black 

[ Upstream commit 54155ed4199c7aa3fd20866648024ab63c96d579 ]

A faulty userspace that calls destroy_session() before destroying the
connections can trigger the failure.  This patch prevents the issue by
refusing to destroy the session if there are outstanding connections.

[ cut here ]
kernel BUG at mm/slub.c:306!
invalid opcode:  [#1] SMP PTI
CPU: 1 PID: 1224 Comm: iscsid Not tainted 5.4.0-rc2.iscsi+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
RIP: 0010:__slab_free+0x181/0x350
[...]
[ 1209.686056] RSP: 0018:a93d4074fae0 EFLAGS: 00010246
[ 1209.686694] RAX: 934efa5ad800 RBX: 801a RCX: 934efa5ad800
[ 1209.687651] RDX: 934efa5ad800 RSI: eb4041e96b00 RDI: 934efd402c40
[ 1209.688582] RBP: a93d4074fb80 R08: 0001 R09: bb5dfa26
[ 1209.689425] R10: 934efa5ad800 R11: 0001 R12: eb4041e96b00
[ 1209.690285] R13: 934efa5ad800 R14: 934efd402c40 R15: 
[ 1209.691213] FS:  7f7945dfb540() GS:934efda8() 
knlGS:
[ 1209.692316] CS:  0010 DS:  ES:  CR0: 80050033
[ 1209.693013] CR2: 55877fd3da80 CR3: 77384000 CR4: 06e0
[ 1209.693897] DR0:  DR1:  DR2: 
[ 1209.694773] DR3:  DR6: fffe0ff0 DR7: 0400
[ 1209.695631] Call Trace:
[ 1209.695957]  ? __wake_up_common_lock+0x8a/0xc0
[ 1209.696712]  iscsi_pool_free+0x26/0x40
[ 1209.697263]  iscsi_session_teardown+0x2f/0xf0
[ 1209.698117]  iscsi_sw_tcp_session_destroy+0x45/0x60
[ 1209.698831]  iscsi_if_rx+0xd88/0x14e0
[ 1209.699370]  netlink_unicast+0x16f/0x200
[ 1209.699932]  netlink_sendmsg+0x21a/0x3e0
[ 1209.700446]  sock_sendmsg+0x4f/0x60
[ 1209.700902]  ___sys_sendmsg+0x2ae/0x320
[ 1209.701451]  ? cp_new_stat+0x150/0x180
[ 1209.701922]  __sys_sendmsg+0x59/0xa0
[ 1209.702357]  do_syscall_64+0x52/0x160
[ 1209.702812]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1209.703419] RIP: 0033:0x7f7946433914
[...]
[ 1209.706084] RSP: 002b:7fffb99f2378 EFLAGS: 0246 ORIG_RAX: 
002e
[ 1209.706994] RAX: ffda RBX: 55bc869eac20 RCX: 7f7946433914
[ 1209.708082] RDX:  RSI: 7fffb99f2390 RDI: 0005
[ 1209.709120] RBP: 7fffb99f2390 R08: 55bc84fe9320 R09: 7fffb99f1f07
[ 1209.710110] R10:  R11: 0246 R12: 0038
[ 1209.711085] R13: 55bc8502306e R14:  R15: 
 Modules linked in:
 ---[ end trace a2d933ede7f730d8 ]---

Link: https://lore.kernel.org/r/20191226203148.2172200-1-kris...@collabora.com
Signed-off-by: Nick Black 
Co-developed-by: Salman Qazi 
Signed-off-by: Salman Qazi 
Co-developed-by: Junho Ryu 
Signed-off-by: Junho Ryu 
Co-developed-by: Khazhismel Kumykov 
Signed-off-by: Khazhismel Kumykov 
Co-developed-by: Gabriel Krisman Bertazi 
Signed-off-by: Gabriel Krisman Bertazi 
Reviewed-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c|  4 
 drivers/scsi/scsi_transport_iscsi.c | 26 +++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 7e3a77d3c6f01..e3ca16043f9af 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -890,6 +890,10 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
 static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
 {
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+   struct iscsi_session *session = cls_session->dd_data;
+
+   if (WARN_ON_ONCE(session->leadconn))
+   return;
 
iscsi_tcp_r2tpool_free(cls_session->dd_data);
iscsi_session_teardown(cls_session);
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 95d71e301a534..aecb563a2b4e3 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2945,6 +2945,24 @@ iscsi_set_path(struct iscsi_transport *transport, struct 
iscsi_uevent *ev)
return err;
 }
 
+static int iscsi_session_has_conns(int sid)
+{
+   struct iscsi_cls_conn *conn;
+   unsigned long flags;
+   int found = 0;
+
+   spin_lock_irqsave(, flags);
+   list_for_each_entry(conn, , conn_list) {
+   if (iscsi_conn_get_sid(conn) == sid) {
+   found = 1;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(, flags);
+
+   return found;
+}
+
 static int
 iscsi_set_iface_params(struct iscsi_transport *transport,
   struct iscsi_uevent *ev, uint32_t len)
@@ -3522,10 +3540,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
break;
   

[PATCH AUTOSEL 4.19 180/252] scsi: iscsi: Don't destroy session if there are outstanding connections

2020-02-14 Thread Sasha Levin
From: Nick Black 

[ Upstream commit 54155ed4199c7aa3fd20866648024ab63c96d579 ]

A faulty userspace that calls destroy_session() before destroying the
connections can trigger the failure.  This patch prevents the issue by
refusing to destroy the session if there are outstanding connections.

[ cut here ]
kernel BUG at mm/slub.c:306!
invalid opcode:  [#1] SMP PTI
CPU: 1 PID: 1224 Comm: iscsid Not tainted 5.4.0-rc2.iscsi+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
RIP: 0010:__slab_free+0x181/0x350
[...]
[ 1209.686056] RSP: 0018:a93d4074fae0 EFLAGS: 00010246
[ 1209.686694] RAX: 934efa5ad800 RBX: 801a RCX: 934efa5ad800
[ 1209.687651] RDX: 934efa5ad800 RSI: eb4041e96b00 RDI: 934efd402c40
[ 1209.688582] RBP: a93d4074fb80 R08: 0001 R09: bb5dfa26
[ 1209.689425] R10: 934efa5ad800 R11: 0001 R12: eb4041e96b00
[ 1209.690285] R13: 934efa5ad800 R14: 934efd402c40 R15: 
[ 1209.691213] FS:  7f7945dfb540() GS:934efda8() 
knlGS:
[ 1209.692316] CS:  0010 DS:  ES:  CR0: 80050033
[ 1209.693013] CR2: 55877fd3da80 CR3: 77384000 CR4: 06e0
[ 1209.693897] DR0:  DR1:  DR2: 
[ 1209.694773] DR3:  DR6: fffe0ff0 DR7: 0400
[ 1209.695631] Call Trace:
[ 1209.695957]  ? __wake_up_common_lock+0x8a/0xc0
[ 1209.696712]  iscsi_pool_free+0x26/0x40
[ 1209.697263]  iscsi_session_teardown+0x2f/0xf0
[ 1209.698117]  iscsi_sw_tcp_session_destroy+0x45/0x60
[ 1209.698831]  iscsi_if_rx+0xd88/0x14e0
[ 1209.699370]  netlink_unicast+0x16f/0x200
[ 1209.699932]  netlink_sendmsg+0x21a/0x3e0
[ 1209.700446]  sock_sendmsg+0x4f/0x60
[ 1209.700902]  ___sys_sendmsg+0x2ae/0x320
[ 1209.701451]  ? cp_new_stat+0x150/0x180
[ 1209.701922]  __sys_sendmsg+0x59/0xa0
[ 1209.702357]  do_syscall_64+0x52/0x160
[ 1209.702812]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1209.703419] RIP: 0033:0x7f7946433914
[...]
[ 1209.706084] RSP: 002b:7fffb99f2378 EFLAGS: 0246 ORIG_RAX: 
002e
[ 1209.706994] RAX: ffda RBX: 55bc869eac20 RCX: 7f7946433914
[ 1209.708082] RDX:  RSI: 7fffb99f2390 RDI: 0005
[ 1209.709120] RBP: 7fffb99f2390 R08: 55bc84fe9320 R09: 7fffb99f1f07
[ 1209.710110] R10:  R11: 0246 R12: 0038
[ 1209.711085] R13: 55bc8502306e R14:  R15: 
 Modules linked in:
 ---[ end trace a2d933ede7f730d8 ]---

Link: https://lore.kernel.org/r/20191226203148.2172200-1-kris...@collabora.com
Signed-off-by: Nick Black 
Co-developed-by: Salman Qazi 
Signed-off-by: Salman Qazi 
Co-developed-by: Junho Ryu 
Signed-off-by: Junho Ryu 
Co-developed-by: Khazhismel Kumykov 
Signed-off-by: Khazhismel Kumykov 
Co-developed-by: Gabriel Krisman Bertazi 
Signed-off-by: Gabriel Krisman Bertazi 
Reviewed-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c|  4 
 drivers/scsi/scsi_transport_iscsi.c | 26 +++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 55181d28291e7..7212e3a13fe6b 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -892,6 +892,10 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
 static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
 {
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+   struct iscsi_session *session = cls_session->dd_data;
+
+   if (WARN_ON_ONCE(session->leadconn))
+   return;
 
iscsi_tcp_r2tpool_free(cls_session->dd_data);
iscsi_session_teardown(cls_session);
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 4c4781e5974f0..c0fb9e7890807 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2945,6 +2945,24 @@ iscsi_set_path(struct iscsi_transport *transport, struct 
iscsi_uevent *ev)
return err;
 }
 
+static int iscsi_session_has_conns(int sid)
+{
+   struct iscsi_cls_conn *conn;
+   unsigned long flags;
+   int found = 0;
+
+   spin_lock_irqsave(, flags);
+   list_for_each_entry(conn, , conn_list) {
+   if (iscsi_conn_get_sid(conn) == sid) {
+   found = 1;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(, flags);
+
+   return found;
+}
+
 static int
 iscsi_set_iface_params(struct iscsi_transport *transport,
   struct iscsi_uevent *ev, uint32_t len)
@@ -3522,10 +3540,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
break;
   

[PATCH AUTOSEL 5.4 329/459] scsi: iscsi: Don't destroy session if there are outstanding connections

2020-02-14 Thread Sasha Levin
From: Nick Black 

[ Upstream commit 54155ed4199c7aa3fd20866648024ab63c96d579 ]

A faulty userspace that calls destroy_session() before destroying the
connections can trigger the failure.  This patch prevents the issue by
refusing to destroy the session if there are outstanding connections.

[ cut here ]
kernel BUG at mm/slub.c:306!
invalid opcode:  [#1] SMP PTI
CPU: 1 PID: 1224 Comm: iscsid Not tainted 5.4.0-rc2.iscsi+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
RIP: 0010:__slab_free+0x181/0x350
[...]
[ 1209.686056] RSP: 0018:a93d4074fae0 EFLAGS: 00010246
[ 1209.686694] RAX: 934efa5ad800 RBX: 801a RCX: 934efa5ad800
[ 1209.687651] RDX: 934efa5ad800 RSI: eb4041e96b00 RDI: 934efd402c40
[ 1209.688582] RBP: a93d4074fb80 R08: 0001 R09: bb5dfa26
[ 1209.689425] R10: 934efa5ad800 R11: 0001 R12: eb4041e96b00
[ 1209.690285] R13: 934efa5ad800 R14: 934efd402c40 R15: 
[ 1209.691213] FS:  7f7945dfb540() GS:934efda8() 
knlGS:
[ 1209.692316] CS:  0010 DS:  ES:  CR0: 80050033
[ 1209.693013] CR2: 55877fd3da80 CR3: 77384000 CR4: 06e0
[ 1209.693897] DR0:  DR1:  DR2: 
[ 1209.694773] DR3:  DR6: fffe0ff0 DR7: 0400
[ 1209.695631] Call Trace:
[ 1209.695957]  ? __wake_up_common_lock+0x8a/0xc0
[ 1209.696712]  iscsi_pool_free+0x26/0x40
[ 1209.697263]  iscsi_session_teardown+0x2f/0xf0
[ 1209.698117]  iscsi_sw_tcp_session_destroy+0x45/0x60
[ 1209.698831]  iscsi_if_rx+0xd88/0x14e0
[ 1209.699370]  netlink_unicast+0x16f/0x200
[ 1209.699932]  netlink_sendmsg+0x21a/0x3e0
[ 1209.700446]  sock_sendmsg+0x4f/0x60
[ 1209.700902]  ___sys_sendmsg+0x2ae/0x320
[ 1209.701451]  ? cp_new_stat+0x150/0x180
[ 1209.701922]  __sys_sendmsg+0x59/0xa0
[ 1209.702357]  do_syscall_64+0x52/0x160
[ 1209.702812]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1209.703419] RIP: 0033:0x7f7946433914
[...]
[ 1209.706084] RSP: 002b:7fffb99f2378 EFLAGS: 0246 ORIG_RAX: 
002e
[ 1209.706994] RAX: ffda RBX: 55bc869eac20 RCX: 7f7946433914
[ 1209.708082] RDX:  RSI: 7fffb99f2390 RDI: 0005
[ 1209.709120] RBP: 7fffb99f2390 R08: 55bc84fe9320 R09: 7fffb99f1f07
[ 1209.710110] R10:  R11: 0246 R12: 0038
[ 1209.711085] R13: 55bc8502306e R14:  R15: 
 Modules linked in:
 ---[ end trace a2d933ede7f730d8 ]---

Link: https://lore.kernel.org/r/20191226203148.2172200-1-kris...@collabora.com
Signed-off-by: Nick Black 
Co-developed-by: Salman Qazi 
Signed-off-by: Salman Qazi 
Co-developed-by: Junho Ryu 
Signed-off-by: Junho Ryu 
Co-developed-by: Khazhismel Kumykov 
Signed-off-by: Khazhismel Kumykov 
Co-developed-by: Gabriel Krisman Bertazi 
Signed-off-by: Gabriel Krisman Bertazi 
Reviewed-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c|  4 
 drivers/scsi/scsi_transport_iscsi.c | 26 +++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 0bc63a7ab41c8..b5dd1caae5e92 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -887,6 +887,10 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
 static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
 {
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+   struct iscsi_session *session = cls_session->dd_data;
+
+   if (WARN_ON_ONCE(session->leadconn))
+   return;
 
iscsi_tcp_r2tpool_free(cls_session->dd_data);
iscsi_session_teardown(cls_session);
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index ed8d9709b9b96..271afea654e2b 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2947,6 +2947,24 @@ iscsi_set_path(struct iscsi_transport *transport, struct 
iscsi_uevent *ev)
return err;
 }
 
+static int iscsi_session_has_conns(int sid)
+{
+   struct iscsi_cls_conn *conn;
+   unsigned long flags;
+   int found = 0;
+
+   spin_lock_irqsave(, flags);
+   list_for_each_entry(conn, , conn_list) {
+   if (iscsi_conn_get_sid(conn) == sid) {
+   found = 1;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(, flags);
+
+   return found;
+}
+
 static int
 iscsi_set_iface_params(struct iscsi_transport *transport,
   struct iscsi_uevent *ev, uint32_t len)
@@ -3524,10 +3542,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
break;
   

[PATCH AUTOSEL 5.5 377/542] scsi: iscsi: Don't destroy session if there are outstanding connections

2020-02-14 Thread Sasha Levin
From: Nick Black 

[ Upstream commit 54155ed4199c7aa3fd20866648024ab63c96d579 ]

A faulty userspace that calls destroy_session() before destroying the
connections can trigger the failure.  This patch prevents the issue by
refusing to destroy the session if there are outstanding connections.

[ cut here ]
kernel BUG at mm/slub.c:306!
invalid opcode:  [#1] SMP PTI
CPU: 1 PID: 1224 Comm: iscsid Not tainted 5.4.0-rc2.iscsi+ #7
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
RIP: 0010:__slab_free+0x181/0x350
[...]
[ 1209.686056] RSP: 0018:a93d4074fae0 EFLAGS: 00010246
[ 1209.686694] RAX: 934efa5ad800 RBX: 801a RCX: 934efa5ad800
[ 1209.687651] RDX: 934efa5ad800 RSI: eb4041e96b00 RDI: 934efd402c40
[ 1209.688582] RBP: a93d4074fb80 R08: 0001 R09: bb5dfa26
[ 1209.689425] R10: 934efa5ad800 R11: 0001 R12: eb4041e96b00
[ 1209.690285] R13: 934efa5ad800 R14: 934efd402c40 R15: 
[ 1209.691213] FS:  7f7945dfb540() GS:934efda8() 
knlGS:
[ 1209.692316] CS:  0010 DS:  ES:  CR0: 80050033
[ 1209.693013] CR2: 55877fd3da80 CR3: 77384000 CR4: 06e0
[ 1209.693897] DR0:  DR1:  DR2: 
[ 1209.694773] DR3:  DR6: fffe0ff0 DR7: 0400
[ 1209.695631] Call Trace:
[ 1209.695957]  ? __wake_up_common_lock+0x8a/0xc0
[ 1209.696712]  iscsi_pool_free+0x26/0x40
[ 1209.697263]  iscsi_session_teardown+0x2f/0xf0
[ 1209.698117]  iscsi_sw_tcp_session_destroy+0x45/0x60
[ 1209.698831]  iscsi_if_rx+0xd88/0x14e0
[ 1209.699370]  netlink_unicast+0x16f/0x200
[ 1209.699932]  netlink_sendmsg+0x21a/0x3e0
[ 1209.700446]  sock_sendmsg+0x4f/0x60
[ 1209.700902]  ___sys_sendmsg+0x2ae/0x320
[ 1209.701451]  ? cp_new_stat+0x150/0x180
[ 1209.701922]  __sys_sendmsg+0x59/0xa0
[ 1209.702357]  do_syscall_64+0x52/0x160
[ 1209.702812]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 1209.703419] RIP: 0033:0x7f7946433914
[...]
[ 1209.706084] RSP: 002b:7fffb99f2378 EFLAGS: 0246 ORIG_RAX: 
002e
[ 1209.706994] RAX: ffda RBX: 55bc869eac20 RCX: 7f7946433914
[ 1209.708082] RDX:  RSI: 7fffb99f2390 RDI: 0005
[ 1209.709120] RBP: 7fffb99f2390 R08: 55bc84fe9320 R09: 7fffb99f1f07
[ 1209.710110] R10:  R11: 0246 R12: 0038
[ 1209.711085] R13: 55bc8502306e R14:  R15: 
 Modules linked in:
 ---[ end trace a2d933ede7f730d8 ]---

Link: https://lore.kernel.org/r/20191226203148.2172200-1-kris...@collabora.com
Signed-off-by: Nick Black 
Co-developed-by: Salman Qazi 
Signed-off-by: Salman Qazi 
Co-developed-by: Junho Ryu 
Signed-off-by: Junho Ryu 
Co-developed-by: Khazhismel Kumykov 
Signed-off-by: Khazhismel Kumykov 
Co-developed-by: Gabriel Krisman Bertazi 
Signed-off-by: Gabriel Krisman Bertazi 
Reviewed-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c|  4 
 drivers/scsi/scsi_transport_iscsi.c | 26 +++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 0bc63a7ab41c8..b5dd1caae5e92 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -887,6 +887,10 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, 
uint16_t cmds_max,
 static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session)
 {
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+   struct iscsi_session *session = cls_session->dd_data;
+
+   if (WARN_ON_ONCE(session->leadconn))
+   return;
 
iscsi_tcp_r2tpool_free(cls_session->dd_data);
iscsi_session_teardown(cls_session);
diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index ed8d9709b9b96..271afea654e2b 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2947,6 +2947,24 @@ iscsi_set_path(struct iscsi_transport *transport, struct 
iscsi_uevent *ev)
return err;
 }
 
+static int iscsi_session_has_conns(int sid)
+{
+   struct iscsi_cls_conn *conn;
+   unsigned long flags;
+   int found = 0;
+
+   spin_lock_irqsave(, flags);
+   list_for_each_entry(conn, , conn_list) {
+   if (iscsi_conn_get_sid(conn) == sid) {
+   found = 1;
+   break;
+   }
+   }
+   spin_unlock_irqrestore(, flags);
+
+   return found;
+}
+
 static int
 iscsi_set_iface_params(struct iscsi_transport *transport,
   struct iscsi_uevent *ev, uint32_t len)
@@ -3524,10 +3542,12 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr 
*nlh, uint32_t *group)
break;
   

[PATCH AUTOSEL 5.4 34/52] scsi: iscsi: Avoid potential deadlock in iscsi_if_rx func

2019-12-20 Thread Sasha Levin
From: Bo Wu 

[ Upstream commit bba340c79bfe3644829db5c852fdfa9e33837d6d ]

In iscsi_if_rx func, after receiving one request through
iscsi_if_recv_msg func, iscsi_if_send_reply will be called to try to
reply to the request in a do-while loop.  If the iscsi_if_send_reply
function keeps returning -EAGAIN, a deadlock will occur.

For example, a client only send msg without calling recvmsg func, then
it will result in the watchdog soft lockup.  The details are given as
follows:

sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ISCSI);
retval = bind(sock_fd, (struct sock addr*) & src_addr, sizeof(src_addr);
while (1) {
state_msg = sendmsg(sock_fd, , 0);
//Note: recvmsg(sock_fd, , 0) is not processed here.
}
close(sock_fd);

watchdog: BUG: soft lockup - CPU#7 stuck for 22s! [netlink_test:253305] Sample 
time: 4000897528 ns(HZ: 250) Sample stat:
curr: user: 675503481560, nice: 321724050, sys: 448689506750, idle: 
4654054240530, iowait: 40885550700, irq: 14161174020, softirq: 8104324140, st: 0
deta: user: 0, nice: 0, sys: 3998210100, idle: 0, iowait: 0, irq: 1547170, 
softirq: 242870, st: 0 Sample softirq:
 TIMER:992
 SCHED:  8
Sample irqstat:
 irq2: delta   1003, curr:3103802, arch_timer
CPU: 7 PID: 253305 Comm: netlink_test Kdump: loaded Tainted: G   OE
Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
pstate: 4045 (nZcv daif +PAN -UAO)
pc : __alloc_skb+0x104/0x1b0
lr : __alloc_skb+0x9c/0x1b0
sp : 33603a30
x29: 33603a30 x28: 02dd
x27: 800b34ced810 x26: 800ba7569f00
x25:  x24: 
x23: 800f7c43f600 x22: 00480020
x21: 091d9000 x20: 800b34eff200
x19: 800ba7569f00 x18: 
x17:  x16: 
x15:  x14: 0001000101000100
x13: 00010101 x12: 010101010100
x11: 0001010101010001 x10: 02dd
x9 : 33603d58 x8 : 800b34eff400
x7 : 800ba7569200 x6 : 800b34eff400
x5 :  x4 : 
x3 :  x2 : 0001
x1 : 800b34eff2c0 x0 : 0300 Call trace:
__alloc_skb+0x104/0x1b0
iscsi_if_rx+0x144/0x12bc [scsi_transport_iscsi]
netlink_unicast+0x1e0/0x258
netlink_sendmsg+0x310/0x378
sock_sendmsg+0x4c/0x70
sock_write_iter+0x90/0xf0
__vfs_write+0x11c/0x190
vfs_write+0xac/0x1c0
ksys_write+0x6c/0xd8
__arm64_sys_write+0x24/0x30
el0_svc_common+0x78/0x130
el0_svc_handler+0x38/0x78
el0_svc+0x8/0xc

Link: 
https://lore.kernel.org/r/edbaaa0bbba2ac4e9c8b6b81deee1d6915e3d...@dggeml505-mbx.china.huawei.com
Signed-off-by: Bo Wu 
Reviewed-by: Zhiqiang Liu 
Reviewed-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/scsi_transport_iscsi.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 417b868d8735e..ed8d9709b9b96 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -24,6 +24,8 @@
 
 #define ISCSI_TRANSPORT_VERSION "2.0-870"
 
+#define ISCSI_SEND_MAX_ALLOWED  10
+
 #define CREATE_TRACE_POINTS
 #include 
 
@@ -3682,6 +3684,7 @@ iscsi_if_rx(struct sk_buff *skb)
struct nlmsghdr *nlh;
struct iscsi_uevent *ev;
uint32_t group;
+   int retries = ISCSI_SEND_MAX_ALLOWED;
 
nlh = nlmsg_hdr(skb);
if (nlh->nlmsg_len < sizeof(*nlh) + sizeof(*ev) ||
@@ -3712,6 +3715,10 @@ iscsi_if_rx(struct sk_buff *skb)
break;
err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
  ev, sizeof(*ev));
+   if (err == -EAGAIN && --retries < 0) {
+   printk(KERN_WARNING "Send reply failed, error 
%d\n", err);
+   break;
+   }
} while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
skb_pull(skb, rlen);
}
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20191220142954.9500-34-sashal%40kernel.org.


[PATCH AUTOSEL 4.9 34/42] scsi: target: iscsi: Wait for all commands to finish before freeing a session

2019-12-11 Thread Sasha Levin
From: Bart Van Assche 

[ Upstream commit e9d3009cb936bd0faf0719f68d98ad8afb1e613b ]

The iSCSI target driver is the only target driver that does not wait for
ongoing commands to finish before freeing a session. Make the iSCSI target
driver wait for ongoing commands to finish before freeing a session. This
patch fixes the following KASAN complaint:

BUG: KASAN: use-after-free in __lock_acquire+0xb1a/0x2710
Read of size 8 at addr 8881154eca70 by task kworker/0:2/247

CPU: 0 PID: 247 Comm: kworker/0:2 Not tainted 5.4.0-rc1-dbg+ #6
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
Workqueue: target_completion target_complete_ok_work [target_core_mod]
Call Trace:
 dump_stack+0x8a/0xd6
 print_address_description.constprop.0+0x40/0x60
 __kasan_report.cold+0x1b/0x33
 kasan_report+0x16/0x20
 __asan_load8+0x58/0x90
 __lock_acquire+0xb1a/0x2710
 lock_acquire+0xd3/0x200
 _raw_spin_lock_irqsave+0x43/0x60
 target_release_cmd_kref+0x162/0x7f0 [target_core_mod]
 target_put_sess_cmd+0x2e/0x40 [target_core_mod]
 lio_check_stop_free+0x12/0x20 [iscsi_target_mod]
 transport_cmd_check_stop_to_fabric+0xd8/0xe0 [target_core_mod]
 target_complete_ok_work+0x1b0/0x790 [target_core_mod]
 process_one_work+0x549/0xa40
 worker_thread+0x7a/0x5d0
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

Allocated by task 889:
 save_stack+0x23/0x90
 __kasan_kmalloc.constprop.0+0xcf/0xe0
 kasan_slab_alloc+0x12/0x20
 kmem_cache_alloc+0xf6/0x360
 transport_alloc_session+0x29/0x80 [target_core_mod]
 iscsi_target_login_thread+0xcd6/0x18f0 [iscsi_target_mod]
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

Freed by task 1025:
 save_stack+0x23/0x90
 __kasan_slab_free+0x13a/0x190
 kasan_slab_free+0x12/0x20
 kmem_cache_free+0x146/0x400
 transport_free_session+0x179/0x2f0 [target_core_mod]
 transport_deregister_session+0x130/0x180 [target_core_mod]
 iscsit_close_session+0x12c/0x350 [iscsi_target_mod]
 iscsit_logout_post_handler+0x136/0x380 [iscsi_target_mod]
 iscsit_response_queue+0x8de/0xbe0 [iscsi_target_mod]
 iscsi_target_tx_thread+0x27f/0x370 [iscsi_target_mod]
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

The buggy address belongs to the object at 8881154ec9c0
 which belongs to the cache se_sess_cache of size 352
The buggy address is located 176 bytes inside of
 352-byte region [8881154ec9c0, 8881154ecb20)
The buggy address belongs to the page:
page:ea0004553b00 refcount:1 mapcount:0 mapping:888101755400 index:0x0 
compound_mapcount: 0
flags: 0x2fff00010200(slab|head)
raw: 2fff00010200 dead0100 dead0122 888101755400
raw:  80130013 0001 
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 8881154ec900: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 8881154ec980: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
>8881154eca00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ^
 8881154eca80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 8881154ecb00: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc

Cc: Mike Christie 
Link: https://lore.kernel.org/r/20191113220508.198257-3-bvanass...@acm.org
Reviewed-by: Roman Bolshakov 
Signed-off-by: Bart Van Assche 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/target/iscsi/iscsi_target.c | 10 --
 include/scsi/iscsi_proto.h  |  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index b6c4f55f79e7a..e5674e5857bf8 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1168,7 +1168,9 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct 
iscsi_cmd *cmd,
hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
conn->cid);
 
-   target_get_sess_cmd(>se_cmd, true);
+   if (target_get_sess_cmd(>se_cmd, true) < 0)
+   return iscsit_add_reject_cmd(cmd,
+   ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
 
cmd->sense_reason = transport_lookup_cmd_lun(>se_cmd,
 scsilun_to_int(>lun));
@@ -1986,7 +1988,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, 
struct iscsi_cmd *cmd,
  conn->sess->se_sess, 0, DMA_NONE,
  TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
 
-   target_get_sess_cmd(>se_cmd, true);
+   if (target_get_sess_cmd(>se_cmd, true) < 0)
+   return iscsit_add_reject_cmd(cmd,
+   ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
 
/*
 * TASK_REASSIGN for ERL=2 / connection stays inside of
@@ -4243,6 +4247,8 @@ int iscsit_close_connection(
 * must wait until they have completed.
  

[PATCH AUTOSEL 4.4 29/37] scsi: target: iscsi: Wait for all commands to finish before freeing a session

2019-12-11 Thread Sasha Levin
From: Bart Van Assche 

[ Upstream commit e9d3009cb936bd0faf0719f68d98ad8afb1e613b ]

The iSCSI target driver is the only target driver that does not wait for
ongoing commands to finish before freeing a session. Make the iSCSI target
driver wait for ongoing commands to finish before freeing a session. This
patch fixes the following KASAN complaint:

BUG: KASAN: use-after-free in __lock_acquire+0xb1a/0x2710
Read of size 8 at addr 8881154eca70 by task kworker/0:2/247

CPU: 0 PID: 247 Comm: kworker/0:2 Not tainted 5.4.0-rc1-dbg+ #6
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
Workqueue: target_completion target_complete_ok_work [target_core_mod]
Call Trace:
 dump_stack+0x8a/0xd6
 print_address_description.constprop.0+0x40/0x60
 __kasan_report.cold+0x1b/0x33
 kasan_report+0x16/0x20
 __asan_load8+0x58/0x90
 __lock_acquire+0xb1a/0x2710
 lock_acquire+0xd3/0x200
 _raw_spin_lock_irqsave+0x43/0x60
 target_release_cmd_kref+0x162/0x7f0 [target_core_mod]
 target_put_sess_cmd+0x2e/0x40 [target_core_mod]
 lio_check_stop_free+0x12/0x20 [iscsi_target_mod]
 transport_cmd_check_stop_to_fabric+0xd8/0xe0 [target_core_mod]
 target_complete_ok_work+0x1b0/0x790 [target_core_mod]
 process_one_work+0x549/0xa40
 worker_thread+0x7a/0x5d0
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

Allocated by task 889:
 save_stack+0x23/0x90
 __kasan_kmalloc.constprop.0+0xcf/0xe0
 kasan_slab_alloc+0x12/0x20
 kmem_cache_alloc+0xf6/0x360
 transport_alloc_session+0x29/0x80 [target_core_mod]
 iscsi_target_login_thread+0xcd6/0x18f0 [iscsi_target_mod]
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

Freed by task 1025:
 save_stack+0x23/0x90
 __kasan_slab_free+0x13a/0x190
 kasan_slab_free+0x12/0x20
 kmem_cache_free+0x146/0x400
 transport_free_session+0x179/0x2f0 [target_core_mod]
 transport_deregister_session+0x130/0x180 [target_core_mod]
 iscsit_close_session+0x12c/0x350 [iscsi_target_mod]
 iscsit_logout_post_handler+0x136/0x380 [iscsi_target_mod]
 iscsit_response_queue+0x8de/0xbe0 [iscsi_target_mod]
 iscsi_target_tx_thread+0x27f/0x370 [iscsi_target_mod]
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

The buggy address belongs to the object at 8881154ec9c0
 which belongs to the cache se_sess_cache of size 352
The buggy address is located 176 bytes inside of
 352-byte region [8881154ec9c0, 8881154ecb20)
The buggy address belongs to the page:
page:ea0004553b00 refcount:1 mapcount:0 mapping:888101755400 index:0x0 
compound_mapcount: 0
flags: 0x2fff00010200(slab|head)
raw: 2fff00010200 dead0100 dead0122 888101755400
raw:  80130013 0001 
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 8881154ec900: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 8881154ec980: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
>8881154eca00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ^
 8881154eca80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 8881154ecb00: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc

Cc: Mike Christie 
Link: https://lore.kernel.org/r/20191113220508.198257-3-bvanass...@acm.org
Reviewed-by: Roman Bolshakov 
Signed-off-by: Bart Van Assche 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/target/iscsi/iscsi_target.c | 10 --
 include/scsi/iscsi_proto.h  |  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index cbb4414edd71b..564828554ca02 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -993,7 +993,9 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct 
iscsi_cmd *cmd,
hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
conn->cid);
 
-   target_get_sess_cmd(>se_cmd, true);
+   if (target_get_sess_cmd(>se_cmd, true) < 0)
+   return iscsit_add_reject_cmd(cmd,
+   ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
 
cmd->sense_reason = transport_lookup_cmd_lun(>se_cmd,
 scsilun_to_int(>lun));
@@ -1804,7 +1806,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, 
struct iscsi_cmd *cmd,
  conn->sess->se_sess, 0, DMA_NONE,
  TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
 
-   target_get_sess_cmd(>se_cmd, true);
+   if (target_get_sess_cmd(>se_cmd, true) < 0)
+   return iscsit_add_reject_cmd(cmd,
+   ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
 
/*
 * TASK_REASSIGN for ERL=2 / connection stays inside of
@@ -4390,6 +4394,8 @@ int iscsit_close_connection(
 * must wait until they have completed.
  

[PATCH AUTOSEL 4.14 44/58] scsi: target: iscsi: Wait for all commands to finish before freeing a session

2019-12-11 Thread Sasha Levin
From: Bart Van Assche 

[ Upstream commit e9d3009cb936bd0faf0719f68d98ad8afb1e613b ]

The iSCSI target driver is the only target driver that does not wait for
ongoing commands to finish before freeing a session. Make the iSCSI target
driver wait for ongoing commands to finish before freeing a session. This
patch fixes the following KASAN complaint:

BUG: KASAN: use-after-free in __lock_acquire+0xb1a/0x2710
Read of size 8 at addr 8881154eca70 by task kworker/0:2/247

CPU: 0 PID: 247 Comm: kworker/0:2 Not tainted 5.4.0-rc1-dbg+ #6
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
Workqueue: target_completion target_complete_ok_work [target_core_mod]
Call Trace:
 dump_stack+0x8a/0xd6
 print_address_description.constprop.0+0x40/0x60
 __kasan_report.cold+0x1b/0x33
 kasan_report+0x16/0x20
 __asan_load8+0x58/0x90
 __lock_acquire+0xb1a/0x2710
 lock_acquire+0xd3/0x200
 _raw_spin_lock_irqsave+0x43/0x60
 target_release_cmd_kref+0x162/0x7f0 [target_core_mod]
 target_put_sess_cmd+0x2e/0x40 [target_core_mod]
 lio_check_stop_free+0x12/0x20 [iscsi_target_mod]
 transport_cmd_check_stop_to_fabric+0xd8/0xe0 [target_core_mod]
 target_complete_ok_work+0x1b0/0x790 [target_core_mod]
 process_one_work+0x549/0xa40
 worker_thread+0x7a/0x5d0
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

Allocated by task 889:
 save_stack+0x23/0x90
 __kasan_kmalloc.constprop.0+0xcf/0xe0
 kasan_slab_alloc+0x12/0x20
 kmem_cache_alloc+0xf6/0x360
 transport_alloc_session+0x29/0x80 [target_core_mod]
 iscsi_target_login_thread+0xcd6/0x18f0 [iscsi_target_mod]
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

Freed by task 1025:
 save_stack+0x23/0x90
 __kasan_slab_free+0x13a/0x190
 kasan_slab_free+0x12/0x20
 kmem_cache_free+0x146/0x400
 transport_free_session+0x179/0x2f0 [target_core_mod]
 transport_deregister_session+0x130/0x180 [target_core_mod]
 iscsit_close_session+0x12c/0x350 [iscsi_target_mod]
 iscsit_logout_post_handler+0x136/0x380 [iscsi_target_mod]
 iscsit_response_queue+0x8de/0xbe0 [iscsi_target_mod]
 iscsi_target_tx_thread+0x27f/0x370 [iscsi_target_mod]
 kthread+0x1bc/0x210
 ret_from_fork+0x24/0x30

The buggy address belongs to the object at 8881154ec9c0
 which belongs to the cache se_sess_cache of size 352
The buggy address is located 176 bytes inside of
 352-byte region [8881154ec9c0, 8881154ecb20)
The buggy address belongs to the page:
page:ea0004553b00 refcount:1 mapcount:0 mapping:888101755400 index:0x0 
compound_mapcount: 0
flags: 0x2fff00010200(slab|head)
raw: 2fff00010200 dead0100 dead0122 888101755400
raw:  80130013 0001 
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 8881154ec900: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 8881154ec980: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
>8881154eca00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ^
 8881154eca80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 8881154ecb00: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc

Cc: Mike Christie 
Link: https://lore.kernel.org/r/20191113220508.198257-3-bvanass...@acm.org
Reviewed-by: Roman Bolshakov 
Signed-off-by: Bart Van Assche 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/target/iscsi/iscsi_target.c | 10 --
 include/scsi/iscsi_proto.h  |  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index fb7bd422e2e1f..21ce92ee16527 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1158,7 +1158,9 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct 
iscsi_cmd *cmd,
hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
conn->cid);
 
-   target_get_sess_cmd(>se_cmd, true);
+   if (target_get_sess_cmd(>se_cmd, true) < 0)
+   return iscsit_add_reject_cmd(cmd,
+   ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
 
cmd->sense_reason = transport_lookup_cmd_lun(>se_cmd,
 scsilun_to_int(>lun));
@@ -2004,7 +2006,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, 
struct iscsi_cmd *cmd,
  conn->sess->se_sess, 0, DMA_NONE,
  TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
 
-   target_get_sess_cmd(>se_cmd, true);
+   if (target_get_sess_cmd(>se_cmd, true) < 0)
+   return iscsit_add_reject_cmd(cmd,
+   ISCSI_REASON_WAITING_FOR_LOGOUT, buf);
 
/*
 * TASK_REASSIGN for ERL=2 / connection stays inside of
@@ -4236,6 +4240,8 @@ int iscsit_close_connection(
 * must wait until they have completed.
  

[PATCH AUTOSEL 4.19 61/79] scsi: iscsi: Don't send data to unbound connection

2019-12-11 Thread Sasha Levin
From: Anatol Pomazau 

[ Upstream commit 238191d65d7217982d69e21c1d623616da34b281 ]

If a faulty initiator fails to bind the socket to the iSCSI connection
before emitting a command, for instance, a subsequent send_pdu, it will
crash the kernel due to a null pointer dereference in sock_sendmsg(), as
shown in the log below.  This patch makes sure the bind succeeded before
trying to use the socket.

BUG: kernel NULL pointer dereference, address: 0018
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x) - not-present page
PGD 0 P4D 0
Oops:  [#1] SMP PTI
CPU: 3 PID: 7 Comm: kworker/u8:0 Not tainted 5.4.0-rc2.iscsi+ #13
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
[   24.158246] Workqueue: iscsi_q_0 iscsi_xmitworker
[   24.158883] RIP: 0010:apparmor_socket_sendmsg+0x5/0x20
[...]
[   24.161739] RSP: 0018:ab6440043ca0 EFLAGS: 00010282
[   24.162400] RAX: 891c1c00 RBX: 89d53968 RCX: 0001
[   24.163253] RDX: 0030 RSI: ab6440043d00 RDI: 
[   24.164104] RBP: 0030 R08: 0030 R09: 0030
[   24.165166] R10: 893e66a0 R11: 0018 R12: ab6440043d00
[   24.166038] R13:  R14:  R15: 9d5575a62e90
[   24.166919] FS:  () GS:9d557db8() 
knlGS:
[   24.167890] CS:  0010 DS:  ES:  CR0: 80050033
[   24.168587] CR2: 0018 CR3: 7a838000 CR4: 06e0
[   24.169451] DR0:  DR1:  DR2: 
[   24.170320] DR3:  DR6: fffe0ff0 DR7: 0400
[   24.171214] Call Trace:
[   24.171537]  security_socket_sendmsg+0x3a/0x50
[   24.172079]  sock_sendmsg+0x16/0x60
[   24.172506]  iscsi_sw_tcp_xmit_segment+0x77/0x120
[   24.173076]  iscsi_sw_tcp_pdu_xmit+0x58/0x170
[   24.173604]  ? iscsi_dbg_trace+0x63/0x80
[   24.174087]  iscsi_tcp_task_xmit+0x101/0x280
[   24.174666]  iscsi_xmit_task+0x83/0x110
[   24.175206]  iscsi_xmitworker+0x57/0x380
[   24.175757]  ? __schedule+0x2a2/0x700
[   24.176273]  process_one_work+0x1b5/0x360
[   24.176837]  worker_thread+0x50/0x3c0
[   24.177353]  kthread+0xf9/0x130
[   24.177799]  ? process_one_work+0x360/0x360
[   24.178401]  ? kthread_park+0x90/0x90
[   24.178915]  ret_from_fork+0x35/0x40
[   24.179421] Modules linked in:
[   24.179856] CR2: 0018
[   24.180327] ---[ end trace b4b7674b6df5f480 ]---

Signed-off-by: Anatol Pomazau 
Co-developed-by: Frank Mayhar 
Signed-off-by: Frank Mayhar 
Co-developed-by: Bharath Ravi 
Signed-off-by: Bharath Ravi 
Co-developed-by: Khazhimsel Kumykov 
Signed-off-by: Khazhimsel Kumykov 
Co-developed-by: Gabriel Krisman Bertazi 
Signed-off-by: Gabriel Krisman Bertazi 
Reviewed-by: Lee Duncan 
Signed-off-by: Martin K. Petersen 
Signed-off-by: Sasha Levin 
---
 drivers/scsi/iscsi_tcp.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 23354f206533b..55181d28291e7 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -374,8 +374,16 @@ static int iscsi_sw_tcp_pdu_xmit(struct iscsi_task *task)
 {
struct iscsi_conn *conn = task->conn;
unsigned int noreclaim_flag;
+   struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+   struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
int rc = 0;
 
+   if (!tcp_sw_conn->sock) {
+   iscsi_conn_printk(KERN_ERR, conn,
+ "Transport not bound to socket!\n");
+   return -EINVAL;
+   }
+
noreclaim_flag = memalloc_noreclaim_save();
 
while (iscsi_sw_tcp_xmit_qlen(conn)) {
-- 
2.20.1

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to open-iscsi+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/20191211152643.23056-61-sashal%40kernel.org.


  1   2   >