From nobody Tue Dec 30 00:00:55 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5CCA5C61D97 for ; Wed, 22 Nov 2023 12:21:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344152AbjKVMVQ (ORCPT ); Wed, 22 Nov 2023 07:21:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344060AbjKVMUr (ORCPT ); Wed, 22 Nov 2023 07:20:47 -0500 Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48E88198B for ; Wed, 22 Nov 2023 04:20:15 -0800 (PST) Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-1ce5e76912aso43664035ad.2 for ; Wed, 22 Nov 2023 04:20:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700655615; x=1701260415; darn=vger.kernel.org; h=user-agent:content-disposition:mime-version:message-id:subject:cc :to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=IlWhbaH6pQ32e6fkOvxOUl4wt3D1WjG9yqrkaFOp/Vk=; b=K1jcjtSa45n7Bn0w9hEoM2jtN1RwlkGEgc2uzl/QLw8O3nhsZQw0TdyzNBL3bKLqjh C0Mxr9QOwaVpKjIp2NaxxkckK56kK7+huHIT+uycHLTphkEz5KUgqIobGsO5IQDn8Wmn zMlK+VjQ8wUs3MxEM8Yjg7FLw6y/nviZkeyAjOzbgwNqZXGGnY8yyVwB7MMCccLVH3oS UJmWN7rt6YNm/nCZJyM6X0rYznamVQHV0EwA6NXHKdCbyL0rlMxR5A6vdgYePmvIjVzD Ke4zkJt8sqpxzOteKKFFmbJLpvChojyhAAJWeSd+OByc1+HEJr3bL5tYwnm8Yh2Lm7OI zq/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700655615; x=1701260415; h=user-agent:content-disposition:mime-version:message-id:subject:cc :to:from:date:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=IlWhbaH6pQ32e6fkOvxOUl4wt3D1WjG9yqrkaFOp/Vk=; b=GJXZp9gQy6jna4QlacBYe/OgEwg3eMSwCyaiOrkkzBRxw/N7EeqsqyhmkJNQGoJxAS 6IGdvkpBwknbFSuSgz4SmxmQh0mc/PuTi5ajTnxG3pQbb0H7ioYkEdyLn13XxuLZm6Wx naBeU5sjZ3moW6qKpUmjYmA2gs3e8UXnoKc02vzfXXqlcHRKFpsmQEUSFDfb+G021jjs tSx+puJVPG271JHwGlPx7AourATvHqP1VvgX0cRdV/v6GZjf0KEeo4jM/6CbppJVZT4b JvSrnTL1xFx+iOg+rlpwaaLeTcavPkIxMq+nqSxuhUDNlYxNNZGkSrD/SByBztFIlYuE ie/w== X-Gm-Message-State: AOJu0YzK7X4mAXaYB9wjiAurrDMh9TtZ1O9ZdwgGF6HiIFf/W7nTCqAu fhxvYWYyyXkD9Vv+QYUZOPtxyKZcBnpcrg== X-Google-Smtp-Source: AGHT+IFYHWZxF7hp76jWe1gWtmFxAlunhcAXQtLDfMk3Sv5ZsfDFopRc7eJ7xFIbpFS9COcAYcE8pA== X-Received: by 2002:a17:903:2347:b0:1cd:fce2:d702 with SMTP id c7-20020a170903234700b001cdfce2d702mr2535728plh.15.1700655614591; Wed, 22 Nov 2023 04:20:14 -0800 (PST) Received: from libra05 ([143.248.188.128]) by smtp.gmail.com with ESMTPSA id b15-20020a170902d50f00b001ca4c20003dsm4225586plg.69.2023.11.22.04.20.11 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 22 Nov 2023 04:20:13 -0800 (PST) Date: Wed, 22 Nov 2023 21:20:08 +0900 From: Yewon Choi To: Bryan Tan , Vishnu Dasa , VMware PV-Drivers Reviewers , Arnd Bergmann , Greg Kroah-Hartman , linux-kernel@vger.kernel.org Cc: threeearcat@gmail.com Subject: [PATCH] vmci_host: use smp_load_acquire/smp_store_release when accessing vmci_host_dev->ct_type Message-ID: <20231122122005.GA4661@libra05> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.4 (2018-02-28) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In vmci_host.c, missing memory barrier between vmci_host_dev->ct_type and vmci_host_dev->context may cause uninitialized data access. One of possible execution flows is as follows: CPU 1 (vmci_host_do_init_context) =3D=3D=3D=3D=3D vmci_host_dev->context =3D vmci_ctx_create(...) // 1 vmci_host_dev->ct_type =3D VMCIOBJ_CONTEXT; // 2 CPU 2 (vmci_host_poll) =3D=3D=3D=3D=3D if (vmci_host_dev->ct_type =3D=3D VMCIOBJ_CONTEXT) { // 3 context =3D vmci_host_dev->context; // 4 poll_wait(..., &context->host_context.wait_queue, ...); While ct_type serves as a flag indicating that context is initialized, there is no memory barrier which prevents reordering between 1,2 and 3, 4. So it is possible that 4 reads uninitialized vmci_host_dev->context. In this case, the null dereference occurs in poll_wait(). In order to prevent this kind of reordering, we change plain accesses to ct_type into smp_load_acquire() and smp_store_release(). Signed-off-by: Yewon Choi --- drivers/misc/vmw_vmci/vmci_host.c | 40 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci= _host.c index abe79f6fd2a7..e83b6e0fe55b 100644 --- a/drivers/misc/vmw_vmci/vmci_host.c +++ b/drivers/misc/vmw_vmci/vmci_host.c @@ -139,7 +139,7 @@ static int vmci_host_close(struct inode *inode, struct = file *filp) { struct vmci_host_dev *vmci_host_dev =3D filp->private_data; =20 - if (vmci_host_dev->ct_type =3D=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) =3D=3D VMCIOBJ_CONTEXT) { vmci_ctx_destroy(vmci_host_dev->context); vmci_host_dev->context =3D NULL; =20 @@ -168,7 +168,7 @@ static __poll_t vmci_host_poll(struct file *filp, poll_= table *wait) struct vmci_ctx *context; __poll_t mask =3D 0; =20 - if (vmci_host_dev->ct_type =3D=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) =3D=3D VMCIOBJ_CONTEXT) { /* * Read context only if ct_type =3D=3D VMCIOBJ_CONTEXT to make * sure that context is initialized @@ -309,7 +309,7 @@ static int vmci_host_do_init_context(struct vmci_host_d= ev *vmci_host_dev, =20 mutex_lock(&vmci_host_dev->lock); =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_NOT_SET) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_NOT_SET) { vmci_ioctl_err("received VMCI init on initialized handle\n"); retval =3D -EINVAL; goto out; @@ -346,7 +346,13 @@ static int vmci_host_do_init_context(struct vmci_host_= dev *vmci_host_dev, goto out; } =20 - vmci_host_dev->ct_type =3D VMCIOBJ_CONTEXT; + /* + * Make sure that ct_type is written after + * vmci_host_dev->context is initialized. + * + * This pairs with smp_load_acquire() in vmci_host_XXX. + */ + smp_store_release(&vmci_host_dev->ct_type, VMCIOBJ_CONTEXT); atomic_inc(&vmci_host_active_users); =20 vmci_call_vsock_callback(true); @@ -366,7 +372,7 @@ static int vmci_host_do_send_datagram(struct vmci_host_= dev *vmci_host_dev, struct vmci_datagram *dg =3D NULL; u32 cid; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -422,7 +428,7 @@ static int vmci_host_do_receive_datagram(struct vmci_ho= st_dev *vmci_host_dev, int retval; size_t size; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -453,7 +459,7 @@ static int vmci_host_do_alloc_queuepair(struct vmci_hos= t_dev *vmci_host_dev, int vmci_status; int __user *retptr; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -522,7 +528,7 @@ static int vmci_host_do_queuepair_setva(struct vmci_hos= t_dev *vmci_host_dev, struct vmci_qp_set_va_info __user *info =3D uptr; s32 result; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -570,7 +576,7 @@ static int vmci_host_do_queuepair_setpf(struct vmci_hos= t_dev *vmci_host_dev, return -EINVAL; } =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -641,7 +647,7 @@ static int vmci_host_do_qp_detach(struct vmci_host_dev = *vmci_host_dev, struct vmci_qp_dtch_info __user *info =3D uptr; s32 result; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -668,7 +674,7 @@ static int vmci_host_do_ctx_add_notify(struct vmci_host= _dev *vmci_host_dev, s32 result; u32 cid; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -691,7 +697,7 @@ static int vmci_host_do_ctx_remove_notify(struct vmci_h= ost_dev *vmci_host_dev, u32 cid; int result; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -715,7 +721,7 @@ static int vmci_host_do_ctx_get_cpt_state(struct vmci_h= ost_dev *vmci_host_dev, void *cpt_buf; int retval; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -747,7 +753,7 @@ static int vmci_host_do_ctx_set_cpt_state(struct vmci_h= ost_dev *vmci_host_dev, void *cpt_buf; int retval; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -785,7 +791,7 @@ static int vmci_host_do_set_notify(struct vmci_host_dev= *vmci_host_dev, { struct vmci_set_notify_info notify_info; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -818,7 +824,7 @@ static int vmci_host_do_notify_resource(struct vmci_hos= t_dev *vmci_host_dev, return -EINVAL; } =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } @@ -867,7 +873,7 @@ static int vmci_host_do_recv_notifications(struct vmci_= host_dev *vmci_host_dev, u32 cid; int retval =3D 0; =20 - if (vmci_host_dev->ct_type !=3D VMCIOBJ_CONTEXT) { + if (smp_load_acquire(&vmci_host_dev->ct_type) !=3D VMCIOBJ_CONTEXT) { vmci_ioctl_err("only valid for contexts\n"); return -EINVAL; } --=20 2.37.3