[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/2] Fix use-after-free in evtchn DPC


  • To: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>, Rafał Wojdyła <omeg@xxxxxxxxxxxxxxxxxxxxxx>, "win-pv-devel@xxxxxxxxxxxxxxxxxxxx" <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Owen Smith <owen.smith@xxxxxxxxxx>
  • Date: Wed, 27 May 2026 09:30:27 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ol+1KZjhLHqRwi/qojjexDfpAcNr45nn6uHMEWYrjaw=; b=Uj2ZMJKfrGINEJ8V8AFC5LxUKRxmq/gOLhvzsyrvqlhByqNFPp81AMiC16tG9EKTDT6HSV+AgI8Ijtoga568/DLwtS2+pkS3uHuPFSI/MOYFJWNSeHbybTXPnaE+XfLnrm+tBgTPJFnbHKqFT3UrgOHev9dXOWAgKkaw/xTy+P2KGPL1L/RnMefEhYvcKaXlzc25ANJtVnvNnXkAnhBwma0KOVUYQs+0+6tYaX/kMLTw/cVfqqt5yZ9daYFPgFLM3blAS+9eOsq45spSsZTRHK5/ZXVEmH7BPS5AT87xZD7p6x6kDnVXHJk7YtVx6kP40WpjifICWxzgWAzh5YJh1Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=fBN87PR2y95so8CpJQplldtNmb16WR1yneE/QRauSfAYwz+0JN+7s8/Mv4cdrIACzClBlk/YtVGnYy9DMMr4Cq+QcxaBibsdFj0D4IzTC+TDg5ALjecRLyhMhZOi57MofsiD7GceOGveUFDXAqbZUNZ3DhqUs706W6+hGUr+PD1+JH1MlSDh1c79XVklz1A7DG+th9VvO1yP9U5ZWTzMO6rUo/jUKWlLNqwp7EfaG5yvs+r8UpLHF6oK0nbWhPSaP/eQQ5wEME8tDpZjXWAolODMibIclvwhswTFFDEFN3vpZZTrYF4qgUqEUz+cbS7uGdsm0TSYKgHviedavMHyhw==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:x-ms-exchange-senderadcheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Delivery-date: Wed, 27 May 2026 09:30:34 +0000
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>
  • Msip_labels:
  • Thread-index: AQHc7SznkKvEC1veTkadT8U5o/IMXLYhGY4AgAB6dACAAAChgIAAB0F7
  • Thread-topic: [PATCH 1/2] Fix use-after-free in evtchn DPC

It does introduce a very small potential race on Open

EvtchnInterruptHandler and therefore EvtchnNotificationDpc can be executed 
immediately after
the call to XENBUS_EVTCHN(Open...), but as Context->Ready could not be set at 
this point, then
the event channel wont get unmasked in the DPC.

Owen

________________________________________
From: win-pv-devel <win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx> on behalf of Tu 
Dinh <ngoc-tu.dinh@xxxxxxxxxx>
Sent: 27 May 2026 10:02 AM
To: Rafał Wojdyła; win-pv-devel@xxxxxxxxxxxxxxxxxxxx
Subject: Re: [PATCH 1/2] Fix use-after-free in evtchn DPC

On 27/05/2026 10:59, Rafał Wojdyła wrote:
>
>
> W dniu 27.05.2026 o 03:41, Tu Dinh pisze:
>> On 26/05/2026 18:30, Rafał Wojdyła wrote:
>>> EvtchnFree() calls XENBUS_EVTCHN(Close) and then KeFlushQueuedDpcs()
>>> to drain any pending DPCs. A DPC queued just before Close returns can
>>> run in the window between Close completing and the flush draining it,
>>> at which point it dereferences Context->Channel inside
>>> XENBUS_EVTCHN(Unmask).
>>>
>>> Also move Context->Fdo initialization to before opening the channel
>>> so Context is fully populated by the time the channel can fire its first
>>> interrupt.
>>>
>>> Signed-off-by: Rafał Wojdyła <omeg@xxxxxxxxxxxxxxxxxxxxxx>
>>> ---
>>>    src/xeniface/ioctl_evtchn.c | 21 ++++++++++++++-------
>>>    src/xeniface/ioctls.h       |  1 +
>>>    2 files changed, 15 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/src/xeniface/ioctl_evtchn.c b/src/xeniface/ioctl_evtchn.c
>>> index 6d63996..e38e25f 100644
>>> --- a/src/xeniface/ioctl_evtchn.c
>>> +++ b/src/xeniface/ioctl_evtchn.c
>>> @@ -58,11 +58,14 @@ EvtchnNotificationDpc(
>>>        KeSetEvent(Context->Event, 0, FALSE);
>>> -    (VOID) XENBUS_EVTCHN(Unmask,
>>> -                         &Context->Fdo->EvtchnInterface,
>>> -                         Context->Channel,
>>> -                         FALSE,
>>> -                         TRUE);
>>> +    if (InterlockedCompareExchange(&Context->Ready, 1, 1) == 1) {
>>> +        (VOID) XENBUS_EVTCHN(Unmask,
>>> +                             &Context->Fdo->EvtchnInterface,
>>> +                             Context->Channel,
>>> +                             FALSE,
>>> +                             TRUE);
>>> +
>>> +    }
>>>    }
>>>    _Function_class_(KSERVICE_ROUTINE)
>>> @@ -103,6 +106,8 @@ EvtchnFree(
>>>        Trace("Context %p, LocalPort %d, FO %p\n",
>>>                           Context, Context->LocalPort, Context-
>>> >FileObject);
>>> +    (VOID) InterlockedExchange(&Context->Ready, 0);
>>> +
>>
>> Shouldn't KeFlushQueuedDpcs() be called before closing the channel?
>> Otherwise there could still be a DPC which has captured Context->Ready=1
>> before InterlockedExchange is called, and then still running
>> concurrently with the XENBUS_EVTCHN(Close).
>  From my understanding KeFlushQueuedDpcs() flushes what's *currently*
> queued, so there would still be a window after it completes and before
> Close() finishes when new events could arrive.

Yes, but that's enough for protecting Context->Channel, as future queued
DPCs will read Context->Ready=0 and won't try to use the channel.


--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.