From: Lee Jones <[email protected]>
[ Upstream commit 2d1e952a2b8e5e92d8d55ac88a7cf7ca5ea591ad ]
If a user can make copy_from_user() fail, there is a potential for
UAF/DF due to a lack of locking around the allocation, use and freeing
of the data buffers.
This issue is not theoretical. I managed to author a POC for it:
BUG: KASAN: double-free in kfree+0x5c/0xac
Free of addr ffff29280be5de00 by task poc/356
CPU: 1 PID: 356 Comm: poc Not tainted 6.1.0-00001-g961aa6552c04-dirty #20
Hardware name: linux,dummy-virt (DT)
Call trace:
dump_backtrace.part.0+0xe0/0xf0
show_stack+0x18/0x40
dump_stack_lvl+0x64/0x80
print_report+0x188/0x48c
kasan_report_invalid_free+0xa0/0xc0
____kasan_slab_free+0x174/0x1b0
__kasan_slab_free+0x18/0x24
__kmem_cache_free+0x130/0x2e0
kfree+0x5c/0xac
mbox_test_message_write+0x208/0x29c
full_proxy_write+0x90/0xf0
vfs_write+0x154/0x440
ksys_write+0xcc/0x180
__arm64_sys_write+0x44/0x60
invoke_syscall+0x60/0x190
el0_svc_common.constprop.0+0x7c/0x160
do_el0_svc+0x40/0xf0
el0_svc+0x2c/0x6c
el0t_64_sync_handler+0xf4/0x120
el0t_64_sync+0x18c/0x190
Allocated by task 356:
kasan_save_stack+0x3c/0x70
kasan_set_track+0x2c/0x40
kasan_save_alloc_info+0x24/0x34
__kasan_kmalloc+0xb8/0xc0
kmalloc_trace+0x58/0x70
mbox_test_message_write+0x6c/0x29c
full_proxy_write+0x90/0xf0
vfs_write+0x154/0x440
ksys_write+0xcc/0x180
__arm64_sys_write+0x44/0x60
invoke_syscall+0x60/0x190
el0_svc_common.constprop.0+0x7c/0x160
do_el0_svc+0x40/0xf0
el0_svc+0x2c/0x6c
el0t_64_sync_handler+0xf4/0x120
el0t_64_sync+0x18c/0x190
Freed by task 357:
kasan_save_stack+0x3c/0x70
kasan_set_track+0x2c/0x40
kasan_save_free_info+0x38/0x5c
____kasan_slab_free+0x13c/0x1b0
__kasan_slab_free+0x18/0x24
__kmem_cache_free+0x130/0x2e0
kfree+0x5c/0xac
mbox_test_message_write+0x208/0x29c
full_proxy_write+0x90/0xf0
vfs_write+0x154/0x440
ksys_write+0xcc/0x180
__arm64_sys_write+0x44/0x60
invoke_syscall+0x60/0x190
el0_svc_common.constprop.0+0x7c/0x160
do_el0_svc+0x40/0xf0
el0_svc+0x2c/0x6c
el0t_64_sync_handler+0xf4/0x120
el0t_64_sync+0x18c/0x190
Signed-off-by: Lee Jones <[email protected]>
Signed-off-by: Jassi Brar <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/mailbox/mailbox-test.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
index 4555d678fadda..6dd5b9614452b 100644
--- a/drivers/mailbox/mailbox-test.c
+++ b/drivers/mailbox/mailbox-test.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/mailbox_client.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
@@ -38,6 +39,7 @@ struct mbox_test_device {
char *signal;
char *message;
spinlock_t lock;
+ struct mutex mutex;
wait_queue_head_t waitq;
struct fasync_struct *async_queue;
struct dentry *root_debugfs_dir;
@@ -110,6 +112,8 @@ static ssize_t mbox_test_message_write(struct file *filp,
return -EINVAL;
}
+ mutex_lock(&tdev->mutex);
+
tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
if (!tdev->message)
return -ENOMEM;
@@ -144,6 +148,8 @@ static ssize_t mbox_test_message_write(struct file *filp,
kfree(tdev->message);
tdev->signal = NULL;
+ mutex_unlock(&tdev->mutex);
+
return ret < 0 ? ret : count;
}
@@ -392,6 +398,7 @@ static int mbox_test_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, tdev);
spin_lock_init(&tdev->lock);
+ mutex_init(&tdev->mutex);
if (tdev->rx_channel) {
tdev->rx_buffer = devm_kzalloc(&pdev->dev,
--
2.39.2
On Fri, 19 May 2023, Sasha Levin wrote:
> From: Lee Jones <[email protected]>
>
> [ Upstream commit 2d1e952a2b8e5e92d8d55ac88a7cf7ca5ea591ad ]
>
> If a user can make copy_from_user() fail, there is a potential for
> UAF/DF due to a lack of locking around the allocation, use and freeing
> of the data buffers.
>
> This issue is not theoretical. I managed to author a POC for it:
>
> BUG: KASAN: double-free in kfree+0x5c/0xac
> Free of addr ffff29280be5de00 by task poc/356
> CPU: 1 PID: 356 Comm: poc Not tainted 6.1.0-00001-g961aa6552c04-dirty #20
> Hardware name: linux,dummy-virt (DT)
> Call trace:
> dump_backtrace.part.0+0xe0/0xf0
> show_stack+0x18/0x40
> dump_stack_lvl+0x64/0x80
> print_report+0x188/0x48c
> kasan_report_invalid_free+0xa0/0xc0
> ____kasan_slab_free+0x174/0x1b0
> __kasan_slab_free+0x18/0x24
> __kmem_cache_free+0x130/0x2e0
> kfree+0x5c/0xac
> mbox_test_message_write+0x208/0x29c
> full_proxy_write+0x90/0xf0
> vfs_write+0x154/0x440
> ksys_write+0xcc/0x180
> __arm64_sys_write+0x44/0x60
> invoke_syscall+0x60/0x190
> el0_svc_common.constprop.0+0x7c/0x160
> do_el0_svc+0x40/0xf0
> el0_svc+0x2c/0x6c
> el0t_64_sync_handler+0xf4/0x120
> el0t_64_sync+0x18c/0x190
>
> Allocated by task 356:
> kasan_save_stack+0x3c/0x70
> kasan_set_track+0x2c/0x40
> kasan_save_alloc_info+0x24/0x34
> __kasan_kmalloc+0xb8/0xc0
> kmalloc_trace+0x58/0x70
> mbox_test_message_write+0x6c/0x29c
> full_proxy_write+0x90/0xf0
> vfs_write+0x154/0x440
> ksys_write+0xcc/0x180
> __arm64_sys_write+0x44/0x60
> invoke_syscall+0x60/0x190
> el0_svc_common.constprop.0+0x7c/0x160
> do_el0_svc+0x40/0xf0
> el0_svc+0x2c/0x6c
> el0t_64_sync_handler+0xf4/0x120
> el0t_64_sync+0x18c/0x190
>
> Freed by task 357:
> kasan_save_stack+0x3c/0x70
> kasan_set_track+0x2c/0x40
> kasan_save_free_info+0x38/0x5c
> ____kasan_slab_free+0x13c/0x1b0
> __kasan_slab_free+0x18/0x24
> __kmem_cache_free+0x130/0x2e0
> kfree+0x5c/0xac
> mbox_test_message_write+0x208/0x29c
> full_proxy_write+0x90/0xf0
> vfs_write+0x154/0x440
> ksys_write+0xcc/0x180
> __arm64_sys_write+0x44/0x60
> invoke_syscall+0x60/0x190
> el0_svc_common.constprop.0+0x7c/0x160
> do_el0_svc+0x40/0xf0
> el0_svc+0x2c/0x6c
> el0t_64_sync_handler+0xf4/0x120
> el0t_64_sync+0x18c/0x190
>
> Signed-off-by: Lee Jones <[email protected]>
> Signed-off-by: Jassi Brar <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---
> drivers/mailbox/mailbox-test.c | 7 +++++++
> 1 file changed, 7 insertions(+)
Could you ensure the follow-up patch is also applied to all branches please?
8fe72b76db79d mailbox: mailbox-test: fix a locking issue in mbox_test_message_write()
--
Lee Jones [李琼斯]