linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH -next V2 0/2] fix two bugs when trying rmmod sata_fsl
@ 2021-11-20  3:34 Baokun Li
  2021-11-20  3:34 ` [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when " Baokun Li
  2021-11-20  3:34 ` [PATCH -next V2 2/2] sata_fsl: fix warning in remove_proc_entry " Baokun Li
  0 siblings, 2 replies; 8+ messages in thread
From: Baokun Li @ 2021-11-20  3:34 UTC (permalink / raw)
  To: damien.lemoal, axboe, tj, linux-ide, linux-kernel
  Cc: sergei.shtylyov, yebin10, libaokun1, yukuai3

V1->V2:
	Fixed the check on the return value of platform_get_irq().
	And propagate errors up to sata_fsl_probe()'s callers.

Baokun Li (2):
  sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
  sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl

 drivers/ata/sata_fsl.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

-- 
2.31.1


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

* [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
  2021-11-20  3:34 [PATCH -next V2 0/2] fix two bugs when trying rmmod sata_fsl Baokun Li
@ 2021-11-20  3:34 ` Baokun Li
  2021-11-20 12:01   ` Sergei Shtylyov
  2021-11-20  3:34 ` [PATCH -next V2 2/2] sata_fsl: fix warning in remove_proc_entry " Baokun Li
  1 sibling, 1 reply; 8+ messages in thread
From: Baokun Li @ 2021-11-20  3:34 UTC (permalink / raw)
  To: damien.lemoal, axboe, tj, linux-ide, linux-kernel
  Cc: sergei.shtylyov, yebin10, libaokun1, yukuai3, Hulk Robot

When the `rmmod sata_fsl.ko` command is executed in the PPC64 GNU/Linux,
a bug is reported:
 ==================================================================
 BUG: Unable to handle kernel data access on read at 0x80000800805b502c
 Oops: Kernel access of bad area, sig: 11 [#1]
 NIP [c0000000000388a4] .ioread32+0x4/0x20
 LR [80000000000c6034] .sata_fsl_port_stop+0x44/0xe0 [sata_fsl]
 Call Trace:
  .free_irq+0x1c/0x4e0 (unreliable)
  .ata_host_stop+0x74/0xd0 [libata]
  .release_nodes+0x330/0x3f0
  .device_release_driver_internal+0x178/0x2c0
  .driver_detach+0x64/0xd0
  .bus_remove_driver+0x70/0xf0
  .driver_unregister+0x38/0x80
  .platform_driver_unregister+0x14/0x30
  .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
  .__se_sys_delete_module+0x1ec/0x2d0
  .system_call_exception+0xfc/0x1f0
  system_call_common+0xf8/0x200
 ==================================================================

The triggering of the BUG is shown in the following stack:

driver_detach
  device_release_driver_internal
    __device_release_driver
      drv->remove(dev) --> platform_drv_remove/platform_remove
        drv->remove(dev) --> sata_fsl_remove
          iounmap(host_priv->hcr_base);			<---- unmap
          kfree(host_priv);                             <---- free
      devres_release_all
        release_nodes
          dr->node.release(dev, dr->data) --> ata_host_stop
            ap->ops->port_stop(ap) --> sata_fsl_port_stop
                ioread32(hcr_base + HCONTROL)           <---- UAF
            host->ops->host_stop(host)

The iounmap(host_priv->hcr_base) and kfree(host_priv) commands should
not be executed in drv->remove. These commands should be executed in
host_stop after port_stop. Therefore, we move these commands to the
new function sata_fsl_host_stop and bind the new function to host_stop
by referring to achi.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
---
 drivers/ata/sata_fsl.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index e5838b23c9e0..30759fd1c3a2 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -1430,12 +1430,25 @@ static struct ata_port_operations sata_fsl_ops = {
 	.pmp_detach = sata_fsl_pmp_detach,
 };
 
+static void sata_fsl_host_stop(struct ata_host *host)
+{
+	struct sata_fsl_host_priv *host_priv = host->private_data;
+
+	iounmap(host_priv->hcr_base);
+	kfree(host_priv);
+}
+
+static struct ata_port_operations sata_fsl_platform_ops = {
+	.inherits       = &sata_fsl_ops,
+	.host_stop      = sata_fsl_host_stop,
+};
+
 static const struct ata_port_info sata_fsl_port_info[] = {
 	{
 	 .flags = SATA_FSL_HOST_FLAGS,
 	 .pio_mask = ATA_PIO4,
 	 .udma_mask = ATA_UDMA6,
-	 .port_ops = &sata_fsl_ops,
+	 .port_ops = &sata_fsl_platform_ops,
 	 },
 };
 
@@ -1558,8 +1571,6 @@ static int sata_fsl_remove(struct platform_device *ofdev)
 	ata_host_detach(host);
 
 	irq_dispose_mapping(host_priv->irq);
-	iounmap(host_priv->hcr_base);
-	kfree(host_priv);
 
 	return 0;
 }
-- 
2.31.1


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

* [PATCH -next V2 2/2] sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl
  2021-11-20  3:34 [PATCH -next V2 0/2] fix two bugs when trying rmmod sata_fsl Baokun Li
  2021-11-20  3:34 ` [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when " Baokun Li
@ 2021-11-20  3:34 ` Baokun Li
  1 sibling, 0 replies; 8+ messages in thread
From: Baokun Li @ 2021-11-20  3:34 UTC (permalink / raw)
  To: damien.lemoal, axboe, tj, linux-ide, linux-kernel
  Cc: sergei.shtylyov, yebin10, libaokun1, yukuai3, Hulk Robot

Trying to remove the fsl-sata module in the PPC64 GNU/Linux
leads to the following warning:
 ------------[ cut here ]------------
 remove_proc_entry: removing non-empty directory 'irq/69',
   leaking at least 'fsl-sata[ff0221000.sata]'
 WARNING: CPU: 3 PID: 1048 at fs/proc/generic.c:722
   .remove_proc_entry+0x20c/0x220
 IRQMASK: 0
 NIP [c00000000033826c] .remove_proc_entry+0x20c/0x220
 LR [c000000000338268] .remove_proc_entry+0x208/0x220
 Call Trace:
  .remove_proc_entry+0x208/0x220 (unreliable)
  .unregister_irq_proc+0x104/0x140
  .free_desc+0x44/0xb0
  .irq_free_descs+0x9c/0xf0
  .irq_dispose_mapping+0x64/0xa0
  .sata_fsl_remove+0x58/0xa0 [sata_fsl]
  .platform_drv_remove+0x40/0x90
  .device_release_driver_internal+0x160/0x2c0
  .driver_detach+0x64/0xd0
  .bus_remove_driver+0x70/0xf0
  .driver_unregister+0x38/0x80
  .platform_driver_unregister+0x14/0x30
  .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
 ---[ end trace 0ea876d4076908f5 ]---

The driver creates the mapping by calling irq_of_parse_and_map(),
so it also has to dispose the mapping. But the easy way out is to
simply use platform_get_irq() instead of irq_of_parse_map(). Also
we should adapt return value checking and propagate error values.

In this case the mapping is not managed by the device but by
the of core, so the device has not to dispose the mapping.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
---
V1->V2:
	Adapt return value checking and propagate error values

 drivers/ata/sata_fsl.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 30759fd1c3a2..f850dfab72a6 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -1493,8 +1493,9 @@ static int sata_fsl_probe(struct platform_device *ofdev)
 	host_priv->ssr_base = ssr_base;
 	host_priv->csr_base = csr_base;
 
-	irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
-	if (!irq) {
+	irq = platform_get_irq(ofdev, 0);
+	if (irq < 0) {
+		retval = irq;
 		dev_err(&ofdev->dev, "invalid irq from platform\n");
 		goto error_exit_with_cleanup;
 	}
@@ -1570,8 +1571,6 @@ static int sata_fsl_remove(struct platform_device *ofdev)
 
 	ata_host_detach(host);
 
-	irq_dispose_mapping(host_priv->irq);
-
 	return 0;
 }
 
-- 
2.31.1


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

* Re: [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
  2021-11-20  3:34 ` [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when " Baokun Li
@ 2021-11-20 12:01   ` Sergei Shtylyov
       [not found]     ` <4d2712d3-00a1-6220-0a86-8580b2f89d03@huawei.com>
  0 siblings, 1 reply; 8+ messages in thread
From: Sergei Shtylyov @ 2021-11-20 12:01 UTC (permalink / raw)
  To: Baokun Li, damien.lemoal, axboe, tj, linux-ide, linux-kernel
  Cc: yebin10, yukuai3, Hulk Robot

Hello!

On 20.11.2021 6:34, Baokun Li wrote:

> When the `rmmod sata_fsl.ko` command is executed in the PPC64 GNU/Linux,
> a bug is reported:
>   ==================================================================
>   BUG: Unable to handle kernel data access on read at 0x80000800805b502c
>   Oops: Kernel access of bad area, sig: 11 [#1]
>   NIP [c0000000000388a4] .ioread32+0x4/0x20
>   LR [80000000000c6034] .sata_fsl_port_stop+0x44/0xe0 [sata_fsl]
>   Call Trace:
>    .free_irq+0x1c/0x4e0 (unreliable)
>    .ata_host_stop+0x74/0xd0 [libata]
>    .release_nodes+0x330/0x3f0
>    .device_release_driver_internal+0x178/0x2c0
>    .driver_detach+0x64/0xd0
>    .bus_remove_driver+0x70/0xf0
>    .driver_unregister+0x38/0x80
>    .platform_driver_unregister+0x14/0x30
>    .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
>    .__se_sys_delete_module+0x1ec/0x2d0
>    .system_call_exception+0xfc/0x1f0
>    system_call_common+0xf8/0x200
>   ==================================================================
> 
> The triggering of the BUG is shown in the following stack:
> 
> driver_detach
>    device_release_driver_internal
>      __device_release_driver
>        drv->remove(dev) --> platform_drv_remove/platform_remove
>          drv->remove(dev) --> sata_fsl_remove
>            iounmap(host_priv->hcr_base);			<---- unmap
>            kfree(host_priv);                             <---- free
>        devres_release_all
>          release_nodes
>            dr->node.release(dev, dr->data) --> ata_host_stop
>              ap->ops->port_stop(ap) --> sata_fsl_port_stop
>                  ioread32(hcr_base + HCONTROL)           <---- UAF
>              host->ops->host_stop(host)
> 
> The iounmap(host_priv->hcr_base) and kfree(host_priv) commands should

    s/commands/functions/?

> not be executed in drv->remove. These commands should be executed in
> host_stop after port_stop. Therefore, we move these commands to the
> new function sata_fsl_host_stop and bind the new function to host_stop
> by referring to achi.

    You mean AHCI? I don't see where you reference ahci (or achi)...

> Reported-by: Hulk Robot <hulkci@huawei.com>
> Signed-off-by: Baokun Li <libaokun1@huawei.com>

    Doesn't this need to go into the stable trees?

> ---
>   drivers/ata/sata_fsl.c | 17 ++++++++++++++---
>   1 file changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
> index e5838b23c9e0..30759fd1c3a2 100644
> --- a/drivers/ata/sata_fsl.c
> +++ b/drivers/ata/sata_fsl.c
> @@ -1430,12 +1430,25 @@ static struct ata_port_operations sata_fsl_ops = {
>   	.pmp_detach = sata_fsl_pmp_detach,
>   };
>   
> +static void sata_fsl_host_stop(struct ata_host *host)
> +{
> +	struct sata_fsl_host_priv *host_priv = host->private_data;
> +
> +	iounmap(host_priv->hcr_base);
> +	kfree(host_priv);
> +}
> +
> +static struct ata_port_operations sata_fsl_platform_ops = {
> +	.inherits       = &sata_fsl_ops,
> +	.host_stop      = sata_fsl_host_stop,

    Why not just add it to the initializer for sata_fsl_ops?

[...]

MBR, Sergei

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

* Re: [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
       [not found]     ` <4d2712d3-00a1-6220-0a86-8580b2f89d03@huawei.com>
@ 2021-11-22  2:33       ` Damien Le Moal
  2021-11-22  2:50         ` libaokun (A)
  2021-11-22 18:58       ` Sergei Shtylyov
  1 sibling, 1 reply; 8+ messages in thread
From: Damien Le Moal @ 2021-11-22  2:33 UTC (permalink / raw)
  To: libaokun (A), Sergei Shtylyov, axboe, tj, linux-ide, linux-kernel
  Cc: yebin10, yukuai3, Hulk Robot

On 2021/11/22 11:03, libaokun (A) wrote:
> 在 2021/11/20 20:01, Sergei Shtylyov 写道:
>> Hello!
>>
>> On 20.11.2021 6:34, Baokun Li wrote:
>>
>>> When the `rmmod sata_fsl.ko` command is executed in the PPC64 GNU/Linux,
>>> a bug is reported:
>>>   ==================================================================
>>>   BUG: Unable to handle kernel data access on read at 0x80000800805b502c
>>>   Oops: Kernel access of bad area, sig: 11 [#1]
>>>   NIP [c0000000000388a4] .ioread32+0x4/0x20
>>>   LR [80000000000c6034] .sata_fsl_port_stop+0x44/0xe0 [sata_fsl]
>>>   Call Trace:
>>>    .free_irq+0x1c/0x4e0 (unreliable)
>>>    .ata_host_stop+0x74/0xd0 [libata]
>>>    .release_nodes+0x330/0x3f0
>>>    .device_release_driver_internal+0x178/0x2c0
>>>    .driver_detach+0x64/0xd0
>>>    .bus_remove_driver+0x70/0xf0
>>>    .driver_unregister+0x38/0x80
>>>    .platform_driver_unregister+0x14/0x30
>>>    .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
>>>    .__se_sys_delete_module+0x1ec/0x2d0
>>>    .system_call_exception+0xfc/0x1f0
>>>    system_call_common+0xf8/0x200
>>>   ==================================================================
>>>
>>> The triggering of the BUG is shown in the following stack:
>>>
>>> driver_detach
>>>    device_release_driver_internal
>>>      __device_release_driver
>>>        drv->remove(dev) --> platform_drv_remove/platform_remove
>>>          drv->remove(dev) --> sata_fsl_remove
>>>            iounmap(host_priv->hcr_base);            <---- unmap
>>>            kfree(host_priv);                             <---- free
>>>        devres_release_all
>>>          release_nodes
>>>            dr->node.release(dev, dr->data) --> ata_host_stop
>>>              ap->ops->port_stop(ap) --> sata_fsl_port_stop
>>>                  ioread32(hcr_base + HCONTROL)           <---- UAF
>>>              host->ops->host_stop(host)
>>>
>>> The iounmap(host_priv->hcr_base) and kfree(host_priv) commands should
>>
>>   s/commands/functions/?
> 
> OK! I'm going to modify this in V3.
> 
> 
>>
>>> not be executed in drv->remove. These commands should be executed in
>>> host_stop after port_stop. Therefore, we move these commands to the
>>> new function sata_fsl_host_stop and bind the new function to host_stop
>>> by referring to achi.
>>
>>   You mean AHCI? I don't see where you reference ahci (or achi)...
> 
> Yes, it's AHCI, I'm sorry for a spelling error here..
> 
> ahci_platform_ops in drivers/ata/libahci_platform.c
> 
> 
>>
>>> Reported-by: Hulk Robot <hulkci@huawei.com>
>>> Signed-off-by: Baokun Li <libaokun1@huawei.com>
>>
>>   Doesn't this need to go into the stable trees?
> 
> 
> I felt it was needed because the bug was triggered in a very simple way,
> 
> although PPC linux is rare these days.
> 
> And I will add
> 
> Fixes: faf0b2e5afe7 ("drivers/ata: add support to Freescale 3.0Gbps SATA Controller").

Also add:

Cc: stable@vger.kernel.org


> 
>>
>>> ---
>>>   drivers/ata/sata_fsl.c | 17 ++++++++++++++---
>>>   1 file changed, 14 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
>>> index e5838b23c9e0..30759fd1c3a2 100644
>>> --- a/drivers/ata/sata_fsl.c
>>> +++ b/drivers/ata/sata_fsl.c
>>> @@ -1430,12 +1430,25 @@ static struct ata_port_operations sata_fsl_ops = {
>>>       .pmp_detach = sata_fsl_pmp_detach,
>>>   };
>>>   +static void sata_fsl_host_stop(struct ata_host *host)
>>> +{
>>> +    struct sata_fsl_host_priv *host_priv = host->private_data;
>>> +
>>> +    iounmap(host_priv->hcr_base);
>>> +    kfree(host_priv);
>>> +}
>>> +
>>> +static struct ata_port_operations sata_fsl_platform_ops = {
>>> +    .inherits       = &sata_fsl_ops,
>>> +    .host_stop      = sata_fsl_host_stop,
>>
>>   Why not just add it to the initializer for sata_fsl_ops?
> 
> 
> This is the AHCI of the reference.
> 
> Most ATA drivers add host_stop to to the  initializer for  xxx_platform_ops,
> 
> such as ahci_platform_ops, ahci_brcm_platform_ops, and ahci_imx_ops.
> 
> It feels like this separates the port operation from the host operation,
> 
> making the hierarchy of the code clearer.
> 
> 
>>
>> [...]
>>
>> MBR, Sergei
>> .
> 
> 
> Thank you very much for your advice.
> 
> If there's nothing else to modify, I'll send a patch V3.
> 
> -- 
> With Best Regards,
> Baokun Li
> .
> 


-- 
Damien Le Moal
Western Digital Research

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

* Re: [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
  2021-11-22  2:33       ` Damien Le Moal
@ 2021-11-22  2:50         ` libaokun (A)
  0 siblings, 0 replies; 8+ messages in thread
From: libaokun (A) @ 2021-11-22  2:50 UTC (permalink / raw)
  To: Damien Le Moal, Sergei Shtylyov, axboe, tj, linux-ide, linux-kernel
  Cc: yebin10, yukuai3, Hulk Robot

在 2021/11/22 10:33, Damien Le Moal 写道:
> On 2021/11/22 11:03, libaokun (A) wrote:
>> 在 2021/11/20 20:01, Sergei Shtylyov 写道:
>>> Hello!
>>>
>>> On 20.11.2021 6:34, Baokun Li wrote:
>>>
>>>> When the `rmmod sata_fsl.ko` command is executed in the PPC64 GNU/Linux,
>>>> a bug is reported:
>>>>    ==================================================================
>>>>    BUG: Unable to handle kernel data access on read at 0x80000800805b502c
>>>>    Oops: Kernel access of bad area, sig: 11 [#1]
>>>>    NIP [c0000000000388a4] .ioread32+0x4/0x20
>>>>    LR [80000000000c6034] .sata_fsl_port_stop+0x44/0xe0 [sata_fsl]
>>>>    Call Trace:
>>>>     .free_irq+0x1c/0x4e0 (unreliable)
>>>>     .ata_host_stop+0x74/0xd0 [libata]
>>>>     .release_nodes+0x330/0x3f0
>>>>     .device_release_driver_internal+0x178/0x2c0
>>>>     .driver_detach+0x64/0xd0
>>>>     .bus_remove_driver+0x70/0xf0
>>>>     .driver_unregister+0x38/0x80
>>>>     .platform_driver_unregister+0x14/0x30
>>>>     .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
>>>>     .__se_sys_delete_module+0x1ec/0x2d0
>>>>     .system_call_exception+0xfc/0x1f0
>>>>     system_call_common+0xf8/0x200
>>>>    ==================================================================
>>>>
>>>> The triggering of the BUG is shown in the following stack:
>>>>
>>>> driver_detach
>>>>     device_release_driver_internal
>>>>       __device_release_driver
>>>>         drv->remove(dev) --> platform_drv_remove/platform_remove
>>>>           drv->remove(dev) --> sata_fsl_remove
>>>>             iounmap(host_priv->hcr_base);            <---- unmap
>>>>             kfree(host_priv);                             <---- free
>>>>         devres_release_all
>>>>           release_nodes
>>>>             dr->node.release(dev, dr->data) --> ata_host_stop
>>>>               ap->ops->port_stop(ap) --> sata_fsl_port_stop
>>>>                   ioread32(hcr_base + HCONTROL)           <---- UAF
>>>>               host->ops->host_stop(host)
>>>>
>>>> The iounmap(host_priv->hcr_base) and kfree(host_priv) commands should
>>>    s/commands/functions/?
>> OK! I'm going to modify this in V3.
>>
>>
>>>> not be executed in drv->remove. These commands should be executed in
>>>> host_stop after port_stop. Therefore, we move these commands to the
>>>> new function sata_fsl_host_stop and bind the new function to host_stop
>>>> by referring to achi.
>>>    You mean AHCI? I don't see where you reference ahci (or achi)...
>> Yes, it's AHCI, I'm sorry for a spelling error here..
>>
>> ahci_platform_ops in drivers/ata/libahci_platform.c
>>
>>
>>>> Reported-by: Hulk Robot <hulkci@huawei.com>
>>>> Signed-off-by: Baokun Li <libaokun1@huawei.com>
>>>    Doesn't this need to go into the stable trees?
>>
>> I felt it was needed because the bug was triggered in a very simple way,
>>
>> although PPC linux is rare these days.
>>
>> And I will add
>>
>> Fixes: faf0b2e5afe7 ("drivers/ata: add support to Freescale 3.0Gbps SATA Controller").
> Also add:
>
> Cc: stable@vger.kernel.org
>
>
>>>> ---
>>>>    drivers/ata/sata_fsl.c | 17 ++++++++++++++---
>>>>    1 file changed, 14 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
>>>> index e5838b23c9e0..30759fd1c3a2 100644
>>>> --- a/drivers/ata/sata_fsl.c
>>>> +++ b/drivers/ata/sata_fsl.c
>>>> @@ -1430,12 +1430,25 @@ static struct ata_port_operations sata_fsl_ops = {
>>>>        .pmp_detach = sata_fsl_pmp_detach,
>>>>    };
>>>>    +static void sata_fsl_host_stop(struct ata_host *host)
>>>> +{
>>>> +    struct sata_fsl_host_priv *host_priv = host->private_data;
>>>> +
>>>> +    iounmap(host_priv->hcr_base);
>>>> +    kfree(host_priv);
>>>> +}
>>>> +
>>>> +static struct ata_port_operations sata_fsl_platform_ops = {
>>>> +    .inherits       = &sata_fsl_ops,
>>>> +    .host_stop      = sata_fsl_host_stop,
>>>    Why not just add it to the initializer for sata_fsl_ops?
>>
>> This is the AHCI of the reference.
>>
>> Most ATA drivers add host_stop to to the  initializer for  xxx_platform_ops,
>>
>> such as ahci_platform_ops, ahci_brcm_platform_ops, and ahci_imx_ops.
>>
>> It feels like this separates the port operation from the host operation,
>>
>> making the hierarchy of the code clearer.
>>
>>
>>> [...]
>>>
>>> MBR, Sergei
>>> .
>>
>> Thank you very much for your advice.
>>
>> If there's nothing else to modify, I'll send a patch V3.
>>
>> -- 
>> With Best Regards,
>> Baokun Li
>> .
>>
>

Thank you very much for your advice.

I'm about to send a patch V3 with the changes suggested by you.

-- 
With Best Regards,
Baokun Li
.


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

* Re: [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
       [not found]     ` <4d2712d3-00a1-6220-0a86-8580b2f89d03@huawei.com>
  2021-11-22  2:33       ` Damien Le Moal
@ 2021-11-22 18:58       ` Sergei Shtylyov
  2021-11-23  1:11         ` libaokun (A)
  1 sibling, 1 reply; 8+ messages in thread
From: Sergei Shtylyov @ 2021-11-22 18:58 UTC (permalink / raw)
  To: libaokun (A), damien.lemoal, axboe, tj, linux-ide, linux-kernel
  Cc: yebin10, yukuai3, Hulk Robot

Hello!

On 22.11.2021 5:03, libaokun (A) wrote:

>>> When the `rmmod sata_fsl.ko` command is executed in the PPC64 GNU/Linux,
>>> a bug is reported:
>>> ==================================================================
>>>   BUG: Unable to handle kernel data access on read at 0x80000800805b502c
>>>   Oops: Kernel access of bad area, sig: 11 [#1]
>>>   NIP [c0000000000388a4] .ioread32+0x4/0x20
>>>   LR [80000000000c6034] .sata_fsl_port_stop+0x44/0xe0 [sata_fsl]
>>>   Call Trace:
>>>    .free_irq+0x1c/0x4e0 (unreliable)
>>>    .ata_host_stop+0x74/0xd0 [libata]
>>>    .release_nodes+0x330/0x3f0
>>>    .device_release_driver_internal+0x178/0x2c0
>>>    .driver_detach+0x64/0xd0
>>>    .bus_remove_driver+0x70/0xf0
>>>    .driver_unregister+0x38/0x80
>>>    .platform_driver_unregister+0x14/0x30
>>>    .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
>>>    .__se_sys_delete_module+0x1ec/0x2d0
>>>    .system_call_exception+0xfc/0x1f0
>>>    system_call_common+0xf8/0x200
>>> ==================================================================
>>>
>>> The triggering of the BUG is shown in the following stack:
>>>
>>> driver_detach
>>>    device_release_driver_internal
>>>      __device_release_driver
>>>        drv->remove(dev) --> platform_drv_remove/platform_remove
>>>          drv->remove(dev) --> sata_fsl_remove
>>>            iounmap(host_priv->hcr_base);            <---- unmap
>>>            kfree(host_priv); <---- free
>>>        devres_release_all
>>>          release_nodes
>>>            dr->node.release(dev, dr->data) --> ata_host_stop
>>>              ap->ops->port_stop(ap) --> sata_fsl_port_stop
>>>                  ioread32(hcr_base + HCONTROL) <---- UAF
>>>              host->ops->host_stop(host)
>>>
>>> The iounmap(host_priv->hcr_base) and kfree(host_priv) commands should
>>
>>   s/commands/functions/?
> 
> OK! I'm going to modify this in V3.
> 
>>
>>> not be executed in drv->remove. These commands should be executed in
>>> host_stop after port_stop. Therefore, we move these commands to the
>>> new function sata_fsl_host_stop and bind the new function to host_stop
>>> by referring to achi.
>>
>>   You mean AHCI? I don't see where you reference ahci (or achi)...
> 
> Yes, it's AHCI, I'm sorry for a spelling error here..
> 
> ahci_platform_ops in drivers/ata/libahci_platform.c

   You should have (at least) written "the AHCI platform driver"...

[...]
>>> diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
>>> index e5838b23c9e0..30759fd1c3a2 100644
>>> --- a/drivers/ata/sata_fsl.c
>>> +++ b/drivers/ata/sata_fsl.c
>>> @@ -1430,12 +1430,25 @@ static struct ata_port_operations sata_fsl_ops = {
>>>       .pmp_detach = sata_fsl_pmp_detach,
>>>   };
>>>   +static void sata_fsl_host_stop(struct ata_host *host)
>>> +{
>>> +    struct sata_fsl_host_priv *host_priv = host->private_data;
>>> +
>>> +    iounmap(host_priv->hcr_base);
>>> +    kfree(host_priv);
>>> +}
>>> +
>>> +static struct ata_port_operations sata_fsl_platform_ops = {
>>> +    .inherits       = &sata_fsl_ops,
>>> +    .host_stop      = sata_fsl_host_stop,
>>
>>   Why not just add it to the initializer for sata_fsl_ops?
> 
> This is the AHCI of the reference.
> 
> Most ATA drivers add host_stop to to the  initializer for xxx_platform_ops,

    Most? Even if so, I guess they add it this way because they're in the 
separate modules with the ops they inherit -- in this case it's not so.

> such as ahci_platform_ops, ahci_brcm_platform_ops, and ahci_imx_ops.

    Note that these are all AHCI drivers, not just (more general) ATA.

> It feels like this separates the port operation from the host operation,

    Why separate them? The 'struct ata_port_operations' embraces many 
different aspects of ATA, the arguments do not always include a 'struct 
*ata_port' (I don't quite like that part in libata).

> making the hierarchy of the code clearer.

    Clear as mud. In your case, there's no separate modules in play, so 
blindly parroting what the AHCI platform drivers do gives you nothing but 
memory waste... :-(

>> [...]
>>
>> MBR, Sergei
>> .
> 
> 
> Thank you very much for your advice.

    You're welcome. :-)

> If there's nothing else to modify, I'll send a patch V3.

    Please use a single structure, it's already large enough to have 2 of them 
in the same module for no good reason.

> -- 
> With Best Regards,
> Baokun Li

MBR, Sergei

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

* Re: [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
  2021-11-22 18:58       ` Sergei Shtylyov
@ 2021-11-23  1:11         ` libaokun (A)
  0 siblings, 0 replies; 8+ messages in thread
From: libaokun (A) @ 2021-11-23  1:11 UTC (permalink / raw)
  To: Sergei Shtylyov, damien.lemoal, axboe, tj, linux-ide, linux-kernel
  Cc: yebin10, yukuai3, Hulk Robot

在 2021/11/23 2:58, Sergei Shtylyov 写道:
> Hello!
>
> On 22.11.2021 5:03, libaokun (A) wrote:
>
>>>> When the `rmmod sata_fsl.ko` command is executed in the PPC64 
>>>> GNU/Linux,
>>>> a bug is reported:
>>>> ==================================================================
>>>>   BUG: Unable to handle kernel data access on read at 
>>>> 0x80000800805b502c
>>>>   Oops: Kernel access of bad area, sig: 11 [#1]
>>>>   NIP [c0000000000388a4] .ioread32+0x4/0x20
>>>>   LR [80000000000c6034] .sata_fsl_port_stop+0x44/0xe0 [sata_fsl]
>>>>   Call Trace:
>>>>    .free_irq+0x1c/0x4e0 (unreliable)
>>>>    .ata_host_stop+0x74/0xd0 [libata]
>>>>    .release_nodes+0x330/0x3f0
>>>>    .device_release_driver_internal+0x178/0x2c0
>>>>    .driver_detach+0x64/0xd0
>>>>    .bus_remove_driver+0x70/0xf0
>>>>    .driver_unregister+0x38/0x80
>>>>    .platform_driver_unregister+0x14/0x30
>>>>    .fsl_sata_driver_exit+0x18/0xa20 [sata_fsl]
>>>>    .__se_sys_delete_module+0x1ec/0x2d0
>>>>    .system_call_exception+0xfc/0x1f0
>>>>    system_call_common+0xf8/0x200
>>>> ==================================================================
>>>>
>>>> The triggering of the BUG is shown in the following stack:
>>>>
>>>> driver_detach
>>>>    device_release_driver_internal
>>>>      __device_release_driver
>>>>        drv->remove(dev) --> platform_drv_remove/platform_remove
>>>>          drv->remove(dev) --> sata_fsl_remove
>>>>            iounmap(host_priv->hcr_base); <---- unmap
>>>>            kfree(host_priv); <---- free
>>>>        devres_release_all
>>>>          release_nodes
>>>>            dr->node.release(dev, dr->data) --> ata_host_stop
>>>>              ap->ops->port_stop(ap) --> sata_fsl_port_stop
>>>>                  ioread32(hcr_base + HCONTROL) <---- UAF
>>>>              host->ops->host_stop(host)
>>>>
>>>> The iounmap(host_priv->hcr_base) and kfree(host_priv) commands should
>>>
>>>   s/commands/functions/?
>>
>> OK! I'm going to modify this in V3.
>>
>>>
>>>> not be executed in drv->remove. These commands should be executed in
>>>> host_stop after port_stop. Therefore, we move these commands to the
>>>> new function sata_fsl_host_stop and bind the new function to host_stop
>>>> by referring to achi.
>>>
>>>   You mean AHCI? I don't see where you reference ahci (or achi)...
>>
>> Yes, it's AHCI, I'm sorry for a spelling error here..
>>
>> ahci_platform_ops in drivers/ata/libahci_platform.c
>
>  You should have (at least) written "the AHCI platform driver"...
>
> [...]
>>>> diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
>>>> index e5838b23c9e0..30759fd1c3a2 100644
>>>> --- a/drivers/ata/sata_fsl.c
>>>> +++ b/drivers/ata/sata_fsl.c
>>>> @@ -1430,12 +1430,25 @@ static struct ata_port_operations 
>>>> sata_fsl_ops = {
>>>>       .pmp_detach = sata_fsl_pmp_detach,
>>>>   };
>>>>   +static void sata_fsl_host_stop(struct ata_host *host)
>>>> +{
>>>> +    struct sata_fsl_host_priv *host_priv = host->private_data;
>>>> +
>>>> +    iounmap(host_priv->hcr_base);
>>>> +    kfree(host_priv);
>>>> +}
>>>> +
>>>> +static struct ata_port_operations sata_fsl_platform_ops = {
>>>> +    .inherits       = &sata_fsl_ops,
>>>> +    .host_stop      = sata_fsl_host_stop,
>>>
>>>   Why not just add it to the initializer for sata_fsl_ops?
>>
>> This is the AHCI of the reference.
>>
>> Most ATA drivers add host_stop to to the  initializer for 
>> xxx_platform_ops,
>
>   Most? Even if so, I guess they add it this way because they're in 
> the separate modules with the ops they inherit -- in this case it's 
> not so.
>
>> such as ahci_platform_ops, ahci_brcm_platform_ops, and ahci_imx_ops.
>
>   Note that these are all AHCI drivers, not just (more general) ATA.
>
>> It feels like this separates the port operation from the host operation,
>
>   Why separate them? The 'struct ata_port_operations' embraces many 
> different aspects of ATA, the arguments do not always include a 
> 'struct *ata_port' (I don't quite like that part in libata).
>
>> making the hierarchy of the code clearer.
>
>   Clear as mud. In your case, there's no separate modules in play, so 
> blindly parroting what the AHCI platform drivers do gives you nothing 
> but memory waste... :-(
>
>>> [...]
>>>
>>> MBR, Sergei
>>> .
>>
>>
>> Thank you very much for your advice.
>
>   You're welcome. :-)
>
>> If there's nothing else to modify, I'll send a patch V3.
>
>   Please use a single structure, it's already large enough to have 2 
> of them in the same module for no good reason.
>
>> -- 
>> With Best Regards,
>> Baokun Li
>
> MBR, Sergei
> .


Thank you very much for your advice.

I'm about to send a patch V4 with the changes suggested by you.

-- 
With Best Regards,
Baokun Li


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

end of thread, other threads:[~2021-11-23  1:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-20  3:34 [PATCH -next V2 0/2] fix two bugs when trying rmmod sata_fsl Baokun Li
2021-11-20  3:34 ` [PATCH -next V2 1/2] sata_fsl: fix UAF in sata_fsl_port_stop when " Baokun Li
2021-11-20 12:01   ` Sergei Shtylyov
     [not found]     ` <4d2712d3-00a1-6220-0a86-8580b2f89d03@huawei.com>
2021-11-22  2:33       ` Damien Le Moal
2021-11-22  2:50         ` libaokun (A)
2021-11-22 18:58       ` Sergei Shtylyov
2021-11-23  1:11         ` libaokun (A)
2021-11-20  3:34 ` [PATCH -next V2 2/2] sata_fsl: fix warning in remove_proc_entry " Baokun Li

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).