Skip to content

Commit a30dc6c

Browse files
Wang Haigregkh
authored andcommitted
VMCI: fix NULL pointer dereference when unmapping queue pair
I got a NULL pointer dereference report when doing fuzz test: Call Trace: qp_release_pages+0xae/0x130 qp_host_unregister_user_memory.isra.25+0x2d/0x80 vmci_qp_broker_unmap+0x191/0x320 ? vmci_host_do_alloc_queuepair.isra.9+0x1c0/0x1c0 vmci_host_unlocked_ioctl+0x59f/0xd50 ? do_vfs_ioctl+0x14b/0xa10 ? tomoyo_file_ioctl+0x28/0x30 ? vmci_host_do_alloc_queuepair.isra.9+0x1c0/0x1c0 __x64_sys_ioctl+0xea/0x120 do_syscall_64+0x34/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae When a queue pair is created by the following call, it will not register the user memory if the page_store is NULL, and the entry->state will be set to VMCIQPB_CREATED_NO_MEM. vmci_host_unlocked_ioctl vmci_host_do_alloc_queuepair vmci_qp_broker_alloc qp_broker_alloc qp_broker_create // set entry->state = VMCIQPB_CREATED_NO_MEM; When unmapping this queue pair, qp_host_unregister_user_memory() will be called to unregister the non-existent user memory, which will result in a null pointer reference. It will also change VMCIQPB_CREATED_NO_MEM to VMCIQPB_CREATED_MEM, which should not be present in this operation. Only when the qp broker has mem, it can unregister the user memory when unmapping the qp broker. Only when the qp broker has no mem, it can register the user memory when mapping the qp broker. Fixes: 06164d2 ("VMCI: queue pairs implementation.") Cc: stable <[email protected]> Reported-by: Hulk Robot <[email protected]> Reviewed-by: Jorgen Hansen <[email protected]> Signed-off-by: Wang Hai <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent f8cefea commit a30dc6c

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

drivers/misc/vmw_vmci/vmci_queue_pair.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2243,7 +2243,8 @@ int vmci_qp_broker_map(struct vmci_handle handle,
22432243

22442244
result = VMCI_SUCCESS;
22452245

2246-
if (context_id != VMCI_HOST_CONTEXT_ID) {
2246+
if (context_id != VMCI_HOST_CONTEXT_ID &&
2247+
!QPBROKERSTATE_HAS_MEM(entry)) {
22472248
struct vmci_qp_page_store page_store;
22482249

22492250
page_store.pages = guest_mem;
@@ -2350,7 +2351,8 @@ int vmci_qp_broker_unmap(struct vmci_handle handle,
23502351
goto out;
23512352
}
23522353

2353-
if (context_id != VMCI_HOST_CONTEXT_ID) {
2354+
if (context_id != VMCI_HOST_CONTEXT_ID &&
2355+
QPBROKERSTATE_HAS_MEM(entry)) {
23542356
qp_acquire_queue_mutex(entry->produce_q);
23552357
result = qp_save_headers(entry);
23562358
if (result < VMCI_SUCCESS)

0 commit comments

Comments
 (0)