Thread (5 messages) 5 messages, 2 authors, 2021-05-24

Re: [PATCH] memstick: rtsx_usb_ms: fix UAF

From: Tong Zhang <hidden>
Date: 2021-05-11 16:41:41
Also in: lkml

On Tue, May 11, 2021 at 3:40 AM Ulf Hansson [off-list ref] wrote:
On Sun, 9 May 2021 at 23:54, Tong Zhang [off-list ref] wrote:
quoted
This patch fixes the following issues:
1. memstick_free_host() will free the host, so the use of ms_dev(host) after
it will be a problem. To fix this, move memstick_free_host() after when we
are done with ms_dev(host).
2. if something bad happens in memstick_add_host() and we end up taking
err_out in rtsx_usb_ms_drv_probe(), we'd better avoid running rtsx_usb_ms_drv_remove()
If the ->probe() function returns a negative error code, the driver
core will not invoke the corresponding ->remove() callback.

Looks like you may want to double check that ->probe() doesn't return
0, even in case of failure.
quoted
3. In rtsx_usb_ms_drv_remove(), pm need to be disabled before we remove
and free host otherwise memstick_check will be called and UAF will
happen.

[   11.351173] BUG: KASAN: use-after-free in rtsx_usb_ms_drv_remove+0x94/0x140 [rtsx_usb_ms]
[   11.357077]  rtsx_usb_ms_drv_remove+0x94/0x140 [rtsx_usb_ms]
[   11.357376]  platform_remove+0x2a/0x50
[   11.367531] Freed by task 298:
[   11.368537]  kfree+0xa4/0x2a0
[   11.368711]  device_release+0x51/0xe0
[   11.368905]  kobject_put+0xa2/0x120
[   11.369090]  rtsx_usb_ms_drv_remove+0x8c/0x140 [rtsx_usb_ms]
[   11.369386]  platform_remove+0x2a/0x50

[   12.038408] BUG: KASAN: use-after-free in __mutex_lock.isra.0+0x3ec/0x7c0
[   12.045432]  mutex_lock+0xc9/0xd0
[   12.046080]  memstick_check+0x6a/0x578 [memstick]
[   12.046509]  process_one_work+0x46d/0x750
[   12.052107] Freed by task 297:
[   12.053115]  kfree+0xa4/0x2a0
[   12.053272]  device_release+0x51/0xe0
[   12.053463]  kobject_put+0xa2/0x120
[   12.053647]  rtsx_usb_ms_drv_remove+0xc4/0x140 [rtsx_usb_ms]
[   12.053939]  platform_remove+0x2a/0x50

Signed-off-by: Tong Zhang <redacted>
---
 drivers/memstick/host/rtsx_usb_ms.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c
index 102dbb8080da..851643d007b7 100644
--- a/drivers/memstick/host/rtsx_usb_ms.c
+++ b/drivers/memstick/host/rtsx_usb_ms.c
@@ -799,9 +799,10 @@ static int rtsx_usb_ms_drv_probe(struct platform_device *pdev)

        return 0;
 err_out:
-       memstick_free_host(msh);
        pm_runtime_disable(ms_dev(host));
        pm_runtime_put_noidle(ms_dev(host));
+       memstick_free_host(msh);
+       platform_set_drvdata(pdev, NULL);
        return err;
 }
@@ -811,6 +812,8 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
        struct memstick_host *msh = host->msh;
        int err;

+       if (!host)
+               return 0;
According to my comment above. You should not reach this point, unless
->probe() was successful and returned 0.
quoted
        host->eject = true;
        cancel_work_sync(&host->handle_req);
@@ -828,9 +831,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
        }
        mutex_unlock(&host->host_mutex);

-       memstick_remove_host(msh);
-       memstick_free_host(msh);
-
        /* Balance possible unbalanced usage count
         * e.g. unconditional module removal
         */
@@ -838,10 +838,11 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev)
                pm_runtime_put(ms_dev(host));

        pm_runtime_disable(ms_dev(host));
-       platform_set_drvdata(pdev, NULL);
-
+       memstick_remove_host(msh);
        dev_dbg(ms_dev(host),
                ": Realtek USB Memstick controller has been removed\n");
+       memstick_free_host(msh);
+       platform_set_drvdata(pdev, NULL);

        return 0;
 }
--
2.25.1
Besides the above, the change looks reasonable to me.

Kind regards
Uffe
Thanks Uffe!
I modified the patch as suggested and sent as v2.
Best,
- Tong
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help