[PATCHv2] iscsi target: Set conn->sess to NULL when iscsi_login_set_conn_values fails
diff mbox series

Message ID 832b92dcf4838101e944f1394de570642a16faac.1534372918.git.plr.vincent@gmail.com
State New, archived
Headers show
Series
  • [PATCHv2] iscsi target: Set conn->sess to NULL when iscsi_login_set_conn_values fails
Related show

Commit Message

Vincent Pelletier Aug. 15, 2018, 10:56 p.m. UTC
Fixes a use-after-free reported by KASAN when later
iscsi_target_login_sess_out gets called and it tries to access
conn->sess->se_sess:

Disabling lock debugging due to kernel taint
iSCSI Login timeout on Network Portal [::]:3260
iSCSI Login negotiation failed.

Comments

Mike Christie Aug. 16, 2018, 4:55 a.m. UTC | #1
On 08/15/2018 05:56 PM, Vincent Pelletier wrote:
> Fixes a use-after-free reported by KASAN when later
> iscsi_target_login_sess_out gets called and it tries to access
> conn->sess->se_sess:
> 
> Disabling lock debugging due to kernel taint
> iSCSI Login timeout on Network Portal [::]:3260
> iSCSI Login negotiation failed.
> ==================================================================
> BUG: KASAN: use-after-free in iscsi_target_login_sess_out.cold.12+0x58/0xff [iscsi_target_mod]
> Read of size 8 at addr ffff880109d070c8 by task iscsi_np/980
> 
> CPU: 1 PID: 980 Comm: iscsi_np Tainted: G           O      4.17.8kasan.sess.connops+ #4
> Hardware name: To be filled by O.E.M. To be filled by O.E.M./Aptio CRB, BIOS 5.6.5 05/19/2014
> Call Trace:
>  dump_stack+0x71/0xac
>  print_address_description+0x65/0x22e
>  ? iscsi_target_login_sess_out.cold.12+0x58/0xff [iscsi_target_mod]
>  kasan_report.cold.6+0x241/0x2fd
>  iscsi_target_login_sess_out.cold.12+0x58/0xff [iscsi_target_mod]
>  iscsi_target_login_thread+0x1086/0x1710 [iscsi_target_mod]
>  ? __sched_text_start+0x8/0x8
>  ? iscsi_target_login_sess_out+0x250/0x250 [iscsi_target_mod]
>  ? __kthread_parkme+0xcc/0x100
>  ? parse_args.cold.14+0xd3/0xd3
>  ? iscsi_target_login_sess_out+0x250/0x250 [iscsi_target_mod]
>  kthread+0x1a0/0x1c0
>  ? kthread_bind+0x30/0x30
>  ret_from_fork+0x35/0x40
> 
> Allocated by task 980:
>  kasan_kmalloc+0xbf/0xe0
>  kmem_cache_alloc_trace+0x112/0x210
>  iscsi_target_login_thread+0x816/0x1710 [iscsi_target_mod]
>  kthread+0x1a0/0x1c0
>  ret_from_fork+0x35/0x40
> 
> Freed by task 980:
>  __kasan_slab_free+0x125/0x170
>  kfree+0x90/0x1d0
>  iscsi_target_login_thread+0x1577/0x1710 [iscsi_target_mod]
>  kthread+0x1a0/0x1c0
>  ret_from_fork+0x35/0x40
> 
> The buggy address belongs to the object at ffff880109d06f00
>  which belongs to the cache kmalloc-512 of size 512
> The buggy address is located 456 bytes inside of
>  512-byte region [ffff880109d06f00, ffff880109d07100)
> The buggy address belongs to the page:
> page:ffffea0004274180 count:1 mapcount:0 mapping:0000000000000000 index:0x0 compound_mapcount: 0
> flags: 0x17fffc000008100(slab|head)
> raw: 017fffc000008100 0000000000000000 0000000000000000 00000001000c000c
> raw: dead000000000100 dead000000000200 ffff88011b002e00 0000000000000000
> page dumped because: kasan: bad access detected
> 
> Memory state around the buggy address:
>  ffff880109d06f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>  ffff880109d07000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>> ffff880109d07080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>                                               ^
>  ffff880109d07100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>  ffff880109d07180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> ==================================================================
> 
> Also, let idr_alloc return value through instead of replacing it with -ENOMEM,
> as it is already a negative value and caller checks sign, not exact value.
> 
> Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
> ---
>  drivers/target/iscsi/iscsi_target_login.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
> index df81b2f7cad9..7337ff80394e 100644
> --- a/drivers/target/iscsi/iscsi_target_login.c
> +++ b/drivers/target/iscsi/iscsi_target_login.c
> @@ -296,10 +296,8 @@ static int iscsi_login_zero_tsih_s1(
>  	}
>  
>  	ret = iscsi_login_set_conn_values(sess, conn, pdu->cid);
> -	if (unlikely(ret)) {
> -		kfree(sess);
> -		return ret;
> -	}
> +	if (unlikely(ret))
> +		goto free_sess;
>  	sess->init_task_tag	= pdu->itt;
>  	memcpy(&sess->isid, pdu->isid, 6);
>  	sess->exp_cmd_sn	= be32_to_cpu(pdu->cmdsn);
> @@ -349,6 +347,7 @@ static int iscsi_login_zero_tsih_s1(
>  				ISCSI_LOGIN_STATUS_NO_RESOURCES);
>  		pr_err("Unable to allocate memory for"
>  				" struct iscsi_sess_ops.\n");
> +		ret = -ENOMEM;
>  		goto remove_idr;
>  	}
>  
> @@ -356,6 +355,7 @@ static int iscsi_login_zero_tsih_s1(
>  	if (IS_ERR(sess->se_sess)) {
>  		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
>  				ISCSI_LOGIN_STATUS_NO_RESOURCES);
> +		ret = -ENOMEM;
>  		goto free_ops;
>  	}
>  
> @@ -370,7 +370,7 @@ static int iscsi_login_zero_tsih_s1(
>  free_sess:
>  	kfree(sess);
>  	conn->sess = NULL;
> -	return -ENOMEM;
> +	return ret;
>  }
>  
>  static int iscsi_login_zero_tsih_s2(
> 

Looks good now. Thanks.

Reviewed-by: Mike Christie <mchristi@redhat.com>

Martin, this was made over that patch that was going through Mathew's
tree. I do not know exactly which one though. It is in next here

https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/target/iscsi?id=ad86353cbddbb6f1c95072ead744d547a9ac8211
Martin K. Petersen Aug. 24, 2018, 2:11 a.m. UTC | #2
Mike,

> this was made over that patch that was going through Mathew's tree. I
> do not know exactly which one though. It is in next here

Doesn't look like Linus will pull Matthew's tree for 4.19.
Mike Christie Aug. 24, 2018, 4:46 p.m. UTC | #3
On 08/23/2018 09:11 PM, Martin K. Petersen wrote:
> 
> Mike,
> 
>> this was made over that patch that was going through Mathew's tree. I
>> do not know exactly which one though. It is in next here
> 
> Doesn't look like Linus will pull Matthew's tree for 4.19.
>

It looks like there is also going to be a conflict with another patch
upstream. I will just round up all the patches and resend in one set
rebased against your current for-4.19 tree.
Martin K. Petersen Aug. 24, 2018, 4:48 p.m. UTC | #4
Mike,

> It looks like there is also going to be a conflict with another patch
> upstream. I will just round up all the patches and resend in one set
> rebased against your current for-4.19 tree.

Super, thanks!

Patch
diff mbox series

==================================================================
BUG: KASAN: use-after-free in iscsi_target_login_sess_out.cold.12+0x58/0xff [iscsi_target_mod]
Read of size 8 at addr ffff880109d070c8 by task iscsi_np/980

CPU: 1 PID: 980 Comm: iscsi_np Tainted: G           O      4.17.8kasan.sess.connops+ #4
Hardware name: To be filled by O.E.M. To be filled by O.E.M./Aptio CRB, BIOS 5.6.5 05/19/2014
Call Trace:
 dump_stack+0x71/0xac
 print_address_description+0x65/0x22e
 ? iscsi_target_login_sess_out.cold.12+0x58/0xff [iscsi_target_mod]
 kasan_report.cold.6+0x241/0x2fd
 iscsi_target_login_sess_out.cold.12+0x58/0xff [iscsi_target_mod]
 iscsi_target_login_thread+0x1086/0x1710 [iscsi_target_mod]
 ? __sched_text_start+0x8/0x8
 ? iscsi_target_login_sess_out+0x250/0x250 [iscsi_target_mod]
 ? __kthread_parkme+0xcc/0x100
 ? parse_args.cold.14+0xd3/0xd3
 ? iscsi_target_login_sess_out+0x250/0x250 [iscsi_target_mod]
 kthread+0x1a0/0x1c0
 ? kthread_bind+0x30/0x30
 ret_from_fork+0x35/0x40

Allocated by task 980:
 kasan_kmalloc+0xbf/0xe0
 kmem_cache_alloc_trace+0x112/0x210
 iscsi_target_login_thread+0x816/0x1710 [iscsi_target_mod]
 kthread+0x1a0/0x1c0
 ret_from_fork+0x35/0x40

Freed by task 980:
 __kasan_slab_free+0x125/0x170
 kfree+0x90/0x1d0
 iscsi_target_login_thread+0x1577/0x1710 [iscsi_target_mod]
 kthread+0x1a0/0x1c0
 ret_from_fork+0x35/0x40

The buggy address belongs to the object at ffff880109d06f00
 which belongs to the cache kmalloc-512 of size 512
The buggy address is located 456 bytes inside of
 512-byte region [ffff880109d06f00, ffff880109d07100)
The buggy address belongs to the page:
page:ffffea0004274180 count:1 mapcount:0 mapping:0000000000000000 index:0x0 compound_mapcount: 0
flags: 0x17fffc000008100(slab|head)
raw: 017fffc000008100 0000000000000000 0000000000000000 00000001000c000c
raw: dead000000000100 dead000000000200 ffff88011b002e00 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff880109d06f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff880109d07000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff880109d07080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                              ^
 ffff880109d07100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff880109d07180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==================================================================

Also, let idr_alloc return value through instead of replacing it with -ENOMEM,
as it is already a negative value and caller checks sign, not exact value.

Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
---
 drivers/target/iscsi/iscsi_target_login.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index df81b2f7cad9..7337ff80394e 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -296,10 +296,8 @@  static int iscsi_login_zero_tsih_s1(
 	}
 
 	ret = iscsi_login_set_conn_values(sess, conn, pdu->cid);
-	if (unlikely(ret)) {
-		kfree(sess);
-		return ret;
-	}
+	if (unlikely(ret))
+		goto free_sess;
 	sess->init_task_tag	= pdu->itt;
 	memcpy(&sess->isid, pdu->isid, 6);
 	sess->exp_cmd_sn	= be32_to_cpu(pdu->cmdsn);
@@ -349,6 +347,7 @@  static int iscsi_login_zero_tsih_s1(
 				ISCSI_LOGIN_STATUS_NO_RESOURCES);
 		pr_err("Unable to allocate memory for"
 				" struct iscsi_sess_ops.\n");
+		ret = -ENOMEM;
 		goto remove_idr;
 	}
 
@@ -356,6 +355,7 @@  static int iscsi_login_zero_tsih_s1(
 	if (IS_ERR(sess->se_sess)) {
 		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
 				ISCSI_LOGIN_STATUS_NO_RESOURCES);
+		ret = -ENOMEM;
 		goto free_ops;
 	}
 
@@ -370,7 +370,7 @@  static int iscsi_login_zero_tsih_s1(
 free_sess:
 	kfree(sess);
 	conn->sess = NULL;
-	return -ENOMEM;
+	return ret;
 }
 
 static int iscsi_login_zero_tsih_s2(