All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] target/user: Fix use-after-free cmd->se_cmd if the cmd is expired
       [not found] <1483433176-21063-1-git-send-email-lixiubo@cmss.chinamobile.com>
@ 2017-01-04  1:29 ` Mike Christie
  2017-01-04  8:51   ` [PATCH] target/user: Fix use-after-free cmd->se_cmd if the cmd isexpired Xiubo Li
  0 siblings, 1 reply; 2+ messages in thread
From: Mike Christie @ 2017-01-04  1:29 UTC (permalink / raw)
  To: lixiubo, bart.vanassche
  Cc: varun, agrover, bgly, target-devel, linux-kernel, linux-scsi,
	namei.unix, stable, Jianfei Hu

On 01/03/2017 02:46 AM, lixiubo@cmss.chinamobile.com wrote:
> From: Xiubo Li <lixiubo@cmss.chinamobile.com>
> 
> This is another use-after-free bug, the crash Call Trace is like:
> [  368.909498] RIP: 0010:[<ffffffff81326766>]  [<ffffffff81326766>]
> memcpy+0x16/0x110
> ......
> [  368.909547] Call Trace:
> [  368.909550]  [<ffffffffa07717a9>] ?gather_data_area+0x109/0x180
> [  368.909552]  [<ffffffffa077227f>] tcmu_handle_completions+0x2ff/0x450
> [  368.909554]  [<ffffffffa07723e5>] tcmu_irqcontrol+0x15/0x20
> [  368.909555]  [<ffffffffa06f07eb>] uio_write+0x7b/0xc0
> [  368.909558]  [<ffffffff811fe12d>] vfs_write+0xbd/0x1e0
> [  368.909559]  [<ffffffff811fec4f>] SyS_write+0x7f/0xe0
> [  368.909562]  [<ffffffff816964c9>] system_call_fastpath+0x16/0x1b
> 
> Don't free se_cmd of the expired cmds in tcmu_check_expired_cmd(),
> it will be dereferenced by tcmu_handle_completions()--->
> tcmu_handle_completion(), after userspace ever resumes processing.
> 
> It will be freed by tcmu_handle_completion() if userspace ever recovers,
> or tcmu_free_device if not.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
> Signed-off-by: Jianfei Hu <hujianfei@cmss.chinamobile.com>
> ---
>  drivers/target/target_core_user.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
> index 2e33100..6396581 100644
> --- a/drivers/target/target_core_user.c
> +++ b/drivers/target/target_core_user.c
> @@ -684,7 +684,6 @@ static int tcmu_check_expired_cmd(int id, void *p, void *data)
>  
>  	set_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags);
>  	target_complete_cmd(cmd->se_cmd, SAM_STAT_CHECK_CONDITION);
> -	cmd->se_cmd = NULL;
>  

How did tcmu_handle_completion get to a point it was accessing the
se_cmd if the TCMU_CMD_BIT_EXPIRED bit was set? Were memory accesses out
of order? CPU1 set the TCMU_CMD_BIT_EXPIRED bit then cleared
cmd->se_cmd, but CPU2 copied cmd->se_cmd to se_cmd and saw it was NULL
but did not yet see the TCMU_CMD_BIT_EXPIRED bit set?

It looks like, if you do the above patch, the above function will call
target_complete_cmd and tcmu_handle_completion will call it again, so we
will have a double free issue.

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

* Re: [PATCH] target/user: Fix use-after-free cmd->se_cmd if the cmd isexpired
  2017-01-04  1:29 ` [PATCH] target/user: Fix use-after-free cmd->se_cmd if the cmd is expired Mike Christie
@ 2017-01-04  8:51   ` Xiubo Li
  0 siblings, 0 replies; 2+ messages in thread
From: Xiubo Li @ 2017-01-04  8:51 UTC (permalink / raw)
  To: Mike Christie, bart.vanassche
  Cc: varun, agrover, bgly, target-devel, linux-kernel, linux-scsi,
	namei.unix, stable, Jianfei Hu


Hi Mike

Thanks very much for your analysis.

>> diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
>> index 2e33100..6396581 100644
>> --- a/drivers/target/target_core_user.c
>> +++ b/drivers/target/target_core_user.c
>> @@ -684,7 +684,6 @@ static int tcmu_check_expired_cmd(int id, void *p, void *data)
>>   
>>   	set_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags);
>>   	target_complete_cmd(cmd->se_cmd, SAM_STAT_CHECK_CONDITION);
>> -	cmd->se_cmd = NULL;
>>   
> How did tcmu_handle_completion get to a point it was accessing the
> se_cmd if the TCMU_CMD_BIT_EXPIRED bit was set?
> Were memory accesses out
> of order?
No, even using the -O3, becuase has there memory dependency ?

> CPU1 set the TCMU_CMD_BIT_EXPIRED bit then cleared
> cmd->se_cmd, but CPU2 copied cmd->se_cmd to se_cmd and saw it was NULL
> but did not yet see the TCMU_CMD_BIT_EXPIRED bit set?

Because the debug rpms for my kernel version were lost, and the crash
tools couldn't be used to have a more accurate analysis.
>
> It looks like, if you do the above patch, the above function will call
> target_complete_cmd and tcmu_handle_completion will call it again, so we
> will have a double free issue.
Maybe the best resolution is to move tcmu_handle_completion() between
spin_lock(&udev->commands_lock) and spin_unlock(&udev->commands_lock)?

Thanks.

BRs
Xiubo Li

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

end of thread, other threads:[~2017-01-04  8:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1483433176-21063-1-git-send-email-lixiubo@cmss.chinamobile.com>
2017-01-04  1:29 ` [PATCH] target/user: Fix use-after-free cmd->se_cmd if the cmd is expired Mike Christie
2017-01-04  8:51   ` [PATCH] target/user: Fix use-after-free cmd->se_cmd if the cmd isexpired Xiubo Li

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.