From nobody Tue May 7 03:43:45 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+77437+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+77437+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1625203733; cv=none; d=zohomail.com; s=zohoarc; b=a+UqNWzQoPHTaD9ij35uXlF7eDDqlgPZF6JB/DXxsn3zKjU2/zBfjj0Ho3/l44MY6vCJs9gK27cYl58+OP0x+MqG7rMJ4Ci0UaLZ0piqjTCOkqKhfAz7Q4DF9djgMf9QIuaLteePpPp2OR4poyVOnotBNvm0Y83yi/WrMUvFRJI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1625203733; h=Cc:Date:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:Message-ID:Reply-To:Sender:Subject:To; bh=rLrqwor74acDbYiRoteMS7c+YQqtkGU3aOPR7JNb9z4=; b=aOla1AKIOwgF6OMq1daFrdxp1BvALgUk3DQx0Gy4TTn0GtqCxBE7V1vlsGhs3bPpSqQSOLp2YGd/fyX9byONefqmWhkGNBNObTyNvMqxf7+putrjT2paZGbW+vs1Hf4NA4291+1zecxbeVJrLBs+0o5Yjw86D4PGYwPfTcQFIkk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+77437+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1625203733764940.4271666194282; Thu, 1 Jul 2021 22:28:53 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id zTjKYY1788612xE8kS22lcxk; Thu, 01 Jul 2021 22:28:53 -0700 X-Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web08.5820.1625203732760076929 for ; Thu, 01 Jul 2021 22:28:52 -0700 X-IronPort-AV: E=McAfee;i="6200,9189,10032"; a="205668391" X-IronPort-AV: E=Sophos;i="5.83,316,1616482800"; d="scan'208";a="205668391" X-Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Jul 2021 22:28:50 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,316,1616482800"; d="scan'208";a="458017588" X-Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.26]) by fmsmga008.fm.intel.com with ESMTP; 01 Jul 2021 22:28:48 -0700 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Eric Dong , Ray Ni , Laszlo Ersek , Rahul Kumar , Jiewen Yao , Qihua Zhuang , Daquan Dong , Justin Tong , Tom Xu Subject: [edk2-devel] [PATCH] UefiCpuPkg/ExceptionLib: Conditionally clear shadow stack token busy bit Date: Fri, 2 Jul 2021 13:28:40 +0800 Message-Id: <20210702052840.15860-1-w.sheng@intel.com> Precedence: Bulk List-Unsubscribe: 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,w.sheng@intel.com X-Gm-Message-State: xUUPLdBArme7KkZDAFmXWl4ix1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1625203733; bh=svSXNMdXTevu31YRBhbfjq/eGV3tAbSScwanI9ltYt4=; h=Cc:Date:From:Reply-To:Subject:To; b=CneSZoj3VJ9uTwOmaeAesU/UsHZ1dpELMp4qffzsQdZ0n8UIpkRdOO0pWGmWTF4PRzV Y1bpU2hXxfydiLme59EbicNkS5uFFb6FUKrU9AejA/7aGdAKe3VWS8VR2SEjnenJRY+DJ ikLlIQWkxn3q2zZU46djuv9fyI2P90xPUKg= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When enter SMM exception, there will be a stack switch only if the IST field of the interrupt gate is set. When CET shadow stack feature is enabled, if there is a stack switch between SMM exception and SMM, the shadow stack token busy bit needs to be cleared when return from SMM exception to SMM. In UEFI BIOS, only page fault exception does the stack swith when SMM shack guard feature is enabled. The condition of clear shadow stack token busy bit should be SMM stack guard enabled, CET shadows stack feature enabled and page fault exception. The shadow stack token should be initialized by UINT64. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3462 Signed-off-by: Sheng Wei Cc: Eric Dong Cc: Ray Ni Cc: Laszlo Ersek Cc: Rahul Kumar Cc: Jiewen Yao Cc: Qihua Zhuang Cc: Daquan Dong Cc: Justin Tong Cc: Tom Xu Reviewed-by: Eric Dong --- .../X64/Xcode5ExceptionHandlerAsm.nasm | 83 +++++++++++-------= ---- UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c | 2 +- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionH= andlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5Except= ionHandlerAsm.nasm index ebe0eec874..4881a02848 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerA= sm.nasm +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/Xcode5ExceptionHandlerA= sm.nasm @@ -20,6 +20,7 @@ ; =20 %define VC_EXCEPTION 29 +%define PF_EXCEPTION 14 =20 extern ASM_PFX(mErrorCodeFlag) ; Error code flags for exceptions extern ASM_PFX(mDoFarReturnFlag) ; Do far return flag @@ -279,6 +280,46 @@ DrFinish: call ASM_PFX(CommonExceptionHandler) add rsp, 4 * 8 + 8 =20 + ; The follow algorithm is used for clear shadow stack token busy bit. + ; The comment is based on the sample shadow stack. + ; The sample shadow stack layout : + ; Address | Context + ; +-------------------------+ + ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L), a= fter SAVEPREVSSP. + ; +-------------------------+ + ; 0xFD8 | Prev SSP | + ; +-------------------------+ + ; 0xFE0 | RIP | + ; +-------------------------+ + ; 0xFE8 | CS | + ; +-------------------------+ + ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSBSY + ; +-------------------------+ + ; 0xFF8 | 0xFD8|0x02|(LMA & CS.L) | + ; +-------------------------+ + ; Instructions for Intel Control Flow Enforcement Technology (CET) are= supported since NASM version 2.15.01. + cmp qword [ASM_PFX(mDoFarReturnFlag)], 0 + jz CetDone + cmp qword [rbp + 8], PF_EXCEPTION ; check if it is a Page Fault + jnz CetDone + cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0 + jz CetDone + mov rax, cr4 + and rax, 0x800000 ; check if CET is enabled + jz CetDone + ; SSP should be 0xFD8 at this point + mov rax, 0x04 ; advance past cs:lip:prevssp;supervisor s= hadow stack token + INCSSP_RAX ; After this SSP should be 0xFF8 + SAVEPREVSSP ; now the shadow stack restore token will = be created at 0xFD0 + READSSP_RAX ; Read new SSP, SSP should be 0x1000 + sub rax, 0x10 + CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 af= ter this + sub rax, 0x20 + RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP will = be 0xFD0 + mov rax, 0x01 ; Pop off the new save token created + INCSSP_RAX ; SSP should be 0xFD8 now +CetDone: + cli ;; UINT64 ExceptionData; add rsp, 8 @@ -373,47 +414,7 @@ DoReturn: push qword [rax + 0x18] ; save EFLAGS in new location mov rax, [rax] ; restore rax popfq ; restore EFLAGS - - ; The follow algorithm is used for clear shadow stack token busy bit. - ; The comment is based on the sample shadow stack. - ; The sample shadow stack layout : - ; Address | Context - ; +-------------------------+ - ; 0xFD0 | FREE | it is 0xFD8|0x02|(LMA & CS.L), a= fter SAVEPREVSSP. - ; +-------------------------+ - ; 0xFD8 | Prev SSP | - ; +-------------------------+ - ; 0xFE0 | RIP | - ; +-------------------------+ - ; 0xFE8 | CS | - ; +-------------------------+ - ; 0xFF0 | 0xFF0 | BUSY | BUSY flag cleared after CLRSSBSY - ; +-------------------------+ - ; 0xFF8 | 0xFD8|0x02|(LMA & CS.L) | - ; +-------------------------+ - ; Instructions for Intel Control Flow Enforcement Technology (CET) are= supported since NASM version 2.15.01. - push rax ; SSP should be 0xFD8 at this point - cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0 - jz CetDone - mov rax, cr4 - and rax, 0x800000 ; check if CET is enabled - jz CetDone - mov rax, 0x04 ; advance past cs:lip:prevssp;supervisor s= hadow stack token - INCSSP_RAX ; After this SSP should be 0xFF8 - SAVEPREVSSP ; now the shadow stack restore token will = be created at 0xFD0 - READSSP_RAX ; Read new SSP, SSP should be 0x1000 - push rax - sub rax, 0x10 - CLRSSBSY_RAX ; Clear token at 0xFF0, SSP should be 0 af= ter this - sub rax, 0x20 - RSTORSSP_RAX ; Restore to token at 0xFD0, new SSP will = be 0xFD0 - pop rax - mov rax, 0x01 ; Pop off the new save token created - INCSSP_RAX ; SSP should be 0xFD8 now -CetDone: - pop rax ; restore rax - - DB 0x48 ; prefix to composite "retq" with next "re= tf" + DB 0x48 ; prefix to composite "retq" with next "re= tf" retf ; far return DoIret: iretq diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSm= mCpuDxeSmm/X64/SmmFuncsArch.c index 661c1ba294..ca3f5ff91a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c @@ -202,7 +202,7 @@ InitShadowStack ( // Please refer to UefiCpuPkg/Library/CpuExceptionHandlerLib/X64 for= the full stack frame at runtime. // InterruptSsp =3D (UINT32)((UINTN)ShadowStack + EFI_PAGES_TO_SIZE(1) = - sizeof(UINT64)); - *(UINT32 *)(UINTN)InterruptSsp =3D (InterruptSsp - sizeof(UINT64) * = 4) | 0x2; + *(UINT64 *)(UINTN)InterruptSsp =3D (InterruptSsp - sizeof(UINT64) * = 4) | 0x2; mCetInterruptSsp =3D InterruptSsp - sizeof(UINT64); =20 mCetInterruptSspTable =3D (UINT32)(UINTN)(mSmmInterruptSspTables + s= izeof(UINT64) * 8 * CpuIndex); --=20 2.16.2.windows.1 -=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 (#77437): https://edk2.groups.io/g/devel/message/77437 Mute This Topic: https://groups.io/mt/83934335/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-