* [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases @ 2022-12-13 15:55 Lee, Chun-Yi 2022-12-14 6:15 ` Gerd Hoffmann 2022-12-14 6:53 ` Yao, Jiewen 0 siblings, 2 replies; 8+ messages in thread From: Lee, Chun-Yi @ 2022-12-13 15:55 UTC (permalink / raw) To: devel Cc: Min M Xu, Gerd Hoffmann, Jiewen Yao, Tom Lendacky, James Bottomley, Erdem Aktas, Lee, Chun-Yi In the commit 4f173db8b4 "OvmfPkg/PlatformInitLib: Add functions for EmuVariableNvStore" , it introduced a PlatformValidateNvVarStore() function for checking the integrity of NvVarStore. In some cases when the VariableHeader->StartId is VARIABLE_DATA, the VariableHeader->State is not just one of the four primary states: VAR_IN_DELETED_TRANSITION, VAR_DELETED, VAR_HEADER_VALID_ONLY, VAR_ADDED. The state may combined two or three states, e.g. 0x3C = (VAR_IN_DELETED_TRANSITION & VAR_ADDED) & VAR_DELETED or 0x3D = VAR_ADDED & VAR_DELETED When the variable store has those variables, then system booting/rebooting will hangs in a ASSERT: NvVarStore Variable header State was invalid. ASSERT /mnt/working/source_code-git/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(819): ((BOOLEAN)(0==1)) Adding more log to UpdateVariable() and PlatformValidateNvVarStore(), we can see there have some variables have 0x3C or 0x3D state in store. e.g. UpdateVariable(), VariableName=BootOrder L1871, State=0000003F <-- VAR_ADDED State &= VAR_DELETED=0000003D FlushHobVariableToFlash(), VariableName=BootOrder ... UpdateVariable(), VariableName=InitialAttemptOrder L1977, State=0000003F State &= VAR_IN_DELETED_TRANSITION=0000003E L2376, State=0000003E State &= VAR_DELETED=0000003C FlushHobVariableToFlash(), VariableName=InitialAttemptOrder ... UpdateVariable(), VariableName=ConIn L1977, State=0000003F State &= VAR_IN_DELETED_TRANSITION=0000003E L2376, State=0000003E State &= VAR_DELETED=0000003C FlushHobVariableToFlash(), VariableName=ConIn ... So, only allowing the four primary states is not enough. This patch adds two more combined states to the valid states list: (VAR_IN_DELETED_TRANSITION & VAR_ADDED) & VAR_DELETED = 0x3c VAR_ADDED & VAR_DELETED = 0x3d Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> --- OvmfPkg/Library/PlatformInitLib/Platform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c b/OvmfPkg/Library/PlatformInitLib/Platform.c index 77f22de046..2af4cefd10 100644 --- a/OvmfPkg/Library/PlatformInitLib/Platform.c +++ b/OvmfPkg/Library/PlatformInitLib/Platform.c @@ -705,7 +705,9 @@ PlatformValidateNvVarStore ( if (!((VariableHeader->State == VAR_IN_DELETED_TRANSITION) || (VariableHeader->State == VAR_DELETED) || (VariableHeader->State == VAR_HEADER_VALID_ONLY) || - (VariableHeader->State == VAR_ADDED))) + (VariableHeader->State == VAR_ADDED) || + (VariableHeader->State == (VAR_ADDED & VAR_DELETED)) || + (VariableHeader->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION & VAR_DELETED)))) { DEBUG ((DEBUG_ERROR, "NvVarStore Variable header State was invalid.\n")); return FALSE; -- 2.35.3 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases 2022-12-13 15:55 [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases Lee, Chun-Yi @ 2022-12-14 6:15 ` Gerd Hoffmann 2022-12-14 13:46 ` [edk2-devel] " joeyli 2022-12-14 6:53 ` Yao, Jiewen 1 sibling, 1 reply; 8+ messages in thread From: Gerd Hoffmann @ 2022-12-14 6:15 UTC (permalink / raw) To: Lee, Chun-Yi Cc: devel, Min M Xu, Jiewen Yao, Tom Lendacky, James Bottomley, Erdem Aktas, Lee, Chun-Yi Hi, > When the variable store has those variables, then system booting/rebooting will > hangs in a ASSERT: > > NvVarStore Variable header State was invalid. > ASSERT > /mnt/working/source_code-git/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(819): > ((BOOLEAN)(0==1)) I'm wondering how you manage to trigger this assert? > Adding more log to UpdateVariable() and PlatformValidateNvVarStore(), we > can see there have some variables have 0x3C or 0x3D state in store. > e.g. PlatformValidateNvVarStore() validates the varstore in ROM before copying it to RAM. The normal UpdateVariable() cycle changes the copy in RAM ... take care, Gerd ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [edk2-devel] [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases 2022-12-14 6:15 ` Gerd Hoffmann @ 2022-12-14 13:46 ` joeyli 2022-12-14 14:12 ` Gerd Hoffmann 2022-12-14 14:24 ` joeyli 0 siblings, 2 replies; 8+ messages in thread From: joeyli @ 2022-12-14 13:46 UTC (permalink / raw) To: devel, kraxel Cc: Lee, Chun-Yi, Min M Xu, Jiewen Yao, Tom Lendacky, James Bottomley, Erdem Aktas Hi Gerd, Thanks for your response! On Wed, Dec 14, 2022 at 07:15:28AM +0100, Gerd Hoffmann via groups.io wrote: > Hi, > > > When the variable store has those variables, then system booting/rebooting will > > hangs in a ASSERT: > > > > NvVarStore Variable header State was invalid. > > ASSERT > > /mnt/working/source_code-git/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(819): > > ((BOOLEAN)(0==1)) > > I'm wondering how you manage to trigger this assert? > Sorry for I forgot to put my testing environment in patch description. My testing is on qemu with OVMF: - edk2-master or edk2-stable202211 build --verbose --debug=1 -D SECURE_BOOT_ENABLE -D TPM_ENABLE -D TPM_CONFIG_ENABLE \ -D NETWORK_IP6_ENABLE -D NETWORK_HTTP_BOOT_ENABLE -a X64 -b DEBUG -t GCC5 \ -p OvmfPkg/OvmfPkgX64.dsc -D FD_SIZE_4MB -D NETWORK_TLS_ENABLE - qemu-7.1.0 with libvirt-8.0.0 pc-q35 with pflash type and nvram: <type arch='x86_64' machine='pc-q35-3.1'>hvm</type> <loader readonly='yes' secure='no' type='pflash'>/usr/share/qemu/ovmf-x86_64-code.bin</loader> <nvram template='/usr/share/qemu/ovmf-x86_64-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram> - grub2 2.06 and Linux kernel 6.1.0-rc5 Two test cases, both of them can reproduce the assert: - First booting to grub2 menu, then "virsh destroy" the guest. The second boot hangs in the "NvVarStore Variable header State was invalid." assert - First boot to Linux kernel 6.1.0-rc5, bash shell prompt shows up. Then run shutdown or reboot command. The second boot hangs in in the "NvVarStore Variable header State was invalid." assert > > Adding more log to UpdateVariable() and PlatformValidateNvVarStore(), we > > can see there have some variables have 0x3C or 0x3D state in store. > > e.g. > > PlatformValidateNvVarStore() validates the varstore in ROM before > copying it to RAM. The normal UpdateVariable() cycle changes the > copy in RAM ... > Yes, in the first boot, those variables have 0x3C or 0x3C state be created. After shutdown or reboot, system hangs in the second boot. The assert shows up in debug log. Thanks a lot! Joey Lee ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [edk2-devel] [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases 2022-12-14 13:46 ` [edk2-devel] " joeyli @ 2022-12-14 14:12 ` Gerd Hoffmann 2022-12-14 15:24 ` joeyli 2022-12-14 14:24 ` joeyli 1 sibling, 1 reply; 8+ messages in thread From: Gerd Hoffmann @ 2022-12-14 14:12 UTC (permalink / raw) To: joeyli Cc: devel, Lee, Chun-Yi, Min M Xu, Jiewen Yao, Tom Lendacky, James Bottomley, Erdem Aktas > Sorry for I forgot to put my testing environment in patch description. > My testing is on qemu with OVMF: > > - edk2-master or edk2-stable202211 > build --verbose --debug=1 -D SECURE_BOOT_ENABLE -D TPM_ENABLE -D TPM_CONFIG_ENABLE \ > -D NETWORK_IP6_ENABLE -D NETWORK_HTTP_BOOT_ENABLE -a X64 -b DEBUG -t GCC5 \ > -p OvmfPkg/OvmfPkgX64.dsc -D FD_SIZE_4MB -D NETWORK_TLS_ENABLE > > - qemu-7.1.0 with libvirt-8.0.0 > pc-q35 with pflash type and nvram: > <type arch='x86_64' machine='pc-q35-3.1'>hvm</type> > <loader readonly='yes' secure='no' type='pflash'>/usr/share/qemu/ovmf-x86_64-code.bin</loader> > <nvram template='/usr/share/qemu/ovmf-x86_64-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram> That is not secure. You have unprotected writable flash. You can either use a build with SMM_REQUIRE=TRUE and run with secure='yes', so only the firmware in SMM mode can write to flash. Or you run with both code and vars read-only. Easiest is <loader>OVMF.fd</loader>. Or you disable secure boot (SECURE_BOOT_ENABLE=FALSE) in your builds. You still have unprotected writable flash then, but it isn't a security hole any more. And the assert isn't triggered either because that code path is only executed for secure boot builds. take care, Gerd ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [edk2-devel] [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases 2022-12-14 14:12 ` Gerd Hoffmann @ 2022-12-14 15:24 ` joeyli 0 siblings, 0 replies; 8+ messages in thread From: joeyli @ 2022-12-14 15:24 UTC (permalink / raw) To: Gerd Hoffmann Cc: devel, Lee, Chun-Yi, Min M Xu, Jiewen Yao, Tom Lendacky, James Bottomley, Erdem Aktas On Wed, Dec 14, 2022 at 03:12:22PM +0100, Gerd Hoffmann wrote: > > Sorry for I forgot to put my testing environment in patch description. > > My testing is on qemu with OVMF: > > > > - edk2-master or edk2-stable202211 > > build --verbose --debug=1 -D SECURE_BOOT_ENABLE -D TPM_ENABLE -D TPM_CONFIG_ENABLE \ > > -D NETWORK_IP6_ENABLE -D NETWORK_HTTP_BOOT_ENABLE -a X64 -b DEBUG -t GCC5 \ > > -p OvmfPkg/OvmfPkgX64.dsc -D FD_SIZE_4MB -D NETWORK_TLS_ENABLE > > > > - qemu-7.1.0 with libvirt-8.0.0 > > pc-q35 with pflash type and nvram: > > <type arch='x86_64' machine='pc-q35-3.1'>hvm</type> > > <loader readonly='yes' secure='no' type='pflash'>/usr/share/qemu/ovmf-x86_64-code.bin</loader> > > <nvram template='/usr/share/qemu/ovmf-x86_64-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram> > > That is not secure. You have unprotected writable flash. > > You can either use a build with SMM_REQUIRE=TRUE and run with > secure='yes', so only the firmware in SMM mode can write to flash. > > Or you run with both code and vars read-only. > Easiest is <loader>OVMF.fd</loader>. > Thanks for your suggestion! It's really helpful! I will try it. > Or you disable secure boot (SECURE_BOOT_ENABLE=FALSE) in your > builds. You still have unprotected writable flash then, but > it isn't a security hole any more. And the assert isn't triggered > either because that code path is only executed for secure boot > builds. > Yes, before I produce the patch, I need to disable SECURE_BOOT_ENABLE to workaround my VM hang problem. IMHO, using "variable header State was invalid" assert to prevent user writes to a unprotected flash is not a good idea. It causes some problem: - User's existing virtual machine can not boot/reboot after updated to edk2-stable202211 OVMF. VM just hangs there and doesn't have any hint. - The VM still works in the first boot. User doesn't know that second boot will hangs because they are writing an unprotected writable flash. - Even enabled debug log, we don't know what does "NvVarStore Variable header State was invalid." mean. Thanks Joey Lee ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [edk2-devel] [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases 2022-12-14 13:46 ` [edk2-devel] " joeyli 2022-12-14 14:12 ` Gerd Hoffmann @ 2022-12-14 14:24 ` joeyli 1 sibling, 0 replies; 8+ messages in thread From: joeyli @ 2022-12-14 14:24 UTC (permalink / raw) To: devel, kraxel Cc: Lee, Chun-Yi, Min M Xu, Jiewen Yao, Tom Lendacky, James Bottomley, Erdem Aktas Hi, On Wed, Dec 14, 2022 at 09:46:36PM +0800, joeyli wrote: > Hi Gerd, > > Thanks for your response! > > On Wed, Dec 14, 2022 at 07:15:28AM +0100, Gerd Hoffmann via groups.io wrote: > > Hi, > > > > > When the variable store has those variables, then system booting/rebooting will > > > hangs in a ASSERT: > > > > > > NvVarStore Variable header State was invalid. > > > ASSERT > > > /mnt/working/source_code-git/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(819): > > > ((BOOLEAN)(0==1)) > > > > I'm wondering how you manage to trigger this assert? > > > > Sorry for I forgot to put my testing environment in patch description. > My testing is on qemu with OVMF: > > - edk2-master or edk2-stable202211 > build --verbose --debug=1 -D SECURE_BOOT_ENABLE -D TPM_ENABLE -D TPM_CONFIG_ENABLE \ > -D NETWORK_IP6_ENABLE -D NETWORK_HTTP_BOOT_ENABLE -a X64 -b DEBUG -t GCC5 \ > -p OvmfPkg/OvmfPkgX64.dsc -D FD_SIZE_4MB -D NETWORK_TLS_ENABLE > > - qemu-7.1.0 with libvirt-8.0.0 > pc-q35 with pflash type and nvram: > <type arch='x86_64' machine='pc-q35-3.1'>hvm</type> > <loader readonly='yes' secure='no' type='pflash'>/usr/share/qemu/ovmf-x86_64-code.bin</loader> > <nvram template='/usr/share/qemu/ovmf-x86_64-vars.bin'>/var/lib/libvirt/qemu/nvram/opensuseTW_VARS.fd</nvram> > > - grub2 2.06 and Linux kernel 6.1.0-rc5 > I forgot shim-15.7, the fallback mechanism created new boot entry and update bootorder in a new *_VARS.fd : FSOpen: Open '\EFI\opensuse\boot.csv' Success UpdateVariable() - Boot0003, 8BE4DF61-93CA-11D2-AA0D-00E098032B8C FlushHobVariableToFlash() - Boot0003, 8BE4DF61-93CA-11D2-AA0D-00E098032B8C UpdateVariable() - BootOrder, 8BE4DF61-93CA-11D2-AA0D-00E098032B8C L1870, State = 0x3F State &= VAR_DELETED = 0x3D <-- state of BootOrder FlushHobVariableToFlash() - BootOrder, 8BE4DF61-93CA-11D2-AA0D-00E098032B8C Joey Lee > Two test cases, both of them can reproduce the assert: > > - First booting to grub2 menu, then "virsh destroy" the guest. > The second boot hangs in the "NvVarStore Variable header State was invalid." assert > > - First boot to Linux kernel 6.1.0-rc5, bash shell prompt shows up. > Then run shutdown or reboot command. > The second boot hangs in in the "NvVarStore Variable header State was invalid." assert > > > > Adding more log to UpdateVariable() and PlatformValidateNvVarStore(), we > > > can see there have some variables have 0x3C or 0x3D state in store. > > > e.g. > > > > PlatformValidateNvVarStore() validates the varstore in ROM before > > copying it to RAM. The normal UpdateVariable() cycle changes the > > copy in RAM ... > > > > Yes, in the first boot, those variables have 0x3C or 0x3C state be > created. After shutdown or reboot, system hangs in the second boot. > The assert shows up in debug log. > > Thanks a lot! > Joey Lee ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases 2022-12-13 15:55 [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases Lee, Chun-Yi 2022-12-14 6:15 ` Gerd Hoffmann @ 2022-12-14 6:53 ` Yao, Jiewen 2022-12-14 15:05 ` [edk2-devel] " joeyli 1 sibling, 1 reply; 8+ messages in thread From: Yao, Jiewen @ 2022-12-14 6:53 UTC (permalink / raw) To: Lee, Chun-Yi, devel@edk2.groups.io Cc: Xu, Min M, Gerd Hoffmann, Tom Lendacky, James Bottomley, Aktas, Erdem, Lee, Chun-Yi Hey Good catch! I think we need handle below valid cases: 1. VAR_HEADER_VALID_ONLY (0x7F) <-- Header added (*) 2. VAR_ADDED (0x3F) <-- Header + data added 3. VAR_ADDED & VAR_IN_DELETED_TRANSITION (0x3E) <-- marked as deleted, but still valid, before new data is added. (*) 4. VAR_ADDED & VAR_IN_DELETED_TRANSITION & VAR_DELETED (0x3C) <-- deleted, after new data is added. 5. VAR_ADDED & VAR_DELETED (0x3D) <-- deleted directly, without new data. (*) means to support surprise shutdown. For the patch: > if (!((VariableHeader->State == VAR_IN_DELETED_TRANSITION) || > (VariableHeader->State == VAR_DELETED) || > (VariableHeader->State == VAR_HEADER_VALID_ONLY) || > - (VariableHeader->State == VAR_ADDED))) > + (VariableHeader->State == VAR_ADDED) || > + (VariableHeader->State == (VAR_ADDED & VAR_DELETED)) || > + (VariableHeader->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION & VAR_DELETED)))) I think: A. If we allow (VAR_HEADER_VALID_ONLY), then we support surprise shutdown, we need also allow (VAR_ADDED & VAR_IN_DELETED_TRANSITION). It should be added as well. B. The (VAR_IN_DELETED_TRANSITION) and (VAR_DELETED) are invalid state. They should be removed. Would you please double check? > -----Original Message----- > From: Lee, Chun-Yi <joeyli.kernel@gmail.com> > Sent: Tuesday, December 13, 2022 11:55 PM > To: devel@edk2.groups.io > Cc: Xu, Min M <min.m.xu@intel.com>; Gerd Hoffmann > <kraxel@redhat.com>; Yao, Jiewen <jiewen.yao@intel.com>; Tom Lendacky > <thomas.lendacky@amd.com>; James Bottomley <jejb@linux.ibm.com>; > Aktas, Erdem <erdemaktas@google.com>; Lee, Chun-Yi <jlee@suse.com> > Subject: [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of > NvVarStore in some cases > > In the commit 4f173db8b4 "OvmfPkg/PlatformInitLib: Add functions for > EmuVariableNvStore" > , it introduced a PlatformValidateNvVarStore() function for checking the > integrity of NvVarStore. > > In some cases when the VariableHeader->StartId is VARIABLE_DATA, the > VariableHeader->State > is not just one of the four primary states: VAR_IN_DELETED_TRANSITION, > VAR_DELETED, > VAR_HEADER_VALID_ONLY, VAR_ADDED. The state may combined two or > three > states, e.g. > 0x3C = (VAR_IN_DELETED_TRANSITION & VAR_ADDED) & VAR_DELETED > or > 0x3D = VAR_ADDED & VAR_DELETED > > When the variable store has those variables, then system booting/rebooting > will > hangs in a ASSERT: > > NvVarStore Variable header State was invalid. > ASSERT > /mnt/working/source_code- > git/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(819): > ((BOOLEAN)(0==1)) > > Adding more log to UpdateVariable() and PlatformValidateNvVarStore(), we > can see there have some variables have 0x3C or 0x3D state in store. > e.g. > > UpdateVariable(), VariableName=BootOrder > L1871, State=0000003F <-- VAR_ADDED > State &= VAR_DELETED=0000003D > FlushHobVariableToFlash(), VariableName=BootOrder > ... > UpdateVariable(), VariableName=InitialAttemptOrder > L1977, State=0000003F > State &= VAR_IN_DELETED_TRANSITION=0000003E > L2376, State=0000003E > State &= VAR_DELETED=0000003C > FlushHobVariableToFlash(), VariableName=InitialAttemptOrder > ... > UpdateVariable(), VariableName=ConIn > L1977, State=0000003F > State &= VAR_IN_DELETED_TRANSITION=0000003E > L2376, State=0000003E > State &= VAR_DELETED=0000003C > FlushHobVariableToFlash(), VariableName=ConIn > ... > > So, only allowing the four primary states is not enough. This patch adds > two more combined states to the valid states list: > > (VAR_IN_DELETED_TRANSITION & VAR_ADDED) & VAR_DELETED = 0x3c > > VAR_ADDED & VAR_DELETED = 0x3d > > Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> > --- > OvmfPkg/Library/PlatformInitLib/Platform.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c > b/OvmfPkg/Library/PlatformInitLib/Platform.c > index 77f22de046..2af4cefd10 100644 > --- a/OvmfPkg/Library/PlatformInitLib/Platform.c > +++ b/OvmfPkg/Library/PlatformInitLib/Platform.c > @@ -705,7 +705,9 @@ PlatformValidateNvVarStore ( > if (!((VariableHeader->State == VAR_IN_DELETED_TRANSITION) || > (VariableHeader->State == VAR_DELETED) || > (VariableHeader->State == VAR_HEADER_VALID_ONLY) || > - (VariableHeader->State == VAR_ADDED))) > + (VariableHeader->State == VAR_ADDED) || > + (VariableHeader->State == (VAR_ADDED & VAR_DELETED)) || > + (VariableHeader->State == (VAR_ADDED & > VAR_IN_DELETED_TRANSITION & VAR_DELETED)))) > { > DEBUG ((DEBUG_ERROR, "NvVarStore Variable header State was > invalid.\n")); > return FALSE; > -- > 2.35.3 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [edk2-devel] [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases 2022-12-14 6:53 ` Yao, Jiewen @ 2022-12-14 15:05 ` joeyli 0 siblings, 0 replies; 8+ messages in thread From: joeyli @ 2022-12-14 15:05 UTC (permalink / raw) To: devel, jiewen.yao Cc: Lee, Chun-Yi, Xu, Min M, Gerd Hoffmann, Tom Lendacky, James Bottomley, Aktas, Erdem Hi Jiewen, Thanks for your response! On Wed, Dec 14, 2022 at 06:53:42AM +0000, Yao, Jiewen via groups.io wrote: > Hey > Good catch! > > I think we need handle below valid cases: > 1. VAR_HEADER_VALID_ONLY (0x7F) <-- Header added (*) > 2. VAR_ADDED (0x3F) <-- Header + data added > 3. VAR_ADDED & VAR_IN_DELETED_TRANSITION (0x3E) <-- marked as deleted, but still valid, before new data is added. (*) > 4. VAR_ADDED & VAR_IN_DELETED_TRANSITION & VAR_DELETED (0x3C) <-- deleted, after new data is added. > 5. VAR_ADDED & VAR_DELETED (0x3D) <-- deleted directly, without new data. > (*) means to support surprise shutdown. > > > For the patch: > > if (!((VariableHeader->State == VAR_IN_DELETED_TRANSITION) || > > (VariableHeader->State == VAR_DELETED) || > > (VariableHeader->State == VAR_HEADER_VALID_ONLY) || > > - (VariableHeader->State == VAR_ADDED))) > > + (VariableHeader->State == VAR_ADDED) || > > + (VariableHeader->State == (VAR_ADDED & VAR_DELETED)) || > > + (VariableHeader->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION & VAR_DELETED)))) > > I think: > A. If we allow (VAR_HEADER_VALID_ONLY), then we support surprise shutdown, we need also allow (VAR_ADDED & VAR_IN_DELETED_TRANSITION). It should be added as well. > B. The (VAR_IN_DELETED_TRANSITION) and (VAR_DELETED) are invalid state. They should be removed. > > Would you please double check? > I have followed your suggestion to change patch to add (VAR_ADDED & VAR_IN_DELETED_TRANSITION) and removed (VAR_IN_DELETED_TRANSITION) and (VAR_DELETED). Like this: Index: edk2/OvmfPkg/Library/PlatformInitLib/Platform.c =================================================================== --- edk2.orig/OvmfPkg/Library/PlatformInitLib/Platform.c +++ edk2/OvmfPkg/Library/PlatformInitLib/Platform.c @@ -704,10 +704,11 @@ PlatformValidateNvVarStore ( VariableOffset = NvVarStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER); } else { DEBUG ((DEBUG_ERROR, "VariableHeader->VendorGuid = %g, VariableHeader->State = 0x%x\n", VariableHeader->VendorGuid, VariableHeader->State)); - if (!((VariableHeader->State == VAR_IN_DELETED_TRANSITION) ||^M - (VariableHeader->State == VAR_DELETED) ||^M - (VariableHeader->State == VAR_HEADER_VALID_ONLY) ||^M - (VariableHeader->State == VAR_ADDED)))^M + if (!((VariableHeader->State == VAR_HEADER_VALID_ONLY) ||^M + (VariableHeader->State == VAR_ADDED) ||^M + (VariableHeader->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION)) ||^M + (VariableHeader->State == (VAR_ADDED & VAR_DELETED)) ||^M + (VariableHeader->State == (VAR_ADDED & VAR_IN_DELETED_TRANSITION & VAR_DELETED))))^M { DEBUG ((DEBUG_ERROR, "NvVarStore Variable header State was invalid.\n")); return FALSE; The above change works to me no my OVMF. Thanks a lot! Joey Lee > > > > > -----Original Message----- > > From: Lee, Chun-Yi <joeyli.kernel@gmail.com> > > Sent: Tuesday, December 13, 2022 11:55 PM > > To: devel@edk2.groups.io > > Cc: Xu, Min M <min.m.xu@intel.com>; Gerd Hoffmann > > <kraxel@redhat.com>; Yao, Jiewen <jiewen.yao@intel.com>; Tom Lendacky > > <thomas.lendacky@amd.com>; James Bottomley <jejb@linux.ibm.com>; > > Aktas, Erdem <erdemaktas@google.com>; Lee, Chun-Yi <jlee@suse.com> > > Subject: [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of > > NvVarStore in some cases > > > > In the commit 4f173db8b4 "OvmfPkg/PlatformInitLib: Add functions for > > EmuVariableNvStore" > > , it introduced a PlatformValidateNvVarStore() function for checking the > > integrity of NvVarStore. > > > > In some cases when the VariableHeader->StartId is VARIABLE_DATA, the > > VariableHeader->State > > is not just one of the four primary states: VAR_IN_DELETED_TRANSITION, > > VAR_DELETED, > > VAR_HEADER_VALID_ONLY, VAR_ADDED. The state may combined two or > > three > > states, e.g. > > 0x3C = (VAR_IN_DELETED_TRANSITION & VAR_ADDED) & VAR_DELETED > > or > > 0x3D = VAR_ADDED & VAR_DELETED > > > > When the variable store has those variables, then system booting/rebooting > > will > > hangs in a ASSERT: > > > > NvVarStore Variable header State was invalid. > > ASSERT > > /mnt/working/source_code- > > git/edk2/OvmfPkg/Library/PlatformInitLib/Platform.c(819): > > ((BOOLEAN)(0==1)) > > > > Adding more log to UpdateVariable() and PlatformValidateNvVarStore(), we > > can see there have some variables have 0x3C or 0x3D state in store. > > e.g. > > > > UpdateVariable(), VariableName=BootOrder > > L1871, State=0000003F <-- VAR_ADDED > > State &= VAR_DELETED=0000003D > > FlushHobVariableToFlash(), VariableName=BootOrder > > ... > > UpdateVariable(), VariableName=InitialAttemptOrder > > L1977, State=0000003F > > State &= VAR_IN_DELETED_TRANSITION=0000003E > > L2376, State=0000003E > > State &= VAR_DELETED=0000003C > > FlushHobVariableToFlash(), VariableName=InitialAttemptOrder > > ... > > UpdateVariable(), VariableName=ConIn > > L1977, State=0000003F > > State &= VAR_IN_DELETED_TRANSITION=0000003E > > L2376, State=0000003E > > State &= VAR_DELETED=0000003C > > FlushHobVariableToFlash(), VariableName=ConIn > > ... > > > > So, only allowing the four primary states is not enough. This patch adds > > two more combined states to the valid states list: > > > > (VAR_IN_DELETED_TRANSITION & VAR_ADDED) & VAR_DELETED = 0x3c > > > > VAR_ADDED & VAR_DELETED = 0x3d > > > > Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> > > --- > > OvmfPkg/Library/PlatformInitLib/Platform.c | 4 +++- > > 1 file changed, 3 insertions(+), 1 deletion(-) > > > > diff --git a/OvmfPkg/Library/PlatformInitLib/Platform.c > > b/OvmfPkg/Library/PlatformInitLib/Platform.c > > index 77f22de046..2af4cefd10 100644 > > --- a/OvmfPkg/Library/PlatformInitLib/Platform.c > > +++ b/OvmfPkg/Library/PlatformInitLib/Platform.c > > @@ -705,7 +705,9 @@ PlatformValidateNvVarStore ( > > if (!((VariableHeader->State == VAR_IN_DELETED_TRANSITION) || > > (VariableHeader->State == VAR_DELETED) || > > (VariableHeader->State == VAR_HEADER_VALID_ONLY) || > > - (VariableHeader->State == VAR_ADDED))) > > + (VariableHeader->State == VAR_ADDED) || > > + (VariableHeader->State == (VAR_ADDED & VAR_DELETED)) || > > + (VariableHeader->State == (VAR_ADDED & > > VAR_IN_DELETED_TRANSITION & VAR_DELETED)))) > > { > > DEBUG ((DEBUG_ERROR, "NvVarStore Variable header State was > > invalid.\n")); > > return FALSE; > > -- > > 2.35.3 > > > > > ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-12-14 15:25 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-12-13 15:55 [PATCH] OvmfPkg/PlatformInitLib: Fix integrity checking failed of NvVarStore in some cases Lee, Chun-Yi 2022-12-14 6:15 ` Gerd Hoffmann 2022-12-14 13:46 ` [edk2-devel] " joeyli 2022-12-14 14:12 ` Gerd Hoffmann 2022-12-14 15:24 ` joeyli 2022-12-14 14:24 ` joeyli 2022-12-14 6:53 ` Yao, Jiewen 2022-12-14 15:05 ` [edk2-devel] " joeyli
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox