Hello community, here is the log from the commit of package ovmf.15364 for openSUSE:Leap:15.2:Update checked in at 2020-12-22 06:22:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2:Update/ovmf.15364 (Old) and /work/SRC/openSUSE:Leap:15.2:Update/.ovmf.15364.new.5145 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "ovmf.15364" Tue Dec 22 06:22:49 2020 rev:1 rq:856935 version:201911 Changes: -------- New Changes file: --- /dev/null 2020-12-09 01:05:43.965003977 +0100 +++ /work/SRC/openSUSE:Leap:15.2:Update/.ovmf.15364.new.5145/ovmf.changes 2020-12-22 06:22:51.312556425 +0100 @@ -0,0 +1,3646 @@ +------------------------------------------------------------------- +Wed Dec 2 09:03:01 UTC 2020 - Gary Ching-Pang Lin <glin@suse.com> + +- Add ovmf-bsc1177789-cryptopkg-fix-null-dereference.patch to fix + the potential NULL dereference in AuthenticodeVerify() + (bsc#1177789, CVE-2019-14584) + +------------------------------------------------------------------- +Thu Sep 3 03:07:28 UTC 2020 - Gary Ching-Pang Lin <glin@suse.com> + +- Add ovmf-bsc1175476-fix-DxeImageVerificationLib-overflow.patch + to fix overflow in DxeImageVerificationHandler + (bsc#1175476, CVE-2019-14562) + +------------------------------------------------------------------- +Mon Jul 20 07:32:48 UTC 2020 - Gary Ching-Pang Lin <glin@suse.com> + +- Add ovmf-bsc1119454-additional-scsi-drivers.patch to support more + SCSI drivers (PvScsi, MptScsi, and LsiScsi) (bsc#1119454) + + Enable LsiScsi explicitly since it's disabled by default + +------------------------------------------------------------------- +Mon Apr 6 03:54:48 UTC 2020 - Gary Ching-Pang Lin <glin@suse.com> + +- Add ovmf-bsc1163927-fix-ping-and-ip6dxe.patch to fix crash and + hang in ShellPkg and Ip6Dxe (bsc#1163927, CVE-2019-14559) + +------------------------------------------------------------------- +Mon Feb 24 04:00:24 UTC 2020 - Gary Ching-Pang Lin <glin@suse.com> + +- Add ovmf-bsc1163969-fix-DxeImageVerificationHandler.patch to fix + dbx signature check (bsc#1163969, CVE-2019-14575) + + Also change the order of several patches to distinguish the + openssl patch +- Add ovmf-bsc1163927-fix-ip4dxe-and-arpdxe.patch to fix memory + leakage in Ip4Dxe and ArpDxe (bsc#1163927, CVE-2019-14559) + +------------------------------------------------------------------- +Tue Feb 18 09:24:30 UTC 2020 - Gary Ching-Pang Lin <glin@suse.com> + +- Add ovmf-bsc1163959-PiDxeS3BootScriptLib-fix-numeric-truncation.patch + to fix the numeric truncation to avoid the potential memory + corruption (bsc#1163959, CVE-2019-14563) + +------------------------------------------------------------------- +Mon Feb 3 02:14:23 UTC 2020 - Gary Ching-Pang Lin <glin@suse.com> + +- Build the unified firmware with preloaded keys for backward + compatibility (bsc#1159793) + +------------------------------------------------------------------- +Fri Dec 20 09:11:37 UTC 2019 - Dirk Mueller <dmueller@suse.com> + +- only build -aarch32 Cortex-A15 EFI on armv7hl + +------------------------------------------------------------------- +Tue Dec 3 02:35:19 UTC 2019 - Gary Ching-Pang Lin <glin@suse.com> + +- Update to edk2-stable201911 + + SecurityPkg: Fix TPM2 ACPI measurement + + MdeModulePkg: Enable variable runtime cache by default + + OvmfPkg: Disable variable runtime cache + + MdeModulePkg/Variable: Add RT GetVariable() cache support + + CryptoPkg: Upgrade OpenSSL to 1.1.1d + + MdePkg-UefiSpec.h: Add UEFI 2.8 new memory attributes + + MdePkg/UefiFileHandleLib: Fix potential NULL dereference + + NetworkPkg/HttpDxe: Set the HostName for the verification + (CVE-2019-14553) + + NetworkPkg/TlsDxe: Add the support of host validation to TlsDxe + driver (CVE-2019-14553) + + CryptoPkg/TlsLib: TlsSetVerifyHost: parse IP address literals + as such (CVE-2019-14553) + + CryptoPkg/TlsLib: Add the new API "TlsSetVerifyHost" + (CVE-2019-14553) + + MdePkg/Include/Protocol/Tls.h: Add the data type of + EfiTlsVerifyHost (CVE-2019-14553) + + MdeModulePkg/BdsDxe: Fix PlatformRecovery issue + + NetworkPkg/SnpDxe: Add PCD to remove ExitBootServices event + from SNP driver + + MdeModulePkg: Update to support SmBios 3.3.0 + + UefiCpuPkg/MpInitLib: honor the platform's boot CPU count in AP + detection + + SecurityPkg/Tcg2: Add Support Laml, Lasa for TPM2 ACPI + + OvmfPkg/PlatformDxe: fix EFI_HII_HANDLE parameters of internal + functions + + OvmfPkg/VirtioNetDxe: fix SignalEvent() call + + OvmfPkg/XenBusDxe: fix UninstallMultipleProtocolInterfaces() + call + + NetworkPkg/Ip4Dxe: fix NetLibDestroyServiceChild() call + + MdeModulePkg/ScsiDiskDxe: Support Storage Security Command + Protocol + + MdePkg: Implement SCSI commands for Security Protocol In/Out + + MdeModulePkg/TerminalDxe: Enhance the arrow keys support + + MdeModulePkg/UefiBootManager: Unload image on + EFI_SECURITY_VIOLATION + + MdeModulePkg/DxeCapsuleLibFmp: Unload image on + EFI_SECURITY_VIOLATION + + MdeModulePkg: Extend the support keyboard type of Terminal + console + + UefiCpuPkg/CpuExceptionHandlerLib: Fix split lock + + UefiCpuPkg: Fix potential spinLock issue in SmmStartupThisAp + + UefiCpuPkg/PiSmmCpu: Enable 5L paging only when phy addr line + > 48 + + OvmfPkg/EnrollDefaultKeys: clean up Base64Decode() retval + handling + + ArmVirtPkg/PlatformBootManagerLib: unload image on + EFI_SECURITY_VIOLATION + + ShellPkg/ShellPkg.dsc AARCH64: enable stack protector + + ArmVirtPkg/ArmVirtPrePiUniCoreRelocatable: revert to PIE + linking + + BaseTools/GenFw AARCH64: fix up GOT based relative relocations + + ShellPkg/Pci.c: Update supported link speed to PCI5.0 + + PcAtChipsetPkg: add PcdRealTimeClockUpdateTimeout + + UefiCpuPkg: Add PcdCpuSmmRestrictedMemoryAccess + + ShellPkg/CommandLib: avoid NULL derefence and memory leak + + MdePkg/DxeHstiLib: Added checks to improve error handling + + BaseTools: Support more file types in build cache + + UefiCpuPkg/SecCore: get AllSecPpiList after SecPlatformMain +- Update openssl to 1.1.1d + + Add openssl-fix-syntax-error.patch to fix a syntax error +- Drop ovmf-bsc1153072-fix-invalid-https-cert.patch + + Already upstreamed + +------------------------------------------------------------------- +Fri Nov 8 04:09:48 UTC 2019 - Gary Ching-Pang Lin <glin@suse.com> + +- Use the same x86 4MB firmware names as the ones in the previous + version (< stable201905) for backward compatibility + +------------------------------------------------------------------- +Wed Nov 6 03:01:29 UTC 2019 - Gary Ching-Pang Lin <glin@suse.com> + +- Update to edk2-stable201908 + + Add TLS and IPv6 supports for ArmVirtQemu + + Various fixes and updates for TPM2 + + Various fixes for OvmfPkg and the underlying infrastructures + + Drop the build requirement of python2 + + Drop the obsolete IntelFrameworkPkg and IntelFrameworkModulePkg + + Remove ShellBinPkg and move the platform packages out of edk2 +- Update openssl to 1.1.1b + + Add berkeley-softfloat-3-b64af41c3276f.tar.xz since arm7 needs + the softfloat implementation for openssl 1.1.1b +- Add ovmf-bsc1153072-fix-invalid-https-cert.patch to reject the + invalid server certificates for HTTPS Boot + (bsc#1153072, CVE-2019-14553) +- Build the varstore templates with EnrollDefaultKeys.efi + + Create the iso files for key enrollment + - Add gen-key-enrollment-iso.sh to generate the iso file + + Drop the non-upstream ovmf-embed-default-keys.patch + - Also drop owner-guid-zero.h + + Drop the MS keys and dbx since they are already in + EnrollDefaultKeys.efi: MicCorKEKCA2011_2011-06-24.crt, + MicCorUEFCA2011_2011-06-27.crt, MicWinProPCA2011_2011-10-19.crt, + and dbxupdate.zip + - Also drop the related script strip_authinfo.pl + + Add ovmf-set-fixed-enroll-time.patch to set the fixed enrolling + time to make the varstore template reproducible + + Require qemu 3.0.0 for fw_cfg +- Enable TLS (HTTPS Boot) and TPM2 support +- Add the firmware descriptors for QEMU +- Update README to match the current settings +- Update the License tag to BSD-2-Clause-Patent +- Build SecureBoot firmwares for aarch64 +- Add a new "smm" flavor to enable System Management Mode + + Also add ovmf-add-exclude-shell-flag.patch to exclude shell + from the resultant SMM firmware files +- Retire the old openSUSE 4096 bit certificates since all those + programs are unmaintained. +- Drop upstreamed patches + + ovmf-bsc1092943-fix-attributes-table.patch + + ovmf-bsc1099193-fix-sev-flash-variables.patch + + ovmf-bsc1115916-fix-timestamp-zeroing.patch + + ovmf-bsc1115917-bounds-checking-for-ueficompress.patch + + ovmf-bsc1127820-fix-blockio-buffer-overflow.patch + + ovmf-bsc1127821-dns-check-packet-size.patch + + ovmf-bsc1127822-fix-fv-parsing.patch + + ovmf-bsc1128503-fix-stack-overflow-in-HiiImage-and-HiiDatabase.patch + + ovmf-bsc1130267-overflow-in-partition-and-udf.patch + + ovmf-bsc1131361-fix-stack-overflow-xhci.patch +- Refresh patches: + + ovmf-add-exclude-shell-flag.patch + + ovmf-disable-ia32-firmware-piepic.patch + + ovmf-pie.patch +- Drop the requirement of xxd + +------------------------------------------------------------------- +Tue Apr 9 03:33:40 UTC 2019 - Gary Ching-Pang Lin <glin@suse.com> + +- Add ovmf-bsc1131361-fix-stack-overflow-xhci.patch to fix stack + overflow in UsbBusDxe and UsbBusPei (bsc#1131361, CVE-2019-0161) + +------------------------------------------------------------------- +Mon Mar 25 03:33:47 UTC 2019 - Gary Ching-Pang Lin <glin@suse.com> + +- Add ovmf-bsc1130267-overflow-in-partition-and-udf.patch to fix + buffer overflows in PartitionDxe and UdfDxe (bsc#1130267, + CVE-2019-0160) ++++ 3449 more lines (skipped) ++++ between /dev/null ++++ and /work/SRC/openSUSE:Leap:15.2:Update/.ovmf.15364.new.5145/ovmf.changes New: ---- README SLES-UEFI-CA-Certificate-2048.crt _service berkeley-softfloat-3-b64af41c3276f.tar.xz descriptors.tar.xz edk2-stable201911.tar.gz gdb_uefi.py.in gen-key-enrollment-iso.sh openSUSE-UEFI-CA-Certificate-2048.crt openSUSE-UEFI-SIGN-Certificate-2048.crt openssl-1.1.1d.tar.gz openssl-1.1.1d.tar.gz.asc openssl-fix-syntax-error.patch openssl.keyring ovmf-add-exclude-shell-flag.patch ovmf-bsc1119454-additional-scsi-drivers.patch ovmf-bsc1163927-fix-ip4dxe-and-arpdxe.patch ovmf-bsc1163927-fix-ping-and-ip6dxe.patch ovmf-bsc1163959-PiDxeS3BootScriptLib-fix-numeric-truncation.patch ovmf-bsc1163969-fix-DxeImageVerificationHandler.patch ovmf-bsc1175476-fix-DxeImageVerificationLib-overflow.patch ovmf-bsc1177789-cryptopkg-fix-null-dereference.patch ovmf-disable-ia32-firmware-piepic.patch ovmf-gdb-symbols.patch ovmf-pie.patch ovmf-rpmlintrc ovmf-set-fixed-enroll-time.patch ovmf.changes ovmf.spec ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ovmf.spec ++++++ ++++ 650 lines (skipped) ++++++ README ++++++ Running the OVMF image in qemu ============================== The easiest way to run the OVMF image is to specify a pflash device for the firmware file. Here is the example to use OVMF in the flash mode: $ cp /usr/share/qemu/ovmf-x86_64.bin . $ qemu-system-x86_64 -pflash ovmf-x86_64.bin Please make sure the file is writable before using the flash mode, or all your changes won't be saved. Starting from r15670, two extra firmware files are provided for the flash mode: ovmf-*-code.bin and ovmf-*-vars.bin, and all non-volatile variables will be stored in ovmf-*-vars.bin. Example: $ cp /usr/share/qemu/ovmf-x86_64-vars.bin . $ qemu-system-x86_64 \ -drive if=pflash,format=raw,unit=0,readonly,file=/usr/share/qemu/ovmf-x86_64-code.bin \ -drive if=pflash,format=raw,unit=1,file=ovmf-x86_64-vars.bin It would be easier to manage the NV variables with the separated vars firmware. NOTE: Running OVMF with '-bios' is deprecated and should not be used anymore. Variable Stores with preloaded keys ----------------------------------- Besides the generic OVMF images, there are images preloaded with different vendor keys. ovmf-x86_64-smm-ms-vars.bin - PK: SUSE Linux Enterprise Secure Boot CA - KEK: Microsoft Corporation KEK CA 2011, SUSE Linux Enterprise Secure Boot CA - db: Microsoft Corporation UEFI CA 2011, Microsoft Windows Production PCA 2011 ovmf-x86_64-smm-opensuse-vars.bin - PK: openSUSE Secure Boot CA - KEK: openSUSE Secure Boot CA - db: openSUSE Secure Boot CA ovmf-x86_64-smm-suse-vars.bin - PK: SUSE Linux Enterprise Secure Boot CA - KEK: SUSE Linux Enterprise Secure Boot CA - db: SUSE Linux Enterprise Secure Boot CA Note that the preloaded key images are all 64 bit because openSUSE/SLE and Windows only support Secure Boot in 64 bit mode. Those variable stores are created with EnrollDefaultKeys.efi which enrolls the Microsoft keys into KEK and db. It also reads the key from SMBIOS Type 11 and enrolls the key into PK and KEK. If the "--no-default" switch is provided, the program will ignore the Microsoft keys and enroll the key from SMBIOS into db instead. x86_64 4MB images ----------------- The OVMF upstream decides to switch the default flash size to 4MB since the edk2 commit 1c47fcd465a496. It's mainly for Windows HCK which requests a larger variable store. To maintain the backward compatibility, the 4MB images are built separately. Only those images with 4m, e.g. ovmf-x86_64-4m.bin, are the 4MB images. Otherwise, it's built with FD_SIZE_2MB, i.e. a 2MB image. x86_64 SMM Support ------------------ The image files with "-smm", e.g. ovmf-x86_64-smm.bin, are the images with SMM support. SMM provides better (virtual) hardware separation between the guest OS and the firmware to prevent the runtime guest OS from tampering with the variable store and S3 areas, so it's recommended to enable SMM along with Secure Boot. Here are the requirements to use the SMM images: * SMM support requires QEMU 2.5. * The minimum required QEMU machine type is "pc-q35-2.5". * SMM with KVM requires Linux 4.4 (host). Here are the qemu commands to start a VM with SMM support: $ cp /usr/share/qemu/ovmf-x86_64-smm-vars.bin . $ qemu-system-x86_64 \ -machine q35,smm=on,accel=(tcg|kvm) \ -global driver=cfi.pflash01,property=secure,value=on \ -drive if=pflash,format=raw,unit=0,readonly,file=/usr/share/qemu/ovmf-x86_64-smm-code.bin \ -drive if=pflash,format=raw,unit=1,file=ovmf-x86_64-smm-vars.bin \ -global ICH9-LPC.disable_s3=1 \ ... NOTE: The pflash variable store is required to use OVMF with SMM. Creating Platform and Key Exchange keys ======================================= A note about terminology. In UEFI terms, "key" means certificate (not the openssl key). UEFI keys are required to be based on RSA 2048 bit keys. The Platform key and Key Exchange Keys should be the equivalent of CA root certificates (i.e. a self signed certificate). Note that in current tianocore OVMF, the input certificates, if taken from external media, *must* be in a file with a .cer extension and in DER format. The platform key is the key which controls updates to the Key Exchange Key database. The Key Exchange Key controls updates to the signature databases. Note that if the Key Exchange Key is an X509 key, any key which has the KEK as its root signature can also be used to validate an efi binary without need for any entries in the signatures database. Create Platform Key (PK) ------------------------ openssl req -new -x509 -newkey rsa:2048 -keyout PK.key -out PK.crt -days <length> Note that the Key is PK.crt (PK.key is the private key you use to sign other certificates) Now convert to DER format openssl x509 -in PK.crt -out PK.cer -outform DER The file PK.cer can be placed on a USB key for enrolling as the platform key. Create Key Exchange Key (KEK) ----------------------------- This is done exactly as the Platform key above, except call the file KEK.cer instead. Note, for expermentation purposes, there's no reason the KEK and the PK can't be the same certificate. Creating derived keys from the KEK ---------------------------------- This process can be used to create subordinate keys which can be used to sign efi binaries (since their roots can be traced back to the KEK). openssl req -new -newkey rsa:2048 -keyout new.key -out new.csr -days <length> Now sign the certificate request with the KEK: openssl x509 -req -in new.csr -CA KEK.crt -CAkey KEK.key -set_serial 1 -out new.crt Note that since the new key doesn't have to be enrolled in the platform because its root of trust can be traced back to the KEK, there's no need to create a DER form of the key (the sbsign utilites used to sign efi binaries take the key.crt file which is in PEM form). Running the UEFI ARM image in qemu ================================== There are two flavors of the UEFI ARM images: AArch32 and AArch64. For the AArch64 image, use the following command: qemu-system-aarch64 -m 1024 -M virt -cpu cortex-a57 -bios /usr/share/qemu/qemu-uefi-aarch64.bin -serial stdio For AArch32: qemu-system-arm -m 1024 -M virt -cpu cortex-a15 -bios /usr/share/qemu/qemu-uefi-aarch32.bin -serial stdio Source Level Debugging ====================== It's possible to debug OVMF with gdb connecting to qemu with the following steps: (1) install the debug package: qemu-ovmf-x86_64-debug (2) Start the virtual machine with '-s' or "-gdb tcp::1234" (3) Start gdb in another terminal and issue the following commands: (gdb) set architecture i386:x86-64:intel (gdb) target remote localhost:1234 (gdb) source /usr/share/ovmf-x86_64/gdb_uefi-ovmf-x86_64-<flavor>.py (gdb) reload-uefi -o /usr/lib/debug/ovmf-x86_64/DebugPkg/GdbSyms/GdbSyms/DEBUG/GdbSyms.dll (4) Happy debugging Reference: https://www.mail-archive.com/edk2-devel@lists.sourceforge.net/msg07075.html Note: It's also possible to debug OVMF with Xen, but the way to set up the port is differnt. Instead of adding the port number to qemu, you need gdbsx. Before starting gdb, execute this command: # gdbsx -a <domainid> 64 1234 Then gdbsx will listen to port 1234 for the specific domainU. The rest is the same as qemu. ++++++ _service ++++++ <services> <service name="tar_scm" mode="disabled"> <param name="filename">ovmf</param> <param name="versionformat">2017+git%at.%h</param> <param name="revision">UDK2017</param> <param name="url">https://github.com/tianocore/edk2.git</param> <param name="scm">git</param> </service> <service name="recompress" mode="disabled"> <param name="compression">xz</param> <param name="file">*.tar</param> </service> <service name="set_version" mode="disabled"/> </services> ++++++ gdb_uefi.py.in ++++++ """ Allows loading TianoCore symbols into a GDB session attached to EFI Firmware. This is how it works: build GdbSyms - it's a dummy binary that contains the relevant symbols needed to find and load image symbols. $ gdb (gdb) taget remote .... (gdb) source Scripts/gdb_uefi.py (gdb) reload-uefi -o /path/to/GdbSyms.dll The -o option should be used if you've debugging EFI, where the PE images were converted from MACH-O or ELF binaries. """ import array import getopt import binascii import re __license__ = "BSD" __version = "1.0.0" __maintainer__ = "Andrei Warkentin" __email__ = "andrey.warkentin@gmail.com" __status__ = "Works" # FOR RPM PACKAGE replace the strings in the spec file build_path="__BUILD_PATH__" source_path="__SOURCE_PATH__" gdb_src_path="__GDB_SRC_PATH__" flavor="__FLAVOR__" class ReloadUefi (gdb.Command): """Reload UEFI symbols""" # # Various constants. # EINVAL = 0xffffffff CV_NB10 = 0x3031424E CV_RSDS = 0x53445352 CV_MTOC = 0x434F544D DOS_MAGIC = 0x5A4D PE32PLUS_MAGIC = 0x20b EST_SIGNATURE = 0x5453595320494249L DEBUG_GUID = [0x49152E77, 0x1ADA, 0x4764, [0xB7,0xA2,0x7A,0xFE, 0xFE,0xD9,0x5E, 0x8B]] DEBUG_IS_UPDATING = 0x1 # # If the images were built as ELF/MACH-O and then converted to PE, # then the base address needs to be offset by PE headers. # offset_by_headers = False def __init__ (self): super (ReloadUefi, self).__init__ ("reload-uefi", gdb.COMMAND_OBSCURE) # # Returns gdb.Type for a type. # def type (self, typename): return gdb.lookup_type (typename) # # Returns gdb.Type for a pointer to a type. # def ptype (self, typename): return gdb.lookup_type (typename).pointer () # # Computes CRC32 on an array of data. # def crc32 (self, data): return binascii.crc32 (data) & 0xFFFFFFFF # # Sets a field in a struct to a value, i.e. # value->field_name = data. # # Newer Py bindings to Gdb provide access to the inferior # memory, but not all, so have to do it this awkward way. # def set_field (self, value, field_name, data): gdb.execute ("set *(%s *) 0x%x = 0x%x" % \ (str (value[field_name].type), \ long (value[field_name].address), \ data)) # # Returns data backing a gdb.Value as an array. # Same comment as above regarding newer Py bindings... # def value_data (self, value, bytes=0): value_address = gdb.Value (value.address) array_t = self.ptype ('UINT8') value_array = value_address.cast (array_t) if bytes == 0: bytes = value.type.sizeof data = array.array ('B') for i in range (0, bytes): data.append (value_array[i]) return data # # Locates the EFI_SYSTEM_TABLE as per UEFI spec 17.4. # Returns base address or -1. # def search_est (self): address = 0 estp_t = self.ptype ('EFI_SYSTEM_TABLE_POINTER') while True: estp = gdb.Value(address).cast(estp_t) if estp['Signature'] == self.EST_SIGNATURE: oldcrc = long (estp['Crc32']) self.set_field (estp, 'Crc32', 0) newcrc = self.crc32 (self.value_data (estp.dereference (), 0)) self.set_field (estp, 'Crc32', long (oldcrc)) if newcrc == oldcrc: return estp['EfiSystemTableBase'] address = address + 4*1024*1024 if long (address) == 0: return gdb.Value(self.EINVAL) # # Searches for a vendor-specific configuration table (in EST), # given a vendor-specific table GUID. GUID is a list like - # [32-bit, 16-bit, 16-bit, [8 bytes]] # def search_config (self, cfg_table, count, guid): index = 0 while index != count: cfg_entry = cfg_table[index]['VendorGuid'] if cfg_entry['Data1'] == guid[0] and \ cfg_entry['Data2'] == guid[1] and \ cfg_entry['Data3'] == guid[2] and \ self.value_data (cfg_entry['Data4']).tolist () == guid[3]: return cfg_table[index]['VendorTable'] index = index + 1 return gdb.Value(self.EINVAL) # # Returns a UTF16 string corresponding to a (CHAR16 *) value in EFI. # def parse_utf16 (self, value): index = 0 data = array.array ('H') while value[index] != 0: data.append (value[index]) index = index + 1 return data.tostring ().decode ('utf-16') # # Returns offset of a field within structure. Useful # for getting container of a structure. # def offsetof (self, typename, field): t = gdb.Value (0).cast (self.ptype (typename)) return long (t[field].address) # # Returns sizeof of a type. # def sizeof (self, typename): return self.type (typename).sizeof # # Returns the EFI_IMAGE_NT_HEADERS32 pointer, given # an ImageBase address as a gdb.Value. # def pe_headers (self, imagebase): dosh_t = self.ptype ('EFI_IMAGE_DOS_HEADER') head_t = self.ptype ('EFI_IMAGE_OPTIONAL_HEADER_UNION') dosh = imagebase.cast(dosh_t) h_addr = imagebase if dosh['e_magic'] == self.DOS_MAGIC: h_addr = h_addr + dosh['e_lfanew'] return gdb.Value(h_addr).cast (head_t) # # Returns True if pe_headers refer to a PE32+ image. # def pe_is_64 (self, pe_headers): if pe_headers['Pe32']['OptionalHeader']['Magic'] == self.PE32PLUS_MAGIC: return True return False # # Returns the PE (not so) optional header. # def pe_optional (self, pe): if self.pe_is_64 (pe): return pe['Pe32Plus']['OptionalHeader'] else: return pe['Pe32']['OptionalHeader'] # # Returns the symbol file name for a PE image. # def pe_parse_debug (self, pe): opt = self.pe_optional (pe) debug_dir_entry = opt['DataDirectory'][6] dep = debug_dir_entry['VirtualAddress'] + opt['ImageBase'] dep = dep.cast (self.ptype ('EFI_IMAGE_DEBUG_DIRECTORY_ENTRY')) cvp = dep.dereference ()['RVA'] + opt['ImageBase'] cvv = cvp.cast(self.ptype ('UINT32')).dereference () if cvv == self.CV_NB10: return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY') elif cvv == self.CV_RSDS: return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY') elif cvv == self.CV_MTOC: return cvp + self.sizeof('EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY') return gdb.Value(self.EINVAL) # # Parses an EFI_LOADED_IMAGE_PROTOCOL, figuring out the symbol file name. # This file name is then appended to list of loaded symbols. # # TBD: Support TE images. # def parse_image (self, image, syms): base = image['ImageBase'] pe = self.pe_headers (base) opt = self.pe_optional (pe) sym_name = self.pe_parse_debug (pe) # For ELF and Mach-O-derived images... if self.offset_by_headers: base = base + opt['SizeOfHeaders'] if sym_name != self.EINVAL: sym_name = sym_name.cast (self.ptype('CHAR8')).string () # Ignore the driver from qemu if re.search (r"\.efidrv$", sym_name): return # FOR RPM PACKAGE substitute the build path sym_name = re.sub(r"^"+re.escape(build_path), "/usr/lib/debug/"+flavor, sym_name) sym_name = re.sub(r"\.dll$", ".debug", sym_name) syms.append ("add-symbol-file %s 0x%x" % \ (sym_name, long (base))) # # Parses table EFI_DEBUG_IMAGE_INFO structures, builds # a list of add-symbol-file commands, and reloads debugger # symbols. # def parse_edii (self, edii, count): index = 0 syms = [] while index != count: entry = edii[index] if entry['ImageInfoType'].dereference () == 1: entry = entry['NormalImage'] self.parse_image(entry['LoadedImageProtocolInstance'], syms) else: print "Skipping unknown EFI_DEBUG_IMAGE_INFO (Type 0x%x)" % \ entry['ImageInfoType'].dereference () index = index + 1 gdb.execute ("symbol-file") print "Loading new symbols..." for sym in syms: print sym gdb.execute (sym) # # Parses EFI_DEBUG_IMAGE_INFO_TABLE_HEADER, in order to load # image symbols. # def parse_dh (self, dh): dh_t = self.ptype ('EFI_DEBUG_IMAGE_INFO_TABLE_HEADER') dh = dh.cast (dh_t) print "DebugImageInfoTable @ 0x%x, 0x%x entries" \ % (long (dh['EfiDebugImageInfoTable']), dh['TableSize']) if dh['UpdateStatus'] & self.DEBUG_IS_UPDATING: print "EfiDebugImageInfoTable update in progress, retry later" return self.parse_edii (dh['EfiDebugImageInfoTable'], dh['TableSize']) # # Parses EFI_SYSTEM_TABLE, in order to load image symbols. # def parse_est (self, est): est_t = self.ptype ('EFI_SYSTEM_TABLE') est = est.cast (est_t) print "Connected to %s (Rev. 0x%x)" % \ (self.parse_utf16 (est['FirmwareVendor']), \ long (est['FirmwareRevision'])) print "ConfigurationTable @ 0x%x, 0x%x entries" \ % (long (est['ConfigurationTable']), est['NumberOfTableEntries']) dh = self.search_config(est['ConfigurationTable'], est['NumberOfTableEntries'], self.DEBUG_GUID) if dh == self.EINVAL: print "No EFI_DEBUG_IMAGE_INFO_TABLE_HEADER" return self.parse_dh (dh) # # Usage information. # def usage (self): print "Usage: reload-uefi [-o] /path/to/GdbSyms.dll" # # Handler for reload-uefi. # def invoke (self, arg, from_tty): args = arg.split(' ') try: opts, args = getopt.getopt(args, "o", ["offset-by-headers"]) except getopt.GetoptError, err: self.usage () return for opt, arg in opts: if opt == "-o": self.offset_by_headers = True if len(args) < 1: self.usage () return # FOR RPM PACKAGE substitute the path of the source code gdb.execute ("set substitute-path "+source_path+" "+gdb_src_path) gdb.execute ("symbol-file") gdb.execute ("symbol-file %s" % args[0]) est = self.search_est () if est == self.EINVAL: print "No EFI_SYSTEM_TABLE..." return print "EFI_SYSTEM_TABLE @ 0x%x" % est self.parse_est (est) ReloadUefi () ++++++ gen-key-enrollment-iso.sh ++++++ #!/bin/bash -e # The script to generate the key enrollment iso file # based on build_iso() in https://git.kraxel.org/cgit/jenkins/edk2/tree/edk2.git.spec # Example: $0 X64 Shell.efi EnrollDefaultKeys.efi default key.iso usage() { PROG_NAME=$1 echo "Usage: $PROG_NAME <Arch> <Shell> <Enroller> <Type> <ISO NAME>" echo "ex: $PROG_NAME X64 Shell.efi EnrollDefaultKeys.efi default key.iso" } ARCH=$(echo $1 | tr '[:lower:'] '[:upper:]') UEFI_SHELL_BINARY="$2" ENROLLER_BINARY="$3" TYPE="$4" ISO_NAME="$5" # Check the arguments if [ x$ARCH != xX64 ] && [ x$ARCH != xAARCH64 ]; then echo "Supported architecture: X64, AARCH64" usage $0 exit 1 fi if [ x$UEFI_SHELL_BINARY == x ] || [ ! -e "$UEFI_SHELL_BINARY" ]; then echo "Please specify the UEFI shell binary" usage $0 exit 1 fi if [ x$ENROLLER_BINARY == x ] || [ ! -e "$ENROLLER_BINARY" ]; then echo "Please specify the enroller binary" usage $0 exit 1 fi if [ x$TYPE == x ]; then echo "Please specify the type of image: default or no-default" usage $0 exit 1 fi if [ x$ISO_NAME == x ]; then echo "Please specify the name of output iso" usage $0 exit 1 fi ISO_PATH=$(realpath $ISO_NAME) TMP_DIR=$(mktemp -d) cp $UEFI_SHELL_BINARY $TMP_DIR/Shell.efi cp $ENROLLER_BINARY $TMP_DIR/EnrollDefaultKeys.efi UEFI_BOOT_EFI=$( if [ $ARCH == "X64" ]; then echo bootx64.efi elif [ $ARCH == "AARCH64" ]; then echo bootaa64.efi else exit 1 fi ) UEFI_SHELL_SIZE=$(stat --format=%s -- "$UEFI_SHELL_BINARY") ENROLLER_SIZE=$(stat --format=%s -- "$ENROLLER_BINARY") START_SCRIPT=$TMP_DIR/"startup.nsh" # Enter the first ESP echo "fs0:" > $START_SCRIPT # Enroll the keys if [ $TYPE == "default" ]; then echo "EnrollDefaultKeys.efi" >> $START_SCRIPT else echo "EnrollDefaultKeys.efi --no-default" >> $START_SCRIPT fi # Reset BootOrder echo "setvar BootOrder -guid 8be4df61-93ca-11d2-aa0d-00e098032b8c -bs -rt -nv =" >> $START_SCRIPT # Shutdown the system echo "reset -s" >> $START_SCRIPT UEFI_SHELL_IMAGE=uefi_shell_${ARCH}_${TYPE}.img # Add 1MB then 10% for metadata UEFI_SHELL_IMAGE_KB=$(( (UEFI_SHELL_SIZE + ENROLLER_SIZE + 1 * 1024 * 1024) * 11 / 10 / 1024 )) pushd $TMP_DIR # Create non-partitioned FAT image rm -f -- "$UEFI_SHELL_IMAGE" /usr/sbin/mkdosfs -C "$UEFI_SHELL_IMAGE" -n UEFI_SHELL -- "$UEFI_SHELL_IMAGE_KB" export MTOOLS_SKIP_CHECK=1 mmd -i "$UEFI_SHELL_IMAGE" ::efi mmd -i "$UEFI_SHELL_IMAGE" ::efi/boot mcopy -i "$UEFI_SHELL_IMAGE" Shell.efi ::efi/boot/$UEFI_BOOT_EFI mcopy -i "$UEFI_SHELL_IMAGE" "$START_SCRIPT" ::efi/boot/startup.nsh mcopy -i "$UEFI_SHELL_IMAGE" EnrollDefaultKeys.efi ::EnrollDefaultKeys.efi mdir -i "$UEFI_SHELL_IMAGE" -/ :: # build ISO with FAT image file as El Torito EFI boot image mkisofs -input-charset ASCII -J -rational-rock \ -eltorito-platform efi -eltorito-boot "$UEFI_SHELL_IMAGE" \ -no-emul-boot -o "$ISO_PATH" -- "$UEFI_SHELL_IMAGE" popd #rm -rf $TMP_DIR ++++++ openssl-fix-syntax-error.patch ++++++ From c3656cc594daac8167721dde7220f0e59ae146fc Mon Sep 17 00:00:00 2001 From: "Dr. Matthias St. Pierre" <Matthias.St.Pierre@ncp-e.com> Date: Wed, 11 Sep 2019 10:25:43 +0200 Subject: [PATCH] crypto/threads_none.c: fix syntax error in openssl_get_fork_id() Fixes #9858 Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/9860) --- crypto/threads_none.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/threads_none.c b/crypto/threads_none.c index aabf0e0dc0..aaaaae872a 100644 --- a/crypto/threads_none.c +++ b/crypto/threads_none.c @@ -143,7 +143,7 @@ int openssl_get_fork_id(void) # if defined(OPENSSL_SYS_UNIX) return getpid(); # else - return return 0; + return 0; # endif } #endif -- 2.24.0 ++++++ ovmf-add-exclude-shell-flag.patch ++++++ Index: edk2-edk2-stable201905/OvmfPkg/OvmfPkgX64.fdf =================================================================== --- edk2-edk2-stable201905.orig/OvmfPkg/OvmfPkgX64.fdf +++ edk2-edk2-stable201905/OvmfPkg/OvmfPkgX64.fdf @@ -291,7 +291,9 @@ INF MdeModulePkg/Universal/Disk/UdfDxe/ !if $(TOOL_CHAIN_TAG) != "XCODE5" INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf !endif +!ifndef $(EXCLUDE_SHELL) INF ShellPkg/Application/Shell/Shell.inf +!endif INF MdeModulePkg/Logo/LogoDxe.inf ++++++ ovmf-bsc1119454-additional-scsi-drivers.patch ++++++ ++++ 8397 lines (skipped) ++++++ ovmf-bsc1163927-fix-ip4dxe-and-arpdxe.patch ++++++ From 7f9f7fccf58af2db5ac8c88801f56f4efe664fcb Mon Sep 17 00:00:00 2001 From: Jiaxin Wu <Jiaxin.wu@intel.com> Date: Mon, 29 Apr 2019 09:51:53 +0800 Subject: [PATCH 1/2] NetworkPkg/Ip4Dxe: Check the received package length (CVE-2019-14559). v3: correct the coding style. v2: correct the commit message & add BZ number. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1610 This patch is to check the received package length to make sure the package has a valid length field. Cc: Fu Siyuan <siyuan.fu@intel.com> Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com> (cherry picked from commit 578bcdc2605e3438b9cbdac4e68339f90f5bf8af) --- NetworkPkg/Ip4Dxe/Ip4Input.c | 46 +++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/NetworkPkg/Ip4Dxe/Ip4Input.c b/NetworkPkg/Ip4Dxe/Ip4Input.c index 24c584658803..fc1a892f14eb 100644 --- a/NetworkPkg/Ip4Dxe/Ip4Input.c +++ b/NetworkPkg/Ip4Dxe/Ip4Input.c @@ -1,7 +1,7 @@ /** @file IP4 input process. -Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> +Copyright (c) 2005 - 2020, Intel Corporation. All rights reserved.<BR> (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent @@ -711,10 +711,6 @@ Ip4PreProcessPacket ( // // Check if the IP4 header is correctly formatted. // - if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) { - return EFI_INVALID_PARAMETER; - } - HeadLen = (Head->HeadLen << 2); TotalLen = NTOHS (Head->TotalLen); @@ -808,6 +804,30 @@ Ip4PreProcessPacket ( return EFI_SUCCESS; } +/** + This function checks the IPv4 packet length. + + @param[in] Packet Pointer to the IPv4 Packet to be checked. + + @retval TRUE The input IPv4 packet length is valid. + @retval FALSE The input IPv4 packet length is invalid. + +**/ +BOOLEAN +Ip4IsValidPacketLength ( + IN NET_BUF *Packet + ) +{ + // + // Check the IP4 packet length. + // + if (Packet->TotalSize < IP4_MIN_HEADLEN) { + return FALSE; + } + + return TRUE; +} + /** The IP4 input routine. It is called by the IP4_INTERFACE when a IP4 fragment is received from MNP. @@ -844,6 +864,10 @@ Ip4AccpetFrame ( goto DROP; } + if (!Ip4IsValidPacketLength (Packet)) { + goto RESTART; + } + Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); ASSERT (Head != NULL); OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN; @@ -890,10 +914,14 @@ Ip4AccpetFrame ( // ZeroMem (&ZeroHead, sizeof (IP4_HEAD)); if (0 == CompareMem (Head, &ZeroHead, sizeof (IP4_HEAD))) { - // Packet may have been changed. Head, HeadLen, TotalLen, and - // info must be reloaded bofore use. The ownership of the packet - // is transfered to the packet process logic. - // + // Packet may have been changed. Head, HeadLen, TotalLen, and + // info must be reloaded before use. The ownership of the packet + // is transferred to the packet process logic. + // + if (!Ip4IsValidPacketLength (Packet)) { + goto RESTART; + } + Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); ASSERT (Head != NULL); Status = Ip4PreProcessPacket ( -- 2.25.0 From 03225826203c978146e4067e1d14fe66fcb75e22 Mon Sep 17 00:00:00 2001 From: Siyuan Fu <siyuan.fu@intel.com> Date: Fri, 21 Feb 2020 10:14:18 +0800 Subject: [PATCH 2/2] NetworkPkg/ArpDxe: Recycle invalid ARP packets (CVE-2019-14559) REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2031 This patch triggers the RecycleEvent for invalid ARP packets. Prior to this, we would just ignore invalid ARP packets, and never free them. Cc: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Signed-off-by: Nicholas Armour <nicholas.armour@intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com> (cherry picked from commit 1d3215fd24f47eaa4877542a59b4bbf5afc0cfe8) --- NetworkPkg/ArpDxe/ArpImpl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NetworkPkg/ArpDxe/ArpImpl.c b/NetworkPkg/ArpDxe/ArpImpl.c index 0e9ef103eff9..c7f770db0734 100644 --- a/NetworkPkg/ArpDxe/ArpImpl.c +++ b/NetworkPkg/ArpDxe/ArpImpl.c @@ -1,7 +1,7 @@ /** @file The implementation of the ARP protocol. -Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> +Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -113,7 +113,7 @@ ArpOnFrameRcvdDpc ( // // Restart the receiving if packet size is not correct. // - goto RESTART_RECEIVE; + goto RECYCLE_RXDATA; } // @@ -125,7 +125,7 @@ ArpOnFrameRcvdDpc ( Head->OpCode = NTOHS (Head->OpCode); if (RxData->DataLength < (sizeof (ARP_HEAD) + 2 * Head->HwAddrLen + 2 * Head->ProtoAddrLen)) { - goto RESTART_RECEIVE; + goto RECYCLE_RXDATA; } if ((Head->HwType != ArpService->SnpMode.IfType) || -- 2.25.0 ++++++ ovmf-bsc1163927-fix-ping-and-ip6dxe.patch ++++++ From 6a5e9bdd108741bcc8fd68276116f41b4a35da75 Mon Sep 17 00:00:00 2001 From: Maciej Rabeda <maciej.rabeda@linux.intel.com> Date: Thu, 27 Feb 2020 11:30:43 +0100 Subject: [PATCH 1/3] ShellPkg: Fix 'ping' command Ip4 receive flow. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2032 'ping' command's receive flow utilizes a single Rx token which it attempts to reuse before recycling the previously received packet. This causes a situation where under ICMP traffic, Ping6OnEchoReplyReceived() function will receive an already recycled packet with EFI_SUCCESS token status and finally dereference invalid pointers from RxData structure. Cc: Ray Ni <ray.ni@intel.com> Cc: Zhichao Gao <zhichao.gao@intel.com> Signed-off-by: Maciej Rabeda <maciej.rabeda@linux.intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com> Acked-by: Zhichao Gao <zhichao.gao@intel.com> (cherry picked from commit 65c73df44c61235ede84c5aa1d2eab6650844966) --- ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c b/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c index 23567fa2c1bb..a3fa32515192 100644 --- a/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c +++ b/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ping.c @@ -614,6 +614,11 @@ Ping6OnEchoReplyReceived ( ON_EXIT: + // + // Recycle the packet before reusing RxToken + // + gBS->SignalEvent (Private->IpChoice == PING_IP_CHOICE_IP6?((EFI_IP6_RECEIVE_DATA*)Private->RxToken.Packet.RxData)->RecycleSignal:((EFI_IP4_RECEIVE_DATA*)Private->RxToken.Packet.RxData)->RecycleSignal); + if (Private->RxCount < Private->SendNum) { // // Continue to receive icmp echo reply packets. @@ -632,10 +637,6 @@ ON_EXIT: // Private->Status = EFI_SUCCESS; } - // - // Singal to recycle the each rxdata here, not at the end of process. - // - gBS->SignalEvent (Private->IpChoice == PING_IP_CHOICE_IP6?((EFI_IP6_RECEIVE_DATA*)Private->RxToken.Packet.RxData)->RecycleSignal:((EFI_IP4_RECEIVE_DATA*)Private->RxToken.Packet.RxData)->RecycleSignal); } /** -- 2.25.1 From 35fb4bd10b630663d7eaa6731e15089f2d6091b1 Mon Sep 17 00:00:00 2001 From: Maciej Rabeda <maciej.rabeda@linux.intel.com> Date: Mon, 2 Mar 2020 13:25:20 +0100 Subject: [PATCH 2/3] NetworkPkg/Ip6Dxe: Improve Neightbor Discovery message validation. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2174 Problem has been identified with Ip6ProcessRouterAdvertise() when Router Advertise packet contains options with malicious/invalid 'Length' field. This can lead to platform entering infinite loop when processing options from that packet. Cc: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Signed-off-by: Maciej Rabeda <maciej.rabeda@linux.intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com> (cherry picked from commit 9c20342eed70ec99ec50cd73cb81804299f05403) --- NetworkPkg/Ip6Dxe/Ip6Nd.c | 44 ++++++++++++++++----------- NetworkPkg/Ip6Dxe/Ip6Nd.h | 13 ++++++++ NetworkPkg/Ip6Dxe/Ip6Option.c | 57 ++++++++++++++++++++++++++--------- 3 files changed, 83 insertions(+), 31 deletions(-) diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.c b/NetworkPkg/Ip6Dxe/Ip6Nd.c index 67d7022a7673..1254f0fdd921 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Nd.c +++ b/NetworkPkg/Ip6Dxe/Ip6Nd.c @@ -1927,7 +1927,7 @@ Ip6ProcessRouterAdvertise ( UINT32 ReachableTime; UINT32 RetransTimer; UINT16 RouterLifetime; - UINT16 Offset; + UINT32 Offset; UINT8 Type; UINT8 Length; IP6_ETHER_ADDR_OPTION LinkLayerOption; @@ -2094,10 +2094,11 @@ Ip6ProcessRouterAdvertise ( // // The only defined options that may appear are the Source // Link-Layer Address, Prefix information and MTU options. - // All included options have a length that is greater than zero. + // All included options have a length that is greater than zero and + // fit within the input packet. // Offset = 16; - while (Offset < Head->PayloadLength) { + while (Offset < (UINT32) Head->PayloadLength) { NetbufCopy (Packet, Offset, sizeof (UINT8), &Type); switch (Type) { case Ip6OptionEtherSource: @@ -2105,9 +2106,12 @@ Ip6ProcessRouterAdvertise ( // Update the neighbor cache // NetbufCopy (Packet, Offset, sizeof (IP6_ETHER_ADDR_OPTION), (UINT8 *) &LinkLayerOption); - if (LinkLayerOption.Length <= 0) { - goto Exit; - } + + // + // Option size validity ensured by Ip6IsNDOptionValid(). + // + ASSERT (LinkLayerOption.Length != 0); + ASSERT (Offset + (UINT32) LinkLayerOption.Length * 8 >= (UINT32) Head->PayloadLength); ZeroMem (&LinkLayerAddress, sizeof (EFI_MAC_ADDRESS)); CopyMem (&LinkLayerAddress, LinkLayerOption.EtherAddr, 6); @@ -2151,13 +2155,17 @@ Ip6ProcessRouterAdvertise ( } } - Offset = (UINT16) (Offset + (UINT16) LinkLayerOption.Length * 8); + Offset += (UINT32) LinkLayerOption.Length * 8; break; case Ip6OptionPrefixInfo: NetbufCopy (Packet, Offset, sizeof (IP6_PREFIX_INFO_OPTION), (UINT8 *) &PrefixOption); - if (PrefixOption.Length != 4) { - goto Exit; - } + + // + // Option size validity ensured by Ip6IsNDOptionValid(). + // + ASSERT (PrefixOption.Length == 4); + ASSERT (Offset + (UINT32) PrefixOption.Length * 8 >= (UINT32) Head->PayloadLength); + PrefixOption.ValidLifetime = NTOHL (PrefixOption.ValidLifetime); PrefixOption.PreferredLifetime = NTOHL (PrefixOption.PreferredLifetime); @@ -2321,9 +2329,12 @@ Ip6ProcessRouterAdvertise ( break; case Ip6OptionMtu: NetbufCopy (Packet, Offset, sizeof (IP6_MTU_OPTION), (UINT8 *) &MTUOption); - if (MTUOption.Length != 1) { - goto Exit; - } + + // + // Option size validity ensured by Ip6IsNDOptionValid(). + // + ASSERT (MTUOption.Length == 1); + ASSERT (Offset + (UINT32) MTUOption.Length * 8 >= (UINT32) Head->PayloadLength); // // Use IPv6 minimum link MTU 1280 bytes as the maximum packet size in order @@ -2338,11 +2349,10 @@ Ip6ProcessRouterAdvertise ( // Silently ignore unrecognized options // NetbufCopy (Packet, Offset + sizeof (UINT8), sizeof (UINT8), &Length); - if (Length <= 0) { - goto Exit; - } - Offset = (UINT16) (Offset + (UINT16) Length * 8); + ASSERT (Length != 0); + + Offset += (UINT32) Length * 8; break; } } diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.h b/NetworkPkg/Ip6Dxe/Ip6Nd.h index 891a32d7d3ca..e4004662951a 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Nd.h +++ b/NetworkPkg/Ip6Dxe/Ip6Nd.h @@ -56,12 +56,21 @@ VOID VOID *Context ); +typedef struct _IP6_OPTION_HEADER { + UINT8 Type; + UINT8 Length; +} IP6_OPTION_HEADER; + +STATIC_ASSERT (sizeof (IP6_OPTION_HEADER) == 2, "IP6_OPTION_HEADER is expected to be exactly 2 bytes long."); + typedef struct _IP6_ETHE_ADDR_OPTION { UINT8 Type; UINT8 Length; UINT8 EtherAddr[6]; } IP6_ETHER_ADDR_OPTION; +STATIC_ASSERT (sizeof (IP6_ETHER_ADDR_OPTION) == 8, "IP6_ETHER_ADDR_OPTION is expected to be exactly 8 bytes long."); + typedef struct _IP6_MTU_OPTION { UINT8 Type; UINT8 Length; @@ -69,6 +78,8 @@ typedef struct _IP6_MTU_OPTION { UINT32 Mtu; } IP6_MTU_OPTION; +STATIC_ASSERT (sizeof (IP6_MTU_OPTION) == 8, "IP6_MTU_OPTION is expected to be exactly 8 bytes long."); + typedef struct _IP6_PREFIX_INFO_OPTION { UINT8 Type; UINT8 Length; @@ -80,6 +91,8 @@ typedef struct _IP6_PREFIX_INFO_OPTION { EFI_IPv6_ADDRESS Prefix; } IP6_PREFIX_INFO_OPTION; +STATIC_ASSERT (sizeof (IP6_PREFIX_INFO_OPTION) == 32, "IP6_PREFIX_INFO_OPTION is expected to be exactly 32 bytes long."); + typedef VOID (*IP6_DAD_CALLBACK) ( diff --git a/NetworkPkg/Ip6Dxe/Ip6Option.c b/NetworkPkg/Ip6Dxe/Ip6Option.c index 4d92a852dc86..6b4b029d1479 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Option.c +++ b/NetworkPkg/Ip6Dxe/Ip6Option.c @@ -129,45 +129,74 @@ Ip6IsNDOptionValid ( IN UINT16 OptionLen ) { - UINT16 Offset; - UINT8 OptionType; + UINT32 Offset; UINT16 Length; + IP6_OPTION_HEADER *OptionHeader; + + if (Option == NULL) { + ASSERT (Option != NULL); + return FALSE; + } Offset = 0; - while (Offset < OptionLen) { - OptionType = *(Option + Offset); - Length = (UINT16) (*(Option + Offset + 1) * 8); + // + // RFC 4861 states that Neighbor Discovery packet can contain zero or more + // options. Start processing the options if at least Type + Length fields + // fit within the input buffer. + // + while (Offset + sizeof (IP6_OPTION_HEADER) - 1 < OptionLen) { + OptionHeader = (IP6_OPTION_HEADER*) (Option + Offset); + Length = (UINT16) OptionHeader->Length * 8; - switch (OptionType) { + switch (OptionHeader->Type) { case Ip6OptionPrefixInfo: if (Length != 32) { return FALSE; } - break; case Ip6OptionMtu: if (Length != 8) { return FALSE; } - break; default: - // - // Check the length of Ip6OptionEtherSource, Ip6OptionEtherTarget, and - // Ip6OptionRedirected here. For unrecognized options, silently ignore - // and continue processing the message. - // + // RFC 4861 states that Length field cannot be 0. if (Length == 0) { return FALSE; } + break; + } + + // + // Check whether recognized options are within the input buffer's scope. + // + switch (OptionHeader->Type) { + case Ip6OptionEtherSource: + case Ip6OptionEtherTarget: + case Ip6OptionPrefixInfo: + case Ip6OptionRedirected: + case Ip6OptionMtu: + if (Offset + Length > (UINT32) OptionLen) { + return FALSE; + } + break; + default: + // + // Unrecognized options can be either valid (but unused) or invalid + // (garbage in between or right after valid options). Silently ignore. + // break; } - Offset = (UINT16) (Offset + Length); + // + // Advance to the next option. + // Length already considers option header's Type + Length. + // + Offset += Length; } return TRUE; -- 2.25.1 From 19f82aecd83989cde630c1f8eb119713f1574908 Mon Sep 17 00:00:00 2001 From: Maciej Rabeda <maciej.rabeda@linux.intel.com> Date: Wed, 1 Apr 2020 11:43:55 +0200 Subject: [PATCH 3/3] NetworkPkg/Ip6Dxe: Fix ASSERT logic in Ip6ProcessRouterAdvertise() REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2655 This patch fixes reversed logic of recently added ASSERTs which should ensure that Ip6IsNDOptionValid() implementation properly reacts to invalid packets. Cc: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Signed-off-by: Maciej Rabeda <maciej.rabeda@linux.intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Fixes: 9c20342eed70ec99ec50cd73cb81804299f05403 (cherry picked from commit 4deef2d865efdc61d1a53ad7bd48f9dd42560b45) --- NetworkPkg/Ip6Dxe/Ip6Nd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NetworkPkg/Ip6Dxe/Ip6Nd.c b/NetworkPkg/Ip6Dxe/Ip6Nd.c index 1254f0fdd921..9e688b2eb728 100644 --- a/NetworkPkg/Ip6Dxe/Ip6Nd.c +++ b/NetworkPkg/Ip6Dxe/Ip6Nd.c @@ -2111,7 +2111,7 @@ Ip6ProcessRouterAdvertise ( // Option size validity ensured by Ip6IsNDOptionValid(). // ASSERT (LinkLayerOption.Length != 0); - ASSERT (Offset + (UINT32) LinkLayerOption.Length * 8 >= (UINT32) Head->PayloadLength); + ASSERT (Offset + (UINT32) LinkLayerOption.Length * 8 <= (UINT32) Head->PayloadLength); ZeroMem (&LinkLayerAddress, sizeof (EFI_MAC_ADDRESS)); CopyMem (&LinkLayerAddress, LinkLayerOption.EtherAddr, 6); @@ -2164,7 +2164,7 @@ Ip6ProcessRouterAdvertise ( // Option size validity ensured by Ip6IsNDOptionValid(). // ASSERT (PrefixOption.Length == 4); - ASSERT (Offset + (UINT32) PrefixOption.Length * 8 >= (UINT32) Head->PayloadLength); + ASSERT (Offset + (UINT32) PrefixOption.Length * 8 <= (UINT32) Head->PayloadLength); PrefixOption.ValidLifetime = NTOHL (PrefixOption.ValidLifetime); PrefixOption.PreferredLifetime = NTOHL (PrefixOption.PreferredLifetime); @@ -2334,7 +2334,7 @@ Ip6ProcessRouterAdvertise ( // Option size validity ensured by Ip6IsNDOptionValid(). // ASSERT (MTUOption.Length == 1); - ASSERT (Offset + (UINT32) MTUOption.Length * 8 >= (UINT32) Head->PayloadLength); + ASSERT (Offset + (UINT32) MTUOption.Length * 8 <= (UINT32) Head->PayloadLength); // // Use IPv6 minimum link MTU 1280 bytes as the maximum packet size in order -- 2.25.1 ++++++ ovmf-bsc1163959-PiDxeS3BootScriptLib-fix-numeric-truncation.patch ++++++ From 322ac05f8bbc1bce066af1dabd1b70ccdbe28891 Mon Sep 17 00:00:00 2001 From: Hao A Wu <hao.a.wu@intel.com> Date: Fri, 28 Jun 2019 14:15:55 +0800 Subject: [PATCH 1/1] MdeModulePkg/PiDxeS3BootScriptLib: Fix potential numeric truncation (CVE-2019-14563) REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2001 For S3BootScriptLib APIs: S3BootScriptSaveIoWrite S3BootScriptSaveMemWrite S3BootScriptSavePciCfgWrite S3BootScriptSavePciCfg2Write S3BootScriptSaveSmbusExecute S3BootScriptSaveInformation S3BootScriptSaveInformationAsciiString S3BootScriptLabel (happen in S3BootScriptLabelInternal()) possible numeric truncations will happen that may lead to S3 boot script entry with improper size being returned to store the boot script data. This commit will add checks to prevent this kind of issue. Please note that the remaining S3BootScriptLib APIs: S3BootScriptSaveIoReadWrite S3BootScriptSaveMemReadWrite S3BootScriptSavePciCfgReadWrite S3BootScriptSavePciCfg2ReadWrite S3BootScriptSaveStall S3BootScriptSaveDispatch2 S3BootScriptSaveDispatch S3BootScriptSaveMemPoll S3BootScriptSaveIoPoll S3BootScriptSavePciPoll S3BootScriptSavePci2Poll S3BootScriptCloseTable S3BootScriptExecute S3BootScriptMoveLastOpcode S3BootScriptCompare are not affected by such numeric truncation. Signed-off-by: Hao A Wu <hao.a.wu@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Eric Dong <eric.dong@intel.com> Acked-by: Jian J Wang <jian.j.wang@intel.com> --- .../PiDxeS3BootScriptLib/BootScriptSave.c | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c index 9106e7d0f9f5..9315fc9f0188 100644 --- a/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c +++ b/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptSave.c @@ -1,7 +1,7 @@ /** @file Save the S3 data to S3 boot script. - Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent @@ -1006,6 +1006,14 @@ S3BootScriptSaveIoWrite ( EFI_BOOT_SCRIPT_IO_WRITE ScriptIoWrite; WidthInByte = (UINT8) (0x01 << (Width & 0x03)); + + // + // Truncation check + // + if ((Count > MAX_UINT8) || + (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_IO_WRITE))) { + return RETURN_OUT_OF_RESOURCES; + } Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_WRITE) + (WidthInByte * Count)); Script = S3BootScriptGetEntryAddAddress (Length); @@ -1102,6 +1110,14 @@ S3BootScriptSaveMemWrite ( EFI_BOOT_SCRIPT_MEM_WRITE ScriptMemWrite; WidthInByte = (UINT8) (0x01 << (Width & 0x03)); + + // + // Truncation check + // + if ((Count > MAX_UINT8) || + (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_MEM_WRITE))) { + return RETURN_OUT_OF_RESOURCES; + } Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_MEM_WRITE) + (WidthInByte * Count)); Script = S3BootScriptGetEntryAddAddress (Length); @@ -1206,6 +1222,14 @@ S3BootScriptSavePciCfgWrite ( } WidthInByte = (UINT8) (0x01 << (Width & 0x03)); + + // + // Truncation check + // + if ((Count > MAX_UINT8) || + (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE))) { + return RETURN_OUT_OF_RESOURCES; + } Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) + (WidthInByte * Count)); Script = S3BootScriptGetEntryAddAddress (Length); @@ -1324,6 +1348,14 @@ S3BootScriptSavePciCfg2Write ( } WidthInByte = (UINT8) (0x01 << (Width & 0x03)); + + // + // Truncation check + // + if ((Count > MAX_UINT8) || + (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE))) { + return RETURN_OUT_OF_RESOURCES; + } Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE) + (WidthInByte * Count)); Script = S3BootScriptGetEntryAddAddress (Length); @@ -1549,6 +1581,12 @@ S3BootScriptSaveSmbusExecute ( return Status; } + // + // Truncation check + // + if (BufferLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)) { + return RETURN_OUT_OF_RESOURCES; + } DataSize = (UINT8)(sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE) + BufferLength); Script = S3BootScriptGetEntryAddAddress (DataSize); @@ -1736,6 +1774,12 @@ S3BootScriptSaveInformation ( UINT8 *Script; EFI_BOOT_SCRIPT_INFORMATION ScriptInformation; + // + // Truncation check + // + if (InformationLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_INFORMATION)) { + return RETURN_OUT_OF_RESOURCES; + } Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_INFORMATION) + InformationLength); Script = S3BootScriptGetEntryAddAddress (Length); @@ -2195,6 +2239,12 @@ S3BootScriptLabelInternal ( UINT8 *Script; EFI_BOOT_SCRIPT_INFORMATION ScriptInformation; + // + // Truncation check + // + if (InformationLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_INFORMATION)) { + return RETURN_OUT_OF_RESOURCES; + } Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_INFORMATION) + InformationLength); Script = S3BootScriptGetEntryAddAddress (Length); -- 2.25.0 ++++++ ovmf-bsc1163969-fix-DxeImageVerificationHandler.patch ++++++ ++++ 1870 lines (skipped) ++++++ ovmf-bsc1175476-fix-DxeImageVerificationLib-overflow.patch ++++++ From e4c140c87487d523bb3585e419ea9df122fd3f67 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek <lersek@redhat.com> Date: Tue, 1 Sep 2020 11:12:19 +0200 Subject: [PATCH 1/3] SecurityPkg/DxeImageVerificationLib: extract SecDataDirEnd, SecDataDirLeft MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following two quantities: SecDataDir->VirtualAddress + SecDataDir->Size SecDataDir->VirtualAddress + SecDataDir->Size - OffSet are used multiple times in DxeImageVerificationHandler(). Introduce helper variables for them: "SecDataDirEnd" and "SecDataDirLeft", respectively. This saves us multiple calculations and significantly simplifies the code. Note that all three summands above have type UINT32, therefore the new variables are also of type UINT32. This patch does not change behavior. (Note that the code already handles the case when the SecDataDir->VirtualAddress + SecDataDir->Size UINT32 addition overflows -- namely, in that case, the certificate loop is never entered, and the corruption check right after the loop fires.) Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Wenyi Xie <xiewenyi2@huawei.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2215 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20200901091221.20948-2-lersek@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Tested-by: Wenyi Xie <xiewenyi2@huawei.com> Reviewed-by: Min M Xu <min.m.xu@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> (cherry picked from commit 503248ccdf45c14d4040ce44163facdc212e4991) --- .../DxeImageVerificationLib.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c index b7fa8ea8c55c..fb3895661b5e 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c @@ -1652,6 +1652,8 @@ DxeImageVerificationHandler ( UINT8 *AuthData; UINTN AuthDataSize; EFI_IMAGE_DATA_DIRECTORY *SecDataDir; + UINT32 SecDataDirEnd; + UINT32 SecDataDirLeft; UINT32 OffSet; CHAR16 *NameStr; RETURN_STATUS PeCoffStatus; @@ -1849,12 +1851,14 @@ DxeImageVerificationHandler ( // "Attribute Certificate Table". // The first certificate starts at offset (SecDataDir->VirtualAddress) from the start of the file. // + SecDataDirEnd = SecDataDir->VirtualAddress + SecDataDir->Size; for (OffSet = SecDataDir->VirtualAddress; - OffSet < (SecDataDir->VirtualAddress + SecDataDir->Size); + OffSet < SecDataDirEnd; OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength))) { WinCertificate = (WIN_CERTIFICATE *) (mImageBase + OffSet); - if ((SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) <= sizeof (WIN_CERTIFICATE) || - (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) < WinCertificate->dwLength) { + SecDataDirLeft = SecDataDirEnd - OffSet; + if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE) || + SecDataDirLeft < WinCertificate->dwLength) { break; } @@ -1948,7 +1952,7 @@ DxeImageVerificationHandler ( } } - if (OffSet != (SecDataDir->VirtualAddress + SecDataDir->Size)) { + if (OffSet != SecDataDirEnd) { // // The Size in Certificate Table or the attribute certificate table is corrupted. // -- 2.28.0 From a70b1a7653b57f9f1c15e513288cfe9ab76192f8 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek <lersek@redhat.com> Date: Tue, 1 Sep 2020 11:12:20 +0200 Subject: [PATCH 2/3] SecurityPkg/DxeImageVerificationLib: assign WinCertificate after size check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the (SecDataDirLeft <= sizeof (WIN_CERTIFICATE)) check only guards the de-referencing of the "WinCertificate" pointer. It does not guard the calculation of the pointer itself: WinCertificate = (WIN_CERTIFICATE *) (mImageBase + OffSet); This is wrong; if we don't know for sure that we have enough room for a WIN_CERTIFICATE, then even creating such a pointer, not just de-referencing it, may invoke undefined behavior. Move the pointer calculation after the size check. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Wenyi Xie <xiewenyi2@huawei.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2215 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20200901091221.20948-3-lersek@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Tested-by: Wenyi Xie <xiewenyi2@huawei.com> Reviewed-by: Min M Xu <min.m.xu@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> (cherry picked from commit a7632e913c1c106f436aefd5e76c394249c383a8) --- .../DxeImageVerificationLib/DxeImageVerificationLib.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c index fb3895661b5e..d544ba8f0a3e 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c @@ -1855,10 +1855,12 @@ DxeImageVerificationHandler ( for (OffSet = SecDataDir->VirtualAddress; OffSet < SecDataDirEnd; OffSet += (WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength))) { - WinCertificate = (WIN_CERTIFICATE *) (mImageBase + OffSet); SecDataDirLeft = SecDataDirEnd - OffSet; - if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE) || - SecDataDirLeft < WinCertificate->dwLength) { + if (SecDataDirLeft <= sizeof (WIN_CERTIFICATE)) { + break; + } + WinCertificate = (WIN_CERTIFICATE *) (mImageBase + OffSet); + if (SecDataDirLeft < WinCertificate->dwLength) { break; } -- 2.28.0 From ce4db99abb9f6b8afe71ed29d83fadf9560ca1b2 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek <lersek@redhat.com> Date: Tue, 1 Sep 2020 11:12:21 +0200 Subject: [PATCH 3/3] SecurityPkg/DxeImageVerificationLib: catch alignment overflow (CVE-2019-14562) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DxeImageVerificationHandler() function currently checks whether "SecDataDir" has enough room for "WinCertificate->dwLength". However, for advancing "OffSet", "WinCertificate->dwLength" is aligned to the next multiple of 8. If "WinCertificate->dwLength" is large enough, the alignment will return 0, and "OffSet" will be stuck at the same value. Check whether "SecDataDir" has room left for both "WinCertificate->dwLength" and the alignment. Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Min Xu <min.m.xu@intel.com> Cc: Wenyi Xie <xiewenyi2@huawei.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2215 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20200901091221.20948-4-lersek@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Tested-by: Wenyi Xie <xiewenyi2@huawei.com> Reviewed-by: Min M Xu <min.m.xu@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> (cherry picked from commit 0b143fa43e92be15d11e22f80773bcb1b2b0608f) --- .../Library/DxeImageVerificationLib/DxeImageVerificationLib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c index d544ba8f0a3e..d8b7b15224b6 100644 --- a/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c +++ b/SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.c @@ -1860,7 +1860,9 @@ DxeImageVerificationHandler ( break; } WinCertificate = (WIN_CERTIFICATE *) (mImageBase + OffSet); - if (SecDataDirLeft < WinCertificate->dwLength) { + if (SecDataDirLeft < WinCertificate->dwLength || + (SecDataDirLeft - WinCertificate->dwLength < + ALIGN_SIZE (WinCertificate->dwLength))) { break; } -- 2.28.0 ++++++ ovmf-bsc1177789-cryptopkg-fix-null-dereference.patch ++++++ From c7311c794c593745b852ee6c0bcdb8a5e71d6ace Mon Sep 17 00:00:00 2001 From: Jian J Wang <jian.j.wang@intel.com> Date: Thu, 25 Apr 2019 23:42:16 +0800 Subject: [PATCH 1/1] CryptoPkg/BaseCryptLib: fix NULL dereference (CVE-2019-14584) REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1914 AuthenticodeVerify() calls OpenSSLs d2i_PKCS7() API to parse asn encoded signed authenticode pkcs#7 data. when this successfully returns, a type check is done by calling PKCS7_type_is_signed() and then Pkcs7->d.sign->contents->type is used. It is possible to construct an asn1 blob that successfully decodes and have d2i_PKCS7() return a valid pointer and have PKCS7_type_is_signed() also return success but have Pkcs7->d.sign be a NULL pointer. Looking at how PKCS7_verify() [inside of OpenSSL] implements checking for pkcs7 structs it does the following: - call PKCS7_type_is_signed() - call PKCS7_get_detached() Looking into how PKCS7_get_detatched() is implemented, it checks to see if p7->d.sign is NULL or if p7->d.sign->contents->d.ptr is NULL. As such, the fix is to do the same as OpenSSL after calling d2i_PKCS7(). - Add call to PKS7_get_detached() to existing error handling Cc: Xiaoyu Lu <xiaoyux.lu@intel.com> Cc: Guomin Jiang <guomin.jiang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Jian J Wang <jian.j.wang@intel.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com> (cherry picked from commit 26442d11e620a9e81c019a24a4ff38441c64ba10) --- CryptoPkg/Library/BaseCryptLib/Pk/CryptAuthenticode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptAuthenticode.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptAuthenticode.c index 2772b1e2be3c..3c2d14a88bce 100644 --- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptAuthenticode.c +++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptAuthenticode.c @@ -9,7 +9,7 @@ AuthenticodeVerify() will get PE/COFF Authenticode and will do basic check for data structure. -Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR> +Copyright (c) 2011 - 2020, Intel Corporation. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -100,7 +100,7 @@ AuthenticodeVerify ( // // Check if it's PKCS#7 Signed Data (for Authenticode Scenario) // - if (!PKCS7_type_is_signed (Pkcs7)) { + if (!PKCS7_type_is_signed (Pkcs7) || PKCS7_get_detached (Pkcs7)) { goto _Exit; } -- 2.28.0 ++++++ ovmf-disable-ia32-firmware-piepic.patch ++++++ Index: edk2-edk2-stable201905/BaseTools/Conf/tools_def.template =================================================================== --- edk2-edk2-stable201905.orig/BaseTools/Conf/tools_def.template +++ edk2-edk2-stable201905/BaseTools/Conf/tools_def.template @@ -1738,7 +1738,7 @@ DEFINE GCC_AARCH64_RC_FLAGS = -I DEFINE GCC48_ALL_CC_FLAGS = -g -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings DEFINE GCC48_IA32_X64_DLINK_COMMON = -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x20 -DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) -m32 -march=i586 -malign-double -fno-stack-protector -D EFI32 -fno-asynchronous-unwind-tables -Wno-address +DEFINE GCC48_IA32_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) -m32 -march=i586 -malign-double -fno-stack-protector -D EFI32 -fno-asynchronous-unwind-tables -Wno-address -fno-pic -fno-pie DEFINE GCC48_X64_CC_FLAGS = DEF(GCC48_ALL_CC_FLAGS) -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address DEFINE GCC48_IA32_X64_ASLDLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,ReferenceAcpiTable -u ReferenceAcpiTable DEFINE GCC48_IA32_X64_DLINK_FLAGS = DEF(GCC48_IA32_X64_DLINK_COMMON) -Wl,--entry,$(IMAGE_ENTRY_POINT) -u $(IMAGE_ENTRY_POINT) -Wl,-Map,$(DEST_DIR_DEBUG)/$(BASE_NAME).map,--whole-archive ++++++ ovmf-gdb-symbols.patch ++++++ ++++ 632 lines (skipped) ++++++ ovmf-pie.patch ++++++ Index: edk2-edk2-stable201905/BaseTools/Source/C/Makefiles/header.makefile =================================================================== --- edk2-edk2-stable201905.orig/BaseTools/Source/C/Makefiles/header.makefile +++ edk2-edk2-stable201905/BaseTools/Source/C/Makefiles/header.makefile @@ -75,7 +75,7 @@ else BUILD_CFLAGS = -MD -fshort-wchar -fno-strict-aliasing -fwrapv \ -fno-delete-null-pointer-checks -Wall -Werror \ -Wno-deprecated-declarations -Wno-stringop-truncation -Wno-restrict \ --Wno-unused-result -nostdlib -g +-Wno-unused-result -nostdlib -g -fPIE endif BUILD_LFLAGS = BUILD_CXXFLAGS = -Wno-unused-result ++++++ ovmf-rpmlintrc ++++++ addFilter("unstripped-binary-or-object /usr/lib/debug/*") addFilter("statically-linked-binary /usr/lib/debug/*") addFilter("executable-stack /usr/lib/debug/*") addFilter("position-independent-executable-suggested /usr/lib/debug/*") ++++++ ovmf-set-fixed-enroll-time.patch ++++++ From c0cec3409f3abda1e2359a79ccac575b4ea1838b Mon Sep 17 00:00:00 2001 From: Gary Lin <glin@suse.com> Date: Tue, 21 May 2019 16:56:06 +0800 Subject: [PATCH 1/1] OvmfPkg/EnrollDefaultKeys: Set the fixed time For the reproducible build, we need to set the fixed time when setting the authenticate variables. Signed-off-by: Gary Lin <glin@suse.com> --- OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c index f45cb799f726..0e42e49d48f2 100644 --- a/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c +++ b/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c @@ -301,6 +301,16 @@ EnrollListOfCerts ( if (EFI_ERROR (Status)) { goto FreeData; } + + // Set the fixed time for the reproducible build + // 2019-5-20 00:00:00 + SingleHeader->TimeStamp.Year = 2019; + SingleHeader->TimeStamp.Month = 5; + SingleHeader->TimeStamp.Day = 20; + SingleHeader->TimeStamp.Hour = 0; + SingleHeader->TimeStamp.Minute = 0; + SingleHeader->TimeStamp.Second = 0; + SingleHeader->TimeStamp.Pad1 = 0; SingleHeader->TimeStamp.Nanosecond = 0; SingleHeader->TimeStamp.TimeZone = 0; -- 2.21.0
participants (1)
-
User for buildservice source handling