Skip to content

Fix: UAF in crypto_run + limit allocation size in adjust_sg_array#104

Open
n4sm wants to merge 11 commits intocryptodev-linux:masterfrom
n4sm:dev
Open

Fix: UAF in crypto_run + limit allocation size in adjust_sg_array#104
n4sm wants to merge 11 commits intocryptodev-linux:masterfrom
n4sm:dev

Conversation

@n4sm
Copy link
Copy Markdown

@n4sm n4sm commented Dec 6, 2025

  • I fixed a UAF in crypto_run, when crypto_run is called asynchronously the process which scheduled the task might get destroyed right after the async request, causing a UAF when __get_userbuf tries to access the target pages. To me there might be a security concern, an attacker might use the UAF to gain access to the address space of a privileged process allowing an arbitrary read / write primitive.
  • I fixed a small bug in adjust_sg_array by restricting the allocation size to 2^10 pages.

n4sm added 8 commits December 6, 2025 02:23
… UAF we just need to crypt with a session and then start crypting again with src == NULL and dst == invalid, this will trigger the release_user_pages at the end of get_userbuf, causing a double free
…ue_work being shared among the cores, cryptask_routine might get executed by a different thread from the one which allocated the kernel_crypt_op, which leads to a UAF on the task and mm fields if thread A exits right after the queue_work in crypto_async_run
@n4sm
Copy link
Copy Markdown
Author

n4sm commented Dec 6, 2025

Actually the UAF in crypto_run is not that easy to patch, the point is that in cryptodev_release, cancel_work_sync gets called but it is already too late. When the program exits, it first frees the task->mm and then it calls cryptodev_release. But during this time window, crypto_run might receive a request from an already freed process:

BUG: KASAN: slab-use-after-free in instrument_atomic_read include/linux/instrumented.h:68 [inline]
BUG: KASAN: slab-use-after-free in atomic_long_read include/linux/atomic/atomic-instrumented.h:3188 [inline]
BUG: KASAN: slab-use-after-free in rwsem_assert_held_nolockdep include/linux/rwsem.h:80 [inline]
BUG: KASAN: slab-use-after-free in rwsem_assert_held include/linux/rwsem.h:197 [inline]
BUG: KASAN: slab-use-after-free in mmap_assert_locked include/linux/mmap_lock.h:65 [inline]
BUG: KASAN: slab-use-after-free in __get_user_pages_locked mm/gup.c:1738 [inline]
BUG: KASAN: slab-use-after-free in get_user_pages_remote+0x139/0x870 mm/gup.c:2661
Read of size 8 at addr ffff88802dc417b8 by task kworker/3:1/107

CPU: 3 UID: 0 PID: 107 Comm: kworker/3:1 Not tainted 6.15.4 #2 PREEMPT(voluntary) 
Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: cryptodev_queue cryptask_routine [cryptodev]
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x7b/0xa0 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:408 [inline]
 print_report+0xd0/0x670 mm/kasan/report.c:521
 kasan_report+0xce/0x100 mm/kasan/report.c:634
 check_region_inline mm/kasan/generic.c:175 [inline]
 kasan_check_range+0x105/0x1b0 mm/kasan/generic.c:189
 instrument_atomic_read include/linux/instrumented.h:68 [inline]
 atomic_long_read include/linux/atomic/atomic-instrumented.h:3188 [inline]
 rwsem_assert_held_nolockdep include/linux/rwsem.h:80 [inline]
 rwsem_assert_held include/linux/rwsem.h:197 [inline]
 mmap_assert_locked include/linux/mmap_lock.h:65 [inline]
 __get_user_pages_locked mm/gup.c:1738 [inline]
 get_user_pages_remote+0x139/0x870 mm/gup.c:2661
 __get_userbuf+0x9c/0x430 drivers/vuln/zc.c:88 [cryptodev]
 get_userbuf+0x283/0xe40 drivers/vuln/zc.c:221 [cryptodev]
 crypto_run+0x6ad/0x12c0 [cryptodev]
 cryptask_routine+0x194/0x440 drivers/vuln/ioctl.c:548 [cryptodev]
 process_one_work+0x61f/0xfd0 kernel/workqueue.c:3238
 process_scheduled_works kernel/workqueue.c:3321 [inline]
 worker_thread+0x8a1/0x1120 kernel/workqueue.c:3402
 kthread+0x33a/0x6b0 kernel/kthread.c:464
 ret_from_fork+0x48/0x80 arch/x86/kernel/process.c:153
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
Freed by task 6965:
 kasan_save_stack+0x33/0x60 mm/kasan/common.c:47
 kasan_save_track+0x14/0x30 mm/kasan/common.c:68
 kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:576
 poison_slab_object mm/kasan/common.c:247 [inline]
 __kasan_slab_free+0x37/0x50 mm/kasan/common.c:264
 kasan_slab_free include/linux/kasan.h:233 [inline]
 slab_free_hook mm/slub.c:2380 [inline]
 slab_free mm/slub.c:4642 [inline]
 kmem_cache_free+0xc4/0x360 mm/slub.c:4744
 mmdrop include/linux/sched/mm.h:55 [inline]
 __mmput kernel/fork.c:1391 [inline]
 mmput+0x275/0x2f0 kernel/fork.c:1402
 exit_mm kernel/exit.c:589 [inline]
 do_exit+0x83b/0x2470 kernel/exit.c:949
 do_group_exit+0xba/0x250 kernel/exit.c:1103
 get_signal+0x17cd/0x19b0 kernel/signal.c:3034
 arch_do_signal_or_restart+0x90/0x640 arch/x86/kernel/signal.c:337
 exit_to_user_mode_loop kernel/entry/common.c:111 [inline]
 exit_to_user_mode_prepare include/linux/entry-common.h:329 [inline]
 __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline]
 syscall_exit_to_user_mode+0xb0/0x130 kernel/entry/common.c:218
 do_syscall_64+0xab/0x1a0 arch/x86/entry/syscall_64.c:100
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

My patch is actually wrong given crypto_run is meant to receive remote requests from other threads, we need to make sure that crypto_run receives a valid task and mm.

@n4sm n4sm marked this pull request as draft December 7, 2025 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant