From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 6A51FD811A4 for ; Thu, 25 Jan 2024 10:48:13 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=b1h5gpH+dq9S9J5EKssr8alip76nnwfPpuKnU4//XJM=; c=relaxed/simple; d=groups.io; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From:In-Reply-To:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Language:Content-Type:Content-Transfer-Encoding; s=20140610; t=1706179692; v=1; b=Ppbjz5zbExYG+ibTwnZs4sQ9O5vqiKVlHsA47EQPcXi022l2epfhrwl/uYyzIa/M175Z9Co8 Rx+cpLPFCNqogbDqYM67KUQVfSSFib67WNZVGAdPZ9F/tKYsBoEVQGa2XW1HfR/UchsuBsqKdtj pwk3v7lCgwvKgSvI0jYv6sDU= X-Received: by 127.0.0.2 with SMTP id 19yrYY7687511xhCupXdDxSK; Thu, 25 Jan 2024 02:48:12 -0800 X-Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.groups.io with SMTP id smtpd.web11.14682.1706179691296370099 for ; Thu, 25 Jan 2024 02:48:11 -0800 X-Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-99-4xtvytdAMUKkxQZago6GUg-1; Thu, 25 Jan 2024 05:48:06 -0500 X-MC-Unique: 4xtvytdAMUKkxQZago6GUg-1 X-Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 30CA7862F7A; Thu, 25 Jan 2024 10:48:06 +0000 (UTC) X-Received: from [10.39.195.100] (unknown [10.39.195.100]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7EA8F492BC9; Thu, 25 Jan 2024 10:48:04 +0000 (UTC) Message-ID: Date: Thu, 25 Jan 2024 11:48:02 +0100 MIME-Version: 1.0 Subject: Re: [edk2-devel] [PATCH] MdeModulePkg/SMM: Support to unregister SMI handler inside SMI handler To: devel@edk2.groups.io, zhiguang.liu@intel.com Cc: Liming Gao , Jiaxin Wu , Ray Ni , Ard Biesheuvel , Sami Mujawar References: <20240124040301.2176-1-zhiguang.liu@intel.com> From: "Laszlo Ersek" In-Reply-To: <20240124040301.2176-1-zhiguang.liu@intel.com> X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,lersek@redhat.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: lIJv19XV0KNklVEZLOMZ9SiQx7686176AA= Content-Language: en-US Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=Ppbjz5zb; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=redhat.com (policy=none) On 1/24/24 05:03, Zhiguang Liu wrote: > To support unregister SMI handler inside SMI handler itself, > get next node before SMI handler is executed, since LIST_ENTRY that > Link points to may be freed if unregister SMI handler in SMI handler > itself. >=20 > Cc: Liming Gao > Cc: Jiaxin Wu > Cc: Ray Ni > Signed-off-by: Zhiguang Liu > --- > MdeModulePkg/Core/PiSmmCore/Smi.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) >=20 > diff --git a/MdeModulePkg/Core/PiSmmCore/Smi.c b/MdeModulePkg/Core/PiSmmC= ore/Smi.c > index 2985f989c3..a75e52b1ae 100644 > --- a/MdeModulePkg/Core/PiSmmCore/Smi.c > +++ b/MdeModulePkg/Core/PiSmmCore/Smi.c > @@ -134,8 +134,14 @@ SmiManage ( > =20 > Head =3D &SmiEntry->SmiHandlers; > =20 > - for (Link =3D Head->ForwardLink; Link !=3D Head; Link =3D Link->Forwar= dLink) { > + for (Link =3D Head->ForwardLink; Link !=3D Head;) { > SmiHandler =3D CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE); > + // > + // To support unregiser SMI handler inside SMI handler itself, > + // get next node before handler is executed, since LIST_ENTRY that > + // Link points to may be freed if unregister SMI handler.=20 > + // > + Link =3D Link->ForwardLink; > =20 > Status =3D SmiHandler->Handler ( > (EFI_HANDLE)SmiHandler, I've had a further thought here. (1) This patch may enable an SMI handler to unregister *itself*, that is, through the following call chain SmiManage() SmiHandler->Handler() SmiHandlerUnRegister() but it still does not ensure *general iterator safety*. Assume that an SMM driver registers two handlers, handler A and handler B. Assume the DispatchHandles for these are stored in global variables in the driver. Then, assume that "handler A" (for whatever reason, under some circumstances) unregisters "handler B". That could still lead to a use-after-free in the SmiManage() loop; is that right? If that driver scenario is plausible, then something like the following would be needed: - a global variable of enum type in "MdeModulePkg/Core/PiSmmCore/Smi.c", with three possible values (NotManaging=3D0, Managing=3D1, CleanupNeeded=3D= 2). - a new "BOOLEAN Deleted" field in SMI_HANDLER - all loops in "Smi.c" iterating over SMI_HANDLERs would have to skip handlers that have been marked as Deleted - in SmiManage(), set the state to Managing (=3D1) before the loop. After the loop, check if the state is CleanupNeeded (=3D2); if so, add an extra pass for actually deleting SMI_HANDLERs from the list that have been marked Deleted. Finally (regardless of the state being Managing (=3D1) or CleanupNeeded (=3D2)), reset the state to NotManaging (=3D0). - in SmiHandlerUnRegister(), if the state is NotManaging (=3D0), delete the handler immediately. Otherwise (i.e., when the state is Managing (=3D1) or CleanupNeeded (=3D2)), set the state to CleanupNeeded (=3D2), and only mark the handler as Deleted. The idea is to inform SmiHandlerUnRegister() whether it's running or not running on the stack of SmiManage(), and to postpone SMI_HANDLER deletion until after the loop finishes in the former case. I'm not sure if real life SmiHandlerUnRegister() usage is worth this complication, however. (2) Independently: does the same issue exist for the StMM core? I seem to be discovering the same problem in MmiManage() [StandaloneMmPkg/Core/Mmi.c]. So, whatever patch we add to the SMM_CORE, should likely be reflected to MM_CORE_STANDALONE too. Adding Ard and Sami to the CC list. Thanks Laszlo -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114384): https://edk2.groups.io/g/devel/message/114384 Mute This Topic: https://groups.io/mt/103925794/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/leave/12367111/7686176/19134562= 12/xyzzy [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-