linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] scsi: target: tcmu: Fix crash on ARM during cmd completion
@ 2020-06-24  8:53 Bodo Stroesser
  2020-06-28  2:17 ` Mike Christie
  2020-06-28  2:31 ` Bart Van Assche
  0 siblings, 2 replies; 5+ messages in thread
From: Bodo Stroesser @ 2020-06-24  8:53 UTC (permalink / raw)
  To: Martin K. Petersen, Mike Christie, linux-scsi, target-devel
  Cc: JiangYu, Daniel Meyerholt, Henry Willard, Bodo Stroesser

If tcmu_handle_completions() has to process a padding shorter
than sizeof(struct tcmu_cmd_entry), the current call to
tcmu_flush_dcache_range() with sizeof(struct tcmu_cmd_entry) as
length param is wrong and causes crashes on e.g. ARM, because
tcmu_flush_dcache_range() in this case calls
	flush_dcache_page(vmalloc_to_page(start));
with start being an invalid address above the end of the
vmalloc'ed area.

The fix is to use the maximum of remaining ring space and
sizeof(struct tcmu_cmd_entry) as the length param.

The patch was tested on kernel 4.19.118.

See https://bugzilla.kernel.org/show_bug.cgi?id=208045#c10

Signed-off-by: Bodo Stroesser <bstroesser@ts.fujitsu.com>
Tested-by: JiangYu <lnsyyj@hotmail.com>
---
 drivers/target/target_core_user.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 3885ca532f8f..82e476d48194 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -1221,7 +1221,14 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev)
 
 		struct tcmu_cmd_entry *entry = (void *) mb + CMDR_OFF + udev->cmdr_last_cleaned;
 
-		tcmu_flush_dcache_range(entry, sizeof(*entry));
+		/*
+		 * Flush max. up to end of cmd ring, since current entry might
+		 * be a padding that is shorter than sizeof(*entry)
+		 */
+		size_t ring_left = head_to_end(udev->cmdr_last_cleaned,
+					       udev->cmdr_size);
+		tcmu_flush_dcache_range(entry, ring_left < sizeof(*entry) ?
+					ring_left : sizeof(*entry));
 
 		if (tcmu_hdr_get_op(entry->hdr.len_op) == TCMU_OP_PAD) {
 			UPDATE_HEAD(udev->cmdr_last_cleaned,
-- 
2.12.3


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

* Re: [PATCH] scsi: target: tcmu: Fix crash on ARM during cmd completion
  2020-06-24  8:53 [PATCH] scsi: target: tcmu: Fix crash on ARM during cmd completion Bodo Stroesser
@ 2020-06-28  2:17 ` Mike Christie
  2020-06-28  2:31 ` Bart Van Assche
  1 sibling, 0 replies; 5+ messages in thread
From: Mike Christie @ 2020-06-28  2:17 UTC (permalink / raw)
  To: Bodo Stroesser, Martin K. Petersen, linux-scsi, target-devel
  Cc: JiangYu, Daniel Meyerholt, Henry Willard

On 6/24/20 3:53 AM, Bodo Stroesser wrote:
> If tcmu_handle_completions() has to process a padding shorter
> than sizeof(struct tcmu_cmd_entry), the current call to
> tcmu_flush_dcache_range() with sizeof(struct tcmu_cmd_entry) as
> length param is wrong and causes crashes on e.g. ARM, because
> tcmu_flush_dcache_range() in this case calls
> 	flush_dcache_page(vmalloc_to_page(start));
> with start being an invalid address above the end of the
> vmalloc'ed area.
> 
> The fix is to use the maximum of remaining ring space and
> sizeof(struct tcmu_cmd_entry) as the length param.
> 
> The patch was tested on kernel 4.19.118.
> 
> See https://urldefense.com/v3/__https://bugzilla.kernel.org/show_bug.cgi?id=208045*c10__;Iw!!GqivPVa7Brio!Kxr99oE0H1b9Ily4SE23nDN7ElSf8Tclo1RILfNSXb6iPh6DA5cSgtBQQsLMBKdrLsmT$ 
> 
> Signed-off-by: Bodo Stroesser <bstroesser@ts.fujitsu.com>
> Tested-by: JiangYu <lnsyyj@hotmail.com>
> ---
>  drivers/target/target_core_user.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
> index 3885ca532f8f..82e476d48194 100644
> --- a/drivers/target/target_core_user.c
> +++ b/drivers/target/target_core_user.c
> @@ -1221,7 +1221,14 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev)
>  
>  		struct tcmu_cmd_entry *entry = (void *) mb + CMDR_OFF + udev->cmdr_last_cleaned;
>  
> -		tcmu_flush_dcache_range(entry, sizeof(*entry));
> +		/*
> +		 * Flush max. up to end of cmd ring, since current entry might
> +		 * be a padding that is shorter than sizeof(*entry)
> +		 */
> +		size_t ring_left = head_to_end(udev->cmdr_last_cleaned,
> +					       udev->cmdr_size);
> +		tcmu_flush_dcache_range(entry, ring_left < sizeof(*entry) ?
> +					ring_left : sizeof(*entry));
>  
>  		if (tcmu_hdr_get_op(entry->hdr.len_op) == TCMU_OP_PAD) {
>  			UPDATE_HEAD(udev->cmdr_last_cleaned,
> 

Thanks again.

Acked-by: Mike Christie <michael.christie@oracle.com>

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

* Re: [PATCH] scsi: target: tcmu: Fix crash on ARM during cmd completion
  2020-06-24  8:53 [PATCH] scsi: target: tcmu: Fix crash on ARM during cmd completion Bodo Stroesser
  2020-06-28  2:17 ` Mike Christie
@ 2020-06-28  2:31 ` Bart Van Assche
  2020-06-28 19:35   ` Michael Christie
  1 sibling, 1 reply; 5+ messages in thread
From: Bart Van Assche @ 2020-06-28  2:31 UTC (permalink / raw)
  To: Bodo Stroesser, Martin K. Petersen, Mike Christie, linux-scsi,
	target-devel
  Cc: JiangYu, Daniel Meyerholt, Henry Willard

On 2020-06-24 01:53, Bodo Stroesser wrote:
> The fix is to use the maximum of remaining ring space and
> sizeof(struct tcmu_cmd_entry) as the length param.
> 

[ ... ]

> +		/*
> +		 * Flush max. up to end of cmd ring, since current entry might
> +		 * be a padding that is shorter than sizeof(*entry)
> +		 */
> +		size_t ring_left = head_to_end(udev->cmdr_last_cleaned,
> +					       udev->cmdr_size);
> +		tcmu_flush_dcache_range(entry, ring_left < sizeof(*entry) ?
> +					ring_left : sizeof(*entry));
>  
>  		if (tcmu_hdr_get_op(entry->hdr.len_op) == TCMU_OP_PAD) {
>  			UPDATE_HEAD(udev->cmdr_last_cleaned,

The patch description says "maximum" but the above formula calculates the
minimum of "ring_left" and sizeof(*entry). Did I perhaps misread this patch?

Thanks,

Bart.



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

* Re: [PATCH] scsi: target: tcmu: Fix crash on ARM during cmd completion
  2020-06-28  2:31 ` Bart Van Assche
@ 2020-06-28 19:35   ` Michael Christie
  2020-06-29  8:53     ` Bodo Stroesser
  0 siblings, 1 reply; 5+ messages in thread
From: Michael Christie @ 2020-06-28 19:35 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Bodo Stroesser, Martin K. Petersen, linux-scsi, target-devel,
	JiangYu, Daniel Meyerholt, Henry Willard



> On Jun 27, 2020, at 9:31 PM, Bart Van Assche <bvanassche@acm.org> wrote:
> 
> On 2020-06-24 01:53, Bodo Stroesser wrote:
>> The fix is to use the maximum of remaining ring space and
>> sizeof(struct tcmu_cmd_entry) as the length param.
>> 
> 
> [ ... ]
> 
>> +		/*
>> +		 * Flush max. up to end of cmd ring, since current entry might
>> +		 * be a padding that is shorter than sizeof(*entry)
>> +		 */
>> +		size_t ring_left = head_to_end(udev->cmdr_last_cleaned,
>> +					       udev->cmdr_size);
>> +		tcmu_flush_dcache_range(entry, ring_left < sizeof(*entry) ?
>> +					ring_left : sizeof(*entry));
>> 
>> 		if (tcmu_hdr_get_op(entry->hdr.len_op) == TCMU_OP_PAD) {
>> 			UPDATE_HEAD(udev->cmdr_last_cleaned,
> 
> The patch description says "maximum" but the above formula calculates the
> minimum of "ring_left" and sizeof(*entry). Did I perhaps misread this patch?

Ah yeah, Bodo probably meant to write what they wrote for the comment above about the max up to the end of the ring and not max of space left and entry size.

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

* Re: [PATCH] scsi: target: tcmu: Fix crash on ARM during cmd completion
  2020-06-28 19:35   ` Michael Christie
@ 2020-06-29  8:53     ` Bodo Stroesser
  0 siblings, 0 replies; 5+ messages in thread
From: Bodo Stroesser @ 2020-06-29  8:53 UTC (permalink / raw)
  To: Michael Christie, Bart Van Assche
  Cc: Martin K. Petersen, linux-scsi, target-devel, JiangYu,
	Daniel Meyerholt, Henry Willard



On 2020-06-28 21:35, Michael Christie wrote:
> 
> 
>> On Jun 27, 2020, at 9:31 PM, Bart Van Assche <bvanassche@acm.org> wrote:
>>
>> On 2020-06-24 01:53, Bodo Stroesser wrote:
>>> The fix is to use the maximum of remaining ring space and
>>> sizeof(struct tcmu_cmd_entry) as the length param.
>>>
>>
>> [ ... ]
>>
>>> +		/*
>>> +		 * Flush max. up to end of cmd ring, since current entry might
>>> +		 * be a padding that is shorter than sizeof(*entry)
>>> +		 */
>>> +		size_t ring_left = head_to_end(udev->cmdr_last_cleaned,
>>> +					       udev->cmdr_size);
>>> +		tcmu_flush_dcache_range(entry, ring_left < sizeof(*entry) ?
>>> +					ring_left : sizeof(*entry));
>>>
>>> 		if (tcmu_hdr_get_op(entry->hdr.len_op) == TCMU_OP_PAD) {
>>> 			UPDATE_HEAD(udev->cmdr_last_cleaned,
>>
>> The patch description says "maximum" but the above formula calculates the
>> minimum of "ring_left" and sizeof(*entry). Did I perhaps misread this patch?
> 
> Ah yeah, Bodo probably meant to write what they wrote for the comment above about the max up to the end of the ring and not max of space left and entry size.
> 

Thank you, you both are right.

While the code and the comment in the code are fine, patch description
is misleading or even wrong.

So I'm going to re-send the patch with fixed description and Mike's
Acked-by.

BR, Bodo

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

end of thread, other threads:[~2020-06-29 23:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-24  8:53 [PATCH] scsi: target: tcmu: Fix crash on ARM during cmd completion Bodo Stroesser
2020-06-28  2:17 ` Mike Christie
2020-06-28  2:31 ` Bart Van Assche
2020-06-28 19:35   ` Michael Christie
2020-06-29  8:53     ` Bodo Stroesser

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).