| From bippy-5f407fcff5a0 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2024-44946: kcm: Serialise kcm_sendmsg() for the same socket. |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| kcm: Serialise kcm_sendmsg() for the same socket. |
| |
| syzkaller reported UAF in kcm_release(). [0] |
| |
| The scenario is |
| |
| 1. Thread A builds a skb with MSG_MORE and sets kcm->seq_skb. |
| |
| 2. Thread A resumes building skb from kcm->seq_skb but is blocked |
| by sk_stream_wait_memory() |
| |
| 3. Thread B calls sendmsg() concurrently, finishes building kcm->seq_skb |
| and puts the skb to the write queue |
| |
| 4. Thread A faces an error and finally frees skb that is already in the |
| write queue |
| |
| 5. kcm_release() does double-free the skb in the write queue |
| |
| When a thread is building a MSG_MORE skb, another thread must not touch it. |
| |
| Let's add a per-sk mutex and serialise kcm_sendmsg(). |
| |
| [0]: |
| BUG: KASAN: slab-use-after-free in __skb_unlink include/linux/skbuff.h:2366 [inline] |
| BUG: KASAN: slab-use-after-free in __skb_dequeue include/linux/skbuff.h:2385 [inline] |
| BUG: KASAN: slab-use-after-free in __skb_queue_purge_reason include/linux/skbuff.h:3175 [inline] |
| BUG: KASAN: slab-use-after-free in __skb_queue_purge include/linux/skbuff.h:3181 [inline] |
| BUG: KASAN: slab-use-after-free in kcm_release+0x170/0x4c8 net/kcm/kcmsock.c:1691 |
| Read of size 8 at addr ffff0000ced0fc80 by task syz-executor329/6167 |
| |
| CPU: 1 PID: 6167 Comm: syz-executor329 Tainted: G B 6.8.0-rc5-syzkaller-g9abbc24128bc #0 |
| Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/25/2024 |
| Call trace: |
| dump_backtrace+0x1b8/0x1e4 arch/arm64/kernel/stacktrace.c:291 |
| show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:298 |
| __dump_stack lib/dump_stack.c:88 [inline] |
| dump_stack_lvl+0xd0/0x124 lib/dump_stack.c:106 |
| print_address_description mm/kasan/report.c:377 [inline] |
| print_report+0x178/0x518 mm/kasan/report.c:488 |
| kasan_report+0xd8/0x138 mm/kasan/report.c:601 |
| __asan_report_load8_noabort+0x20/0x2c mm/kasan/report_generic.c:381 |
| __skb_unlink include/linux/skbuff.h:2366 [inline] |
| __skb_dequeue include/linux/skbuff.h:2385 [inline] |
| __skb_queue_purge_reason include/linux/skbuff.h:3175 [inline] |
| __skb_queue_purge include/linux/skbuff.h:3181 [inline] |
| kcm_release+0x170/0x4c8 net/kcm/kcmsock.c:1691 |
| __sock_release net/socket.c:659 [inline] |
| sock_close+0xa4/0x1e8 net/socket.c:1421 |
| __fput+0x30c/0x738 fs/file_table.c:376 |
| ____fput+0x20/0x30 fs/file_table.c:404 |
| task_work_run+0x230/0x2e0 kernel/task_work.c:180 |
| exit_task_work include/linux/task_work.h:38 [inline] |
| do_exit+0x618/0x1f64 kernel/exit.c:871 |
| do_group_exit+0x194/0x22c kernel/exit.c:1020 |
| get_signal+0x1500/0x15ec kernel/signal.c:2893 |
| do_signal+0x23c/0x3b44 arch/arm64/kernel/signal.c:1249 |
| do_notify_resume+0x74/0x1f4 arch/arm64/kernel/entry-common.c:148 |
| exit_to_user_mode_prepare arch/arm64/kernel/entry-common.c:169 [inline] |
| exit_to_user_mode arch/arm64/kernel/entry-common.c:178 [inline] |
| el0_svc+0xac/0x168 arch/arm64/kernel/entry-common.c:713 |
| el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 |
| el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 |
| |
| Allocated by task 6166: |
| kasan_save_stack mm/kasan/common.c:47 [inline] |
| kasan_save_track+0x40/0x78 mm/kasan/common.c:68 |
| kasan_save_alloc_info+0x70/0x84 mm/kasan/generic.c:626 |
| unpoison_slab_object mm/kasan/common.c:314 [inline] |
| __kasan_slab_alloc+0x74/0x8c mm/kasan/common.c:340 |
| kasan_slab_alloc include/linux/kasan.h:201 [inline] |
| slab_post_alloc_hook mm/slub.c:3813 [inline] |
| slab_alloc_node mm/slub.c:3860 [inline] |
| kmem_cache_alloc_node+0x204/0x4c0 mm/slub.c:3903 |
| __alloc_skb+0x19c/0x3d8 net/core/skbuff.c:641 |
| alloc_skb include/linux/skbuff.h:1296 [inline] |
| kcm_sendmsg+0x1d3c/0x2124 net/kcm/kcmsock.c:783 |
| sock_sendmsg_nosec net/socket.c:730 [inline] |
| __sock_sendmsg net/socket.c:745 [inline] |
| sock_sendmsg+0x220/0x2c0 net/socket.c:768 |
| splice_to_socket+0x7cc/0xd58 fs/splice.c:889 |
| do_splice_from fs/splice.c:941 [inline] |
| direct_splice_actor+0xec/0x1d8 fs/splice.c:1164 |
| splice_direct_to_actor+0x438/0xa0c fs/splice.c:1108 |
| do_splice_direct_actor fs/splice.c:1207 [inline] |
| do_splice_direct+0x1e4/0x304 fs/splice.c:1233 |
| do_sendfile+0x460/0xb3c fs/read_write.c:1295 |
| __do_sys_sendfile64 fs/read_write.c:1362 [inline] |
| __se_sys_sendfile64 fs/read_write.c:1348 [inline] |
| __arm64_sys_sendfile64+0x160/0x3b4 fs/read_write.c:1348 |
| __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline] |
| invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:51 |
| el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:136 |
| do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:155 |
| el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:712 |
| el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 |
| el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 |
| |
| Freed by task 6167: |
| kasan_save_stack mm/kasan/common.c:47 [inline] |
| kasan_save_track+0x40/0x78 mm/kasan/common.c:68 |
| kasan_save_free_info+0x5c/0x74 mm/kasan/generic.c:640 |
| poison_slab_object+0x124/0x18c mm/kasan/common.c:241 |
| __kasan_slab_free+0x3c/0x78 mm/kasan/common.c:257 |
| kasan_slab_free include/linux/kasan.h:184 [inline] |
| slab_free_hook mm/slub.c:2121 [inline] |
| slab_free mm/slub.c:4299 [inline] |
| kmem_cache_free+0x15c/0x3d4 mm/slub.c:4363 |
| kfree_skbmem+0x10c/0x19c |
| __kfree_skb net/core/skbuff.c:1109 [inline] |
| kfree_skb_reason+0x240/0x6f4 net/core/skbuff.c:1144 |
| kfree_skb include/linux/skbuff.h:1244 [inline] |
| kcm_release+0x104/0x4c8 net/kcm/kcmsock.c:1685 |
| __sock_release net/socket.c:659 [inline] |
| sock_close+0xa4/0x1e8 net/socket.c:1421 |
| __fput+0x30c/0x738 fs/file_table.c:376 |
| ____fput+0x20/0x30 fs/file_table.c:404 |
| task_work_run+0x230/0x2e0 kernel/task_work.c:180 |
| exit_task_work include/linux/task_work.h:38 [inline] |
| do_exit+0x618/0x1f64 kernel/exit.c:871 |
| do_group_exit+0x194/0x22c kernel/exit.c:1020 |
| get_signal+0x1500/0x15ec kernel/signal.c:2893 |
| do_signal+0x23c/0x3b44 arch/arm64/kernel/signal.c:1249 |
| do_notify_resume+0x74/0x1f4 arch/arm64/kernel/entry-common.c:148 |
| exit_to_user_mode_prepare arch/arm64/kernel/entry-common.c:169 [inline] |
| exit_to_user_mode arch/arm64/kernel/entry-common.c:178 [inline] |
| el0_svc+0xac/0x168 arch/arm64/kernel/entry-common.c:713 |
| el0t_64_sync_handler+0x84/0xfc arch/arm64/kernel/entry-common.c:730 |
| el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598 |
| |
| The buggy address belongs to the object at ffff0000ced0fc80 |
| which belongs to the cache skbuff_head_cache of size 240 |
| The buggy address is located 0 bytes inside of |
| freed 240-byte region [ffff0000ced0fc80, ffff0000ced0fd70) |
| |
| The buggy address belongs to the physical page: |
| page:00000000d35f4ae4 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10ed0f |
| flags: 0x5ffc00000000800(slab|node=0|zone=2|lastcpupid=0x7ff) |
| page_type: 0xffffffff() |
| raw: 05ffc00000000800 ffff0000c1cbf640 fffffdffc3423100 dead000000000004 |
| raw: 0000000000000000 00000000000c000c 00000001ffffffff 0000000000000000 |
| page dumped because: kasan: bad access detected |
| |
| Memory state around the buggy address: |
| ffff0000ced0fb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb |
| ffff0000ced0fc00: fb fb fb fb fb fb fc fc fc fc fc fc fc fc fc fc |
| >ffff0000ced0fc80: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb |
| ^ |
| ffff0000ced0fd00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fc fc |
| ffff0000ced0fd80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb |
| |
| The Linux kernel CVE team has assigned CVE-2024-44946 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Issue introduced in 4.6 with commit ab7ac4eb9832e32a09f4e8042705484d2fb0aad3 and fixed in 4.19.321 with commit 8c9cdbf600143bd6835c8b8351e5ac956da79aec |
| Issue introduced in 4.6 with commit ab7ac4eb9832e32a09f4e8042705484d2fb0aad3 and fixed in 5.4.283 with commit 6633b17840bf828921254d788ccd15602843fe9b |
| Issue introduced in 4.6 with commit ab7ac4eb9832e32a09f4e8042705484d2fb0aad3 and fixed in 5.10.225 with commit eb06c8d3022ce6738711191c89f9b3e9cfb91914 |
| Issue introduced in 4.6 with commit ab7ac4eb9832e32a09f4e8042705484d2fb0aad3 and fixed in 5.15.166 with commit fa6c23fe6dcac8c8bd63920ee8681292a2bd544e |
| Issue introduced in 4.6 with commit ab7ac4eb9832e32a09f4e8042705484d2fb0aad3 and fixed in 6.1.107 with commit 72da240aafb142630cf16adc803ccdacb3780849 |
| Issue introduced in 4.6 with commit ab7ac4eb9832e32a09f4e8042705484d2fb0aad3 and fixed in 6.6.48 with commit 00425508f30baa5ab6449a1f478480ca7cffa6da |
| Issue introduced in 4.6 with commit ab7ac4eb9832e32a09f4e8042705484d2fb0aad3 and fixed in 6.10.7 with commit 9c8d544ed619f704e2b70e63e08ab75630c2ea23 |
| Issue introduced in 4.6 with commit ab7ac4eb9832e32a09f4e8042705484d2fb0aad3 and fixed in 6.11 with commit 807067bf014d4a3ae2cc55bd3de16f22a01eb580 |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2024-44946 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| include/net/kcm.h |
| net/kcm/kcmsock.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/8c9cdbf600143bd6835c8b8351e5ac956da79aec |
| https://git.kernel.org/stable/c/6633b17840bf828921254d788ccd15602843fe9b |
| https://git.kernel.org/stable/c/eb06c8d3022ce6738711191c89f9b3e9cfb91914 |
| https://git.kernel.org/stable/c/fa6c23fe6dcac8c8bd63920ee8681292a2bd544e |
| https://git.kernel.org/stable/c/72da240aafb142630cf16adc803ccdacb3780849 |
| https://git.kernel.org/stable/c/00425508f30baa5ab6449a1f478480ca7cffa6da |
| https://git.kernel.org/stable/c/9c8d544ed619f704e2b70e63e08ab75630c2ea23 |
| https://git.kernel.org/stable/c/807067bf014d4a3ae2cc55bd3de16f22a01eb580 |