All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] iscsi_tcp: Check if tcp_conn is valid in
  2022-03-04  2:56 ` [PATCH 2/2] iscsi_tcp: Check if tcp_conn is valid in Wenchao Hao
@ 2022-03-03 14:59   ` Mike Christie
  2022-03-04  2:24     ` Wenchao Hao
  0 siblings, 1 reply; 7+ messages in thread
From: Mike Christie @ 2022-03-03 14:59 UTC (permalink / raw)
  To: Wenchao Hao, Lee Duncan, Chris Leech, James E . J . Bottomley,
	Martin K . Petersen, open-iscsi, linux-scsi, linux-kernel
  Cc: Wu Bo, Zhiqiang Liu, linfeilong

On 3/3/22 8:56 PM, Wenchao Hao wrote:
> iscsi_create_conn() would add newly alloced iscsi_cls_conn to connlist,
> it means when userspace sends ISCSI_UEVENT_SET_PARAM, iscsi_conn_lookup()
> would found this iscsi_cls_conn and call the set_param callback which is
> iscsi_sw_tcp_conn_set_param(). While the iscsi_conn's dd_data might not
> been initialized.
> 
> Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
> Signed-off-by: Wu Bo <wubo40@huawei.com>
> ---
>  drivers/scsi/iscsi_tcp.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
> index 14db224486be..a42449df6156 100644
> --- a/drivers/scsi/iscsi_tcp.c
> +++ b/drivers/scsi/iscsi_tcp.c
> @@ -716,13 +716,17 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
>  {
>  	struct iscsi_conn *conn = cls_conn->dd_data;
>  	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
> -	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
> +	struct iscsi_sw_tcp_conn *tcp_sw_conn;
>  
>  	switch(param) {
>  	case ISCSI_PARAM_HDRDGST_EN:
>  		iscsi_set_param(cls_conn, param, buf, buflen);
>  		break;
>  	case ISCSI_PARAM_DATADGST_EN:
> +		if (!tcp_conn || !tcp_conn->dd_data)
> +			return -ENOTCONN;
> +
> +		tcp_sw_conn = tcp_conn->dd_data;
>  		iscsi_set_param(cls_conn, param, buf, buflen);
>  		tcp_sw_conn->sendpage = conn->datadgst_en ?
>  			sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;

Is this something you hit or from code review?

We have those state checks:

if ((conn->state == ISCSI_CONN_BOUND) ||
    (conn->state == ISCSI_CONN_UP)) {
	err = transport->set_param(conn, ev->u.set_param.param,

so we don't call set_param until after we have bound the
connection which will be after ISCSI_UEVENT_CREATE_CONN has returned.

Also for this specific bug iscsi_if_recv_msg is called with the
rx_queue_mutex, so set_param can only be called after the
ISCSI_UEVENT_CREATE_CONN cmd has returned.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] iscsi_tcp: Fix NULL pointer dereference in iscsi_sw_tcp_conn_get_param()
  2022-03-04  2:56 [PATCH 1/2] iscsi_tcp: Fix NULL pointer dereference in iscsi_sw_tcp_conn_get_param() Wenchao Hao
@ 2022-03-03 15:03 ` Mike Christie
  2022-03-04  2:40   ` Wenchao Hao
  2022-03-07 11:55   ` Wenchao Hao
  2022-03-04  2:56 ` [PATCH 2/2] iscsi_tcp: Check if tcp_conn is valid in Wenchao Hao
  1 sibling, 2 replies; 7+ messages in thread
From: Mike Christie @ 2022-03-03 15:03 UTC (permalink / raw)
  To: Wenchao Hao, Lee Duncan, Chris Leech, James E . J . Bottomley,
	Martin K . Petersen, open-iscsi, linux-scsi, linux-kernel
  Cc: Wu Bo, Zhiqiang Liu, linfeilong

On 3/3/22 8:56 PM, Wenchao Hao wrote:
> kernel might crash in iscsi_sw_tcp_conn_get_param() because it dereference
> an invalid address.
> 
> The initialization of iscsi_conn's dd_data is after device_register() of
> struct iscsi_cls_conn, so iscsi_conn's dd_data might not initialized when
> iscsi_sw_tcp_conn_get_param() is called.
> 
> Following stack would be reported and kernel would panic.
> 
> [449311.812887] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
> [449311.812893] Mem abort info:
> [449311.812895]   ESR = 0x96000004
> [449311.812899]   Exception class = DABT (current EL), IL = 32 bits
> [449311.812901]   SET = 0, FnV = 0
> [449311.812903]   EA = 0, S1PTW = 0
> [449311.812905] Data abort info:
> [449311.812907]   ISV = 0, ISS = 0x00000004
> [449311.812909]   CM = 0, WnR = 0
> [449311.812915] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000e26e7ace
> [449311.812918] [0000000000000008] pgd=0000000000000000
> [449311.812925] Internal error: Oops: 96000004 [#1] SMP
> [449311.814974] Process iscsiadm (pid: 8286, stack limit = 0xffff800010f78000)
> [449311.815570] CPU: 0 PID: 8286 Comm: iscsiadm Kdump: loaded Tainted: G    B   W         4.19.90-vhulk2201.1.0.h1021.kasan.eulerosv2r10.aarch64 #1
> [449311.816584] sd 1:0:0:1: [sdg] Attached SCSI disk
> [449311.816695] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
> [449311.817677] pstate: 40400005 (nZcv daif +PAN -UAO)
> [449311.818121] pc : iscsi_sw_tcp_conn_get_param+0xec/0x300 [iscsi_tcp]
> [449311.818688] lr : iscsi_sw_tcp_conn_get_param+0xe8/0x300 [iscsi_tcp]
> [449311.819244] sp : ffff800010f7f890
> [449311.819542] x29: ffff800010f7f890 x28: ffff8000cb1bea38
> [449311.820025] x27: ffff800010911010 x26: ffff2000028887a4
> [449311.820500] x25: ffff800009200d98 x24: ffff800010911000
> [449311.820973] x23: 0000000000000000 x22: ffff8000cb1bea28
> [449311.821458] x21: 0000000000000015 x20: ffff200081afa000
> [449311.821934] x19: 1ffff000021eff20 x18: 0000000000000000
> [449311.822414] x17: 0000000000000000 x16: ffff200080618220
> [449311.822891] x15: 0000000000000000 x14: 0000000000000000
> [449311.823413] x13: 0000000000000000 x12: 0000000000000000
> [449311.823897] x11: 1ffff0001ab4f41f x10: ffff10001ab4f41f
> [449311.824373] x9 : 0000000000000000 x8 : ffff8000d5a7a100
> [449311.824847] x7 : 0000000000000000 x6 : dfff200000000000
> [449311.825329] x5 : ffff1000021eff20 x4 : ffff8000cb1bea30
> [449311.825806] x3 : ffff200002911178 x2 : ffff2000841ff000
> [449311.826281] x1 : e0c234eab8420c00 x0 : ffff8000cb1bea38
> [449311.826756] Call trace:
> [449311.826987]  iscsi_sw_tcp_conn_get_param+0xec/0x300 [iscsi_tcp]
> [449311.827550]  show_conn_ep_param_ISCSI_PARAM_CONN_ADDRESS+0xe4/0x100 [scsi_transport_iscsi]
> [449311.828304]  dev_attr_show+0x58/0xb0
> [449311.828639]  sysfs_kf_seq_show+0x124/0x210
> [449311.829014]  kernfs_seq_show+0x8c/0xa0
> [449311.829362]  seq_read+0x188/0x8a0
> [449311.829667]  kernfs_fop_read+0x250/0x398
> [449311.830024]  __vfs_read+0xe0/0x350
> [449311.830339]  vfs_read+0xbc/0x1c0
> [449311.830635]  ksys_read+0xdc/0x1b8
> [449311.830941]  __arm64_sys_read+0x50/0x60
> [449311.831295]  el0_svc_common+0xc8/0x320
> [449311.831642]  el0_svc_handler+0xf8/0x160
> [449311.831998]  el0_svc+0x10/0x218
> [449311.832292] Code: f94006d7 910022e0 940007bb aa1c03e0 (f94006f9)
> 
> Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
> Signed-off-by: Wu Bo <wubo40@huawei.com>
> ---
>  drivers/scsi/iscsi_tcp.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
> index 1bc37593c88f..14db224486be 100644
> --- a/drivers/scsi/iscsi_tcp.c
> +++ b/drivers/scsi/iscsi_tcp.c
> @@ -741,11 +741,16 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
>  {
>  	struct iscsi_conn *conn = cls_conn->dd_data;
>  	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
> -	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
> +	struct iscsi_sw_tcp_conn *tcp_sw_conn;
>  	struct sockaddr_in6 addr;
>  	struct socket *sock;
>  	int rc;
>  
> +	if (!tcp_conn)
> +		return -ENOTCONN;
> +
> +	tcp_sw_conn = tcp_conn->dd_data;
> +
>  	switch(param) {
>  	case ISCSI_PARAM_CONN_PORT:
>  	case ISCSI_PARAM_CONN_ADDRESS:

We are actually doing sysfs/device addition wrong.

We should be doing the 2 step setup where in step 1 we alloc/init.
When everything is allocated and initialized, then we should do
device_add which exposes us to sysfs. On the teardown side, we are
then supposed to do 2 steps where the remove function does device_del
which waits until sysfs accesses are completed. We can then tear
the structs down and free them and call device_put.

The exposure to NL would be similar where it goes into the wrapper
around device_add. However, see my comments on the other patch where
I don't think we can hit the bug you mention because every nl cmd
that calls into the drivers is done under the rx_queue_mutex.

I think we should separate the iscsi_create_conn function like we
do for sessions. This is going to be a little more involved because
you need to also convert iscsi_tcp_conn_setup and the drivers since
we can call into the drivers for the get_conn_param callout.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] iscsi_tcp: Check if tcp_conn is valid in
  2022-03-03 14:59   ` Mike Christie
@ 2022-03-04  2:24     ` Wenchao Hao
  0 siblings, 0 replies; 7+ messages in thread
From: Wenchao Hao @ 2022-03-04  2:24 UTC (permalink / raw)
  To: Mike Christie, Lee Duncan, Chris Leech, James E . J . Bottomley,
	Martin K . Petersen, open-iscsi, linux-scsi, linux-kernel
  Cc: Wu Bo, Zhiqiang Liu, linfeilong

On 2022/3/3 22:59, Mike Christie wrote:
> On 3/3/22 8:56 PM, Wenchao Hao wrote:
>> iscsi_create_conn() would add newly alloced iscsi_cls_conn to connlist,
>> it means when userspace sends ISCSI_UEVENT_SET_PARAM, iscsi_conn_lookup()
>> would found this iscsi_cls_conn and call the set_param callback which is
>> iscsi_sw_tcp_conn_set_param(). While the iscsi_conn's dd_data might not
>> been initialized.
>>
>> Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
>> Signed-off-by: Wu Bo <wubo40@huawei.com>
>> ---
>>   drivers/scsi/iscsi_tcp.c | 6 +++++-
>>   1 file changed, 5 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
>> index 14db224486be..a42449df6156 100644
>> --- a/drivers/scsi/iscsi_tcp.c
>> +++ b/drivers/scsi/iscsi_tcp.c
>> @@ -716,13 +716,17 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
>>   {
>>   	struct iscsi_conn *conn = cls_conn->dd_data;
>>   	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
>> -	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
>> +	struct iscsi_sw_tcp_conn *tcp_sw_conn;
>>   
>>   	switch(param) {
>>   	case ISCSI_PARAM_HDRDGST_EN:
>>   		iscsi_set_param(cls_conn, param, buf, buflen);
>>   		break;
>>   	case ISCSI_PARAM_DATADGST_EN:
>> +		if (!tcp_conn || !tcp_conn->dd_data)
>> +			return -ENOTCONN;
>> +
>> +		tcp_sw_conn = tcp_conn->dd_data;
>>   		iscsi_set_param(cls_conn, param, buf, buflen);
>>   		tcp_sw_conn->sendpage = conn->datadgst_en ?
>>   			sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
> 
> Is this something you hit or from code review?
> 

It's from code review. I reviewed the code because the panic mentioned 
in my first patch. The issue seems would not happen, so just ignore it.

> We have those state checks:
> 
> if ((conn->state == ISCSI_CONN_BOUND) ||
>      (conn->state == ISCSI_CONN_UP)) {
> 	err = transport->set_param(conn, ev->u.set_param.param,
> 
> so we don't call set_param until after we have bound the
> connection which will be after ISCSI_UEVENT_CREATE_CONN has returned.
> 
> Also for this specific bug iscsi_if_recv_msg is called with the
> rx_queue_mutex, so set_param can only be called after the
> ISCSI_UEVENT_CREATE_CONN cmd has returned.
> .
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] iscsi_tcp: Fix NULL pointer dereference in iscsi_sw_tcp_conn_get_param()
  2022-03-03 15:03 ` Mike Christie
@ 2022-03-04  2:40   ` Wenchao Hao
  2022-03-07 11:55   ` Wenchao Hao
  1 sibling, 0 replies; 7+ messages in thread
From: Wenchao Hao @ 2022-03-04  2:40 UTC (permalink / raw)
  To: Mike Christie, Lee Duncan, Chris Leech, James E . J . Bottomley,
	Martin K . Petersen, open-iscsi, linux-scsi, linux-kernel
  Cc: Wu Bo, Zhiqiang Liu, linfeilong

On 2022/3/3 23:03, Mike Christie wrote:
> On 3/3/22 8:56 PM, Wenchao Hao wrote:
>> kernel might crash in iscsi_sw_tcp_conn_get_param() because it dereference
>> an invalid address.
>>
>> The initialization of iscsi_conn's dd_data is after device_register() of
>> struct iscsi_cls_conn, so iscsi_conn's dd_data might not initialized when
>> iscsi_sw_tcp_conn_get_param() is called.
>>
>> Following stack would be reported and kernel would panic.
>>
>> [449311.812887] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
>> [449311.812893] Mem abort info:
>> [449311.812895]   ESR = 0x96000004
>> [449311.812899]   Exception class = DABT (current EL), IL = 32 bits
>> [449311.812901]   SET = 0, FnV = 0
>> [449311.812903]   EA = 0, S1PTW = 0
>> [449311.812905] Data abort info:
>> [449311.812907]   ISV = 0, ISS = 0x00000004
>> [449311.812909]   CM = 0, WnR = 0
>> [449311.812915] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000e26e7ace
>> [449311.812918] [0000000000000008] pgd=0000000000000000
>> [449311.812925] Internal error: Oops: 96000004 [#1] SMP
>> [449311.814974] Process iscsiadm (pid: 8286, stack limit = 0xffff800010f78000)
>> [449311.815570] CPU: 0 PID: 8286 Comm: iscsiadm Kdump: loaded Tainted: G    B   W         4.19.90-vhulk2201.1.0.h1021.kasan.eulerosv2r10.aarch64 #1
>> [449311.816584] sd 1:0:0:1: [sdg] Attached SCSI disk
>> [449311.816695] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
>> [449311.817677] pstate: 40400005 (nZcv daif +PAN -UAO)
>> [449311.818121] pc : iscsi_sw_tcp_conn_get_param+0xec/0x300 [iscsi_tcp]
>> [449311.818688] lr : iscsi_sw_tcp_conn_get_param+0xe8/0x300 [iscsi_tcp]
>> [449311.819244] sp : ffff800010f7f890
>> [449311.819542] x29: ffff800010f7f890 x28: ffff8000cb1bea38
>> [449311.820025] x27: ffff800010911010 x26: ffff2000028887a4
>> [449311.820500] x25: ffff800009200d98 x24: ffff800010911000
>> [449311.820973] x23: 0000000000000000 x22: ffff8000cb1bea28
>> [449311.821458] x21: 0000000000000015 x20: ffff200081afa000
>> [449311.821934] x19: 1ffff000021eff20 x18: 0000000000000000
>> [449311.822414] x17: 0000000000000000 x16: ffff200080618220
>> [449311.822891] x15: 0000000000000000 x14: 0000000000000000
>> [449311.823413] x13: 0000000000000000 x12: 0000000000000000
>> [449311.823897] x11: 1ffff0001ab4f41f x10: ffff10001ab4f41f
>> [449311.824373] x9 : 0000000000000000 x8 : ffff8000d5a7a100
>> [449311.824847] x7 : 0000000000000000 x6 : dfff200000000000
>> [449311.825329] x5 : ffff1000021eff20 x4 : ffff8000cb1bea30
>> [449311.825806] x3 : ffff200002911178 x2 : ffff2000841ff000
>> [449311.826281] x1 : e0c234eab8420c00 x0 : ffff8000cb1bea38
>> [449311.826756] Call trace:
>> [449311.826987]  iscsi_sw_tcp_conn_get_param+0xec/0x300 [iscsi_tcp]
>> [449311.827550]  show_conn_ep_param_ISCSI_PARAM_CONN_ADDRESS+0xe4/0x100 [scsi_transport_iscsi]
>> [449311.828304]  dev_attr_show+0x58/0xb0
>> [449311.828639]  sysfs_kf_seq_show+0x124/0x210
>> [449311.829014]  kernfs_seq_show+0x8c/0xa0
>> [449311.829362]  seq_read+0x188/0x8a0
>> [449311.829667]  kernfs_fop_read+0x250/0x398
>> [449311.830024]  __vfs_read+0xe0/0x350
>> [449311.830339]  vfs_read+0xbc/0x1c0
>> [449311.830635]  ksys_read+0xdc/0x1b8
>> [449311.830941]  __arm64_sys_read+0x50/0x60
>> [449311.831295]  el0_svc_common+0xc8/0x320
>> [449311.831642]  el0_svc_handler+0xf8/0x160
>> [449311.831998]  el0_svc+0x10/0x218
>> [449311.832292] Code: f94006d7 910022e0 940007bb aa1c03e0 (f94006f9)
>>
>> Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
>> Signed-off-by: Wu Bo <wubo40@huawei.com>
>> ---
>>   drivers/scsi/iscsi_tcp.c | 7 ++++++-
>>   1 file changed, 6 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
>> index 1bc37593c88f..14db224486be 100644
>> --- a/drivers/scsi/iscsi_tcp.c
>> +++ b/drivers/scsi/iscsi_tcp.c
>> @@ -741,11 +741,16 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
>>   {
>>   	struct iscsi_conn *conn = cls_conn->dd_data;
>>   	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
>> -	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
>> +	struct iscsi_sw_tcp_conn *tcp_sw_conn;
>>   	struct sockaddr_in6 addr;
>>   	struct socket *sock;
>>   	int rc;
>>   
>> +	if (!tcp_conn)
>> +		return -ENOTCONN;
>> +
>> +	tcp_sw_conn = tcp_conn->dd_data;
>> +
>>   	switch(param) {
>>   	case ISCSI_PARAM_CONN_PORT:
>>   	case ISCSI_PARAM_CONN_ADDRESS:
> 
> We are actually doing sysfs/device addition wrong.
> 
> We should be doing the 2 step setup where in step 1 we alloc/init.
> When everything is allocated and initialized, then we should do
> device_add which exposes us to sysfs. On the teardown side, we are
> then supposed to do 2 steps where the remove function does device_del
> which waits until sysfs accesses are completed. We can then tear
> the structs down and free them and call device_put.
> 

I agree with this, and I would try to split device_add() from 
iscsi_create_conn().

What's more I would do some check between sysfs files add/remove and 
kernel object initialize/release to make a micro-refactoring

> The exposure to NL would be similar where it goes into the wrapper
> around device_add. However, see my comments on the other patch where
> I don't think we can hit the bug you mention because every nl cmd
> that calls into the drivers is done under the rx_queue_mutex.
> 
> I think we should separate the iscsi_create_conn function like we
> do for sessions. This is going to be a little more involved because
> you need to also convert iscsi_tcp_conn_setup and the drivers since
> we can call into the drivers for the get_conn_param callout.
> .
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] iscsi_tcp: Fix NULL pointer dereference in iscsi_sw_tcp_conn_get_param()
@ 2022-03-04  2:56 Wenchao Hao
  2022-03-03 15:03 ` Mike Christie
  2022-03-04  2:56 ` [PATCH 2/2] iscsi_tcp: Check if tcp_conn is valid in Wenchao Hao
  0 siblings, 2 replies; 7+ messages in thread
From: Wenchao Hao @ 2022-03-04  2:56 UTC (permalink / raw)
  To: Lee Duncan, Chris Leech, James E . J . Bottomley,
	Martin K . Petersen, open-iscsi, linux-scsi, linux-kernel
  Cc: Wu Bo, Zhiqiang Liu, linfeilong, Wenchao Hao

kernel might crash in iscsi_sw_tcp_conn_get_param() because it dereference
an invalid address.

The initialization of iscsi_conn's dd_data is after device_register() of
struct iscsi_cls_conn, so iscsi_conn's dd_data might not initialized when
iscsi_sw_tcp_conn_get_param() is called.

Following stack would be reported and kernel would panic.

[449311.812887] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
[449311.812893] Mem abort info:
[449311.812895]   ESR = 0x96000004
[449311.812899]   Exception class = DABT (current EL), IL = 32 bits
[449311.812901]   SET = 0, FnV = 0
[449311.812903]   EA = 0, S1PTW = 0
[449311.812905] Data abort info:
[449311.812907]   ISV = 0, ISS = 0x00000004
[449311.812909]   CM = 0, WnR = 0
[449311.812915] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000e26e7ace
[449311.812918] [0000000000000008] pgd=0000000000000000
[449311.812925] Internal error: Oops: 96000004 [#1] SMP
[449311.814974] Process iscsiadm (pid: 8286, stack limit = 0xffff800010f78000)
[449311.815570] CPU: 0 PID: 8286 Comm: iscsiadm Kdump: loaded Tainted: G    B   W         4.19.90-vhulk2201.1.0.h1021.kasan.eulerosv2r10.aarch64 #1
[449311.816584] sd 1:0:0:1: [sdg] Attached SCSI disk
[449311.816695] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
[449311.817677] pstate: 40400005 (nZcv daif +PAN -UAO)
[449311.818121] pc : iscsi_sw_tcp_conn_get_param+0xec/0x300 [iscsi_tcp]
[449311.818688] lr : iscsi_sw_tcp_conn_get_param+0xe8/0x300 [iscsi_tcp]
[449311.819244] sp : ffff800010f7f890
[449311.819542] x29: ffff800010f7f890 x28: ffff8000cb1bea38
[449311.820025] x27: ffff800010911010 x26: ffff2000028887a4
[449311.820500] x25: ffff800009200d98 x24: ffff800010911000
[449311.820973] x23: 0000000000000000 x22: ffff8000cb1bea28
[449311.821458] x21: 0000000000000015 x20: ffff200081afa000
[449311.821934] x19: 1ffff000021eff20 x18: 0000000000000000
[449311.822414] x17: 0000000000000000 x16: ffff200080618220
[449311.822891] x15: 0000000000000000 x14: 0000000000000000
[449311.823413] x13: 0000000000000000 x12: 0000000000000000
[449311.823897] x11: 1ffff0001ab4f41f x10: ffff10001ab4f41f
[449311.824373] x9 : 0000000000000000 x8 : ffff8000d5a7a100
[449311.824847] x7 : 0000000000000000 x6 : dfff200000000000
[449311.825329] x5 : ffff1000021eff20 x4 : ffff8000cb1bea30
[449311.825806] x3 : ffff200002911178 x2 : ffff2000841ff000
[449311.826281] x1 : e0c234eab8420c00 x0 : ffff8000cb1bea38
[449311.826756] Call trace:
[449311.826987]  iscsi_sw_tcp_conn_get_param+0xec/0x300 [iscsi_tcp]
[449311.827550]  show_conn_ep_param_ISCSI_PARAM_CONN_ADDRESS+0xe4/0x100 [scsi_transport_iscsi]
[449311.828304]  dev_attr_show+0x58/0xb0
[449311.828639]  sysfs_kf_seq_show+0x124/0x210
[449311.829014]  kernfs_seq_show+0x8c/0xa0
[449311.829362]  seq_read+0x188/0x8a0
[449311.829667]  kernfs_fop_read+0x250/0x398
[449311.830024]  __vfs_read+0xe0/0x350
[449311.830339]  vfs_read+0xbc/0x1c0
[449311.830635]  ksys_read+0xdc/0x1b8
[449311.830941]  __arm64_sys_read+0x50/0x60
[449311.831295]  el0_svc_common+0xc8/0x320
[449311.831642]  el0_svc_handler+0xf8/0x160
[449311.831998]  el0_svc+0x10/0x218
[449311.832292] Code: f94006d7 910022e0 940007bb aa1c03e0 (f94006f9)

Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
Signed-off-by: Wu Bo <wubo40@huawei.com>
---
 drivers/scsi/iscsi_tcp.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 1bc37593c88f..14db224486be 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -741,11 +741,16 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
 {
 	struct iscsi_conn *conn = cls_conn->dd_data;
 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
-	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+	struct iscsi_sw_tcp_conn *tcp_sw_conn;
 	struct sockaddr_in6 addr;
 	struct socket *sock;
 	int rc;
 
+	if (!tcp_conn)
+		return -ENOTCONN;
+
+	tcp_sw_conn = tcp_conn->dd_data;
+
 	switch(param) {
 	case ISCSI_PARAM_CONN_PORT:
 	case ISCSI_PARAM_CONN_ADDRESS:
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] iscsi_tcp: Check if tcp_conn is valid in
  2022-03-04  2:56 [PATCH 1/2] iscsi_tcp: Fix NULL pointer dereference in iscsi_sw_tcp_conn_get_param() Wenchao Hao
  2022-03-03 15:03 ` Mike Christie
@ 2022-03-04  2:56 ` Wenchao Hao
  2022-03-03 14:59   ` Mike Christie
  1 sibling, 1 reply; 7+ messages in thread
From: Wenchao Hao @ 2022-03-04  2:56 UTC (permalink / raw)
  To: Lee Duncan, Chris Leech, James E . J . Bottomley,
	Martin K . Petersen, open-iscsi, linux-scsi, linux-kernel
  Cc: Wu Bo, Zhiqiang Liu, linfeilong, Wenchao Hao

iscsi_create_conn() would add newly alloced iscsi_cls_conn to connlist,
it means when userspace sends ISCSI_UEVENT_SET_PARAM, iscsi_conn_lookup()
would found this iscsi_cls_conn and call the set_param callback which is
iscsi_sw_tcp_conn_set_param(). While the iscsi_conn's dd_data might not
been initialized.

Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
Signed-off-by: Wu Bo <wubo40@huawei.com>
---
 drivers/scsi/iscsi_tcp.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 14db224486be..a42449df6156 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -716,13 +716,17 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
 {
 	struct iscsi_conn *conn = cls_conn->dd_data;
 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
-	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+	struct iscsi_sw_tcp_conn *tcp_sw_conn;
 
 	switch(param) {
 	case ISCSI_PARAM_HDRDGST_EN:
 		iscsi_set_param(cls_conn, param, buf, buflen);
 		break;
 	case ISCSI_PARAM_DATADGST_EN:
+		if (!tcp_conn || !tcp_conn->dd_data)
+			return -ENOTCONN;
+
+		tcp_sw_conn = tcp_conn->dd_data;
 		iscsi_set_param(cls_conn, param, buf, buflen);
 		tcp_sw_conn->sendpage = conn->datadgst_en ?
 			sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] iscsi_tcp: Fix NULL pointer dereference in iscsi_sw_tcp_conn_get_param()
  2022-03-03 15:03 ` Mike Christie
  2022-03-04  2:40   ` Wenchao Hao
@ 2022-03-07 11:55   ` Wenchao Hao
  1 sibling, 0 replies; 7+ messages in thread
From: Wenchao Hao @ 2022-03-07 11:55 UTC (permalink / raw)
  To: Mike Christie, Lee Duncan, Chris Leech, James E . J . Bottomley,
	Martin K . Petersen, open-iscsi, linux-scsi, linux-kernel
  Cc: Wu Bo, Zhiqiang Liu, linfeilong

On 2022/3/3 23:03, Mike Christie wrote:
> On 3/3/22 8:56 PM, Wenchao Hao wrote:
>> kernel might crash in iscsi_sw_tcp_conn_get_param() because it dereference
>> an invalid address.
>>
>> The initialization of iscsi_conn's dd_data is after device_register() of
>> struct iscsi_cls_conn, so iscsi_conn's dd_data might not initialized when
>> iscsi_sw_tcp_conn_get_param() is called.
>>
> 
> We are actually doing sysfs/device addition wrong.
> 
> We should be doing the 2 step setup where in step 1 we alloc/init.
> When everything is allocated and initialized, then we should do
> device_add which exposes us to sysfs. On the teardown side, we are
> then supposed to do 2 steps where the remove function does device_del
> which waits until sysfs accesses are completed. We can then tear
> the structs down and free them and call device_put.
> 

I reviewed the teardown flow of iscsi_cls_conn, it has already written 
as what you saied.


> The exposure to NL would be similar where it goes into the wrapper
> around device_add. However, see my comments on the other patch where
> I don't think we can hit the bug you mention because every nl cmd
> that calls into the drivers is done under the rx_queue_mutex.
> 
> I think we should separate the iscsi_create_conn function like we
> do for sessions. This is going to be a little more involved because
> you need to also convert iscsi_tcp_conn_setup and the drivers since
> we can call into the drivers for the get_conn_param callout.
> .
> 

I hesitated about when should we call device_add(). I think there are 
two places to call it.

The first one is in iscsi_conn_setup(), after some initialization of 
conn, it keeps same with previous's implement and need not to change 
drivers' code. What's more, the change can fix iscsi_tcp's NULL pointer 
access.  While this change can not make sure the LLDs related sources 
are already initialized when iscsi_cls_conn is exposed to sysfs. It 
means LLDs' callback are still responsible to check if the resources are 
accessible.

Another one is in create_conn callback for each driver's 
iscsi_transport.  This need us to change each driver's code.

I send 2 patches which make changes in iscsi_conn_setup(), it's ok with 
iscsi_tcp, would you help to review them?


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-03-07 11:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-04  2:56 [PATCH 1/2] iscsi_tcp: Fix NULL pointer dereference in iscsi_sw_tcp_conn_get_param() Wenchao Hao
2022-03-03 15:03 ` Mike Christie
2022-03-04  2:40   ` Wenchao Hao
2022-03-07 11:55   ` Wenchao Hao
2022-03-04  2:56 ` [PATCH 2/2] iscsi_tcp: Check if tcp_conn is valid in Wenchao Hao
2022-03-03 14:59   ` Mike Christie
2022-03-04  2:24     ` Wenchao Hao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.