From b0d4fdcac6c495f9496262e1124996f398fa1134 Mon Sep 17 00:00:00 2001 From: sun_hai_10 Date: Thu, 29 Feb 2024 20:25:22 +0800 Subject: [PATCH] update to 2.12 --- ...-Fix-user-facing-typo-with-an-incorr.patch | 24 - ...-Properly-disable-the-os-prober-by-d.patch | 71 - ...tes-Disable-the-os-prober-by-default.patch | 70 - ...d-support-for-Linux-EFI-stub-loading.patch | 983 -- 0005-Rework-linux-command.patch | 109 - 0006-Rework-linux16-command.patch | 99 - ...ecureboot-support-on-efi-chainloader.patch | 1401 --- ...loaders-that-link-in-efi-mode-honor-.patch | 390 - ...rch-64-on-32-boot-in-linuxefi-loader.patch | 264 - 0010-re-write-.gitignore.patch | 248 - ...ient-architecture-CAS-reboot-support.patch | 176 - ...nsole-display-attr-when-clear-screen.patch | 31 - ...video-support-for-IBM-power-machines.patch | 65 - 0014-Move-bash-completion-script-922997.patch | 52 - ...o-include-entries-by-title-not-just-.patch | 140 - 0016-Make-exit-take-a-return-code.patch | 267 - ...es-load-an-env-block-from-a-variable.patch | 89 - 0018-Migrate-PPC-from-Yaboot-to-Grub2.patch | 154 - 0019-Add-fw_path-variable-revised.patch | 81 - ...-hex-hex-straight-through-unmolested.patch | 173 - ...g-module-to-parse-Boot-Loader-Specif.patch | 1609 --- 0022-Add-devicetree-loading.patch | 68 - 0023-Enable-pager-by-default.-985860.patch | 23 - ...n-t-say-GNU-Linux-in-generated-menus.patch | 42 - ...rame-to-list-of-relocations-stripped.patch | 22 - ...password-to-boot-entries-generated-b.patch | 28 - ...f-man-pages-with-slightly-nicer-ones.patch | 1959 ---- ...ix-when-fallback-searching-for-grub-.patch | 41 - ...-before-grub.cfg-on-tftp-config-file.patch | 127 - ...CLASS-in-10_linux-from-etc-os-releas.patch | 29 - ...t-ordering-for-.debug-and-rescue-ker.patch | 30 - 0032-Try-prefix-if-fw_path-doesn-t-work.patch | 222 - 0033-Use-rpm-s-sort-for-grub2-mkconfig.patch | 475 - ...fig-construct-titles-that-look-like-.patch | 69 - ...ly-grub2-password-config-tool-985962.patch | 269 - 0036-tcp-add-window-scaling-support.patch | 87 - ...net-and-bootp-add-support-for-dhcpv6.patch | 651 -- ...rnel-settings-and-use-it-in-10_linux.patch | 296 - ...1374141-fix-incorrect-mask-for-ppc64.patch | 48 - 0040-Make-grub_fatal-also-backtrace.patch | 172 - ...ix-up-some-man-pages-rpmdiff-noticed.patch | 150 - ...fo-pages-say-grub2-where-appropriate.patch | 1008 -- ...-chainloader-entries-don-t-try-any-x.patch | 124 - ...-Add-ability-to-boot-from-subvolumes.patch | 703 -- ...port-btrfs_subvol-and-btrfs_subvolid.patch | 26 - 0046-grub2-btrfs-03-follow_default.patch | 198 - 0047-grub2-btrfs-04-grub2-install.patch | 176 - 0048-grub2-btrfs-05-grub2-mkconfig.patch | 129 - 0049-grub2-btrfs-06-subvol-mount.patch | 539 - ...subvol-name-scheme-to-support-old-sn.patch | 58 - ...-correctly-with-btrfs-snapshots-bsc-.patch | 274 - ...ocate_pool-and-grub_efi_free_pool-wr.patch | 72 - ...fi_.-memory-helpers-where-reasonable.patch | 106 - 0054-Add-PRIxGRUB_EFI_STATUS-and-use-it.patch | 48 - 0055-don-t-use-int-for-efi-status.patch | 22 - ...INIT-declare-its-function-prototypes.patch | 29 - ...-efi-as-HFS-on-ppc-machines-in-grub-.patch | 41 - ...d-xen-or-multiboot-2-modules-as-need.patch | 47 - ...-calibration-not-take-51-seconds-to-.patch | 211 - 0060-align-struct-efi_variable-better.patch | 33 - 0061-Add-BLS-support-to-grub-mkconfig.patch | 399 - ...-backtrace-on-grub_abort-for-grub-em.patch | 26 - ...nux-and-initrd-commands-for-grub-emu.patch | 350 - 0064-Add-grub2-switch-to-blscfg.patch | 410 - 0065-make-better-backtraces.patch | 910 -- ...w-our-startup-message-if-debug-is-se.patch | 23 - ...-some-minor-include-path-weirdnesses.patch | 137 - ...it-possible-to-enabled-build-id-sha1.patch | 61 - ...f-grub_dprintf-without-the-file-line.patch | 56 - ...dprintf-that-tells-us-load-addresses.patch | 178 - 0071-Fixup-for-newer-compiler.patch | 36 - ...-export-the-start-and-_start-symbols.patch | 42 - 0073-Fixup-for-newer-compiler.patch | 22 - ...pport-for-non-Ethernet-network-cards.patch | 766 -- ...racketed-ipv6-addrs-and-port-numbers.patch | 270 - 0076-bootp-New-net_bootp6-command.patch | 1368 --- 0077-efinet-UEFI-IPv6-PXE-support.patch | 126 - 0078-grub.texi-Add-net_bootp6-doument.patch | 48 - ...essing-DHCPACK-packet-from-HTTP-Boot.patch | 108 - ...etting-network-from-UEFI-device-path.patch | 405 - ...etting-DNS-server-from-UEFI-protocol.patch | 336 - 0082-Support-UEFI-networking-protocols.patch | 5053 ---------- 0083-AUDIT-0-http-boot-tracker-bug.patch | 62 - ...-incr-command-to-increment-integer-v.patch | 93 - 0085-Add-auto-hide-menu-support.patch | 189 - 0086-Add-grub-set-bootflag-utility.patch | 295 - ...b-boot-indeterminate.service-example.patch | 33 - 0088-gentpl-add-disable-support.patch | 46 - 0089-gentpl-add-pc-firmware-type.patch | 22 - ...e-the-firmware-acceleration-for-http.patch | 25 - ...ot_url-reflect-the-protocol-hostname.patch | 50 - ...n-tell-configure-which-cflags-utils-.patch | 149 - ...make-it-possible-to-run-checkers-on-.patch | 58 - 0094-Rework-how-the-fdt-command-builds.patch | 123 - ...able-non-wordsize-allocations-on-arm.patch | 41 - ...nd-prefix-when-HTTP-path-is-relative.patch | 152 - 0097-Make-grub_error-more-verbose.patch | 61 - ...eset-an-alias-for-the-reboot-command.patch | 40 - 0099-Add-a-version-command.patch | 132 - ...dprintf-and-nerf-dprintf-in-script.c.patch | 74 - ...-Better-memory-allocation-and-error-.patch | 279 - ...tter-locations-for-kernel-and-initrd.patch | 211 - ...p-all-the-places-Wsign-compare-error.patch | 397 - ...gn-compare-Wno-conversion-Wno-error-.patch | 59 - ...ce-buffers-for-reading-to-addresses-.patch | 101 - ...-arrange-grub_cmd_linux-a-little-bit.patch | 133 - ...e-our-own-allocator-for-kernel-stuff.patch | 258 - ...itrd-params-cmdline-allocations-abov.patch | 171 - 0109-Fix-getroot.c-s-trampolines.patch | 47 - ...not-allow-stack-trampolines-anywhere.patch | 38 - 0111-Reimplement-boot_counter.patch | 196 - ...ntry-selection-based-on-ID-and-title.patch | 233 - ...try-users-option-argument-to-be-opti.patch | 46 - ...export-env-and-efi-load-env-commands.patch | 346 - ...le-to-subtract-conditions-from-debug.patch | 45 - ...bles-from-the-initial-context-when-c.patch | 44 - ...-boot-success-reset-from-menu-auto-h.patch | 168 - ...ix-systemctl-kexec-exit-status-check.patch | 37 - ...b-emu-linux-loader-messages-as-debug.patch | 34 - ...t-boot-commands-will-only-return-on-.patch | 97 - 0121-Do-better-in-bootstrap.conf.patch | 28 - 0122-Use-git-to-apply-gnulib-patches.patch | 631 -- ...g-Update-comment-about-running-as-ro.patch | 27 - ...g-Write-new-env-to-tmpfile-and-then-.patch | 152 - ...indeterminate-getting-set-on-boot_su.patch | 81 - 0126-Add-start-symbol-for-RISC-V.patch | 28 - ...conf-Force-autogen.sh-to-use-python3.patch | 33 - ...fw-http-_path-variables-to-make-them.patch | 50 - ...-literal-IPv6-addresses-in-square-br.patch | 114 - ...o-specify-a-port-number-in-addresses.patch | 48 - ...mprove-check-to-detect-literal-IPv6-.patch | 48 - ...debug-message-if-parsing-the-address.patch | 68 - ...so-accept-F8-as-a-user-interrupt-key.patch | 30 - ...se-address-before-jumping-to-the-PE-.patch | 62 - ...ate-TPM-measurement-errors-to-the-ve.patch | 62 - ...maximum-bounce-buffer-size-to-16-MiB.patch | 40 - ...fix-when-the-HTTP-path-is-relative-a.patch | 47 - ...turn-in-efi-export-env-and-efi-load-.patch | 27 - ...p-fix-some-allocation-error-checking.patch | 37 - ...p-fix-some-allocation-error-checking.patch | 39 - ...g.c-fix-some-potential-allocation-ov.patch | 127 - ...integer-overflows-in-grub_cmd_initrd.patch | 49 - ...rnel-validation-without-shim-protoco.patch | 130 - ...ar-pointers-in-grub-core-net-bootp.c.patch | 37 - ...ointers-in-grub-core-net-efi-ip4_con.patch | 38 - ...ointers-in-grub-core-net-efi-ip6_con.patch | 28 - ...-pointers-in-grub-core-net-efi-net.c.patch | 37 - ...-pointers-in-grub-core-net-efi-pxe.c.patch | 46 - ...gration-scripts-to-make-systemctl-re.patch | 190 - ...ion.sh-Also-set-old-menu_show_once-g.patch | 32 - ...set-1-when-keyboard-is-in-Translate-.patch | 121 - ...ll-disable-support-for-EFI-platforms.patch | 120 - ...imestamps-configure-flag-to-prepend-.patch | 112 - ...ements-to-grub_disk_open-and-grub_di.patch | 47 - ...on-grub_debug_is_enabled-void-return.patch | 51 - ...ear-screen-when-debugging-is-enabled.patch | 31 - ..._-instrumentation-new-file-debug-tag.patch | 71 - ...-Avoiding-many-unecessary-open-close.patch | 136 - ...-implements-fibre-channel-discovery-.patch | 90 - ...erpc-enables-device-mapper-discovery.patch | 106 - ...fallback_set-var-to-force-the-set-ma.patch | 245 - ...igning-grub-with-an-appended-signatu.patch | 316 - ...rub-Document-signing-grub-under-UEFI.patch | 61 - ...nt-signing-grub-with-an-appended-sig.patch | 67 - ...e-grub_dl_set_persistent-for-the-emu.patch | 44 - 0166-pgp-factor-out-rsa_pad.patch | 191 - ...rage-for-grub_crypto_pk_-to-crypto.c.patch | 71 - ...p-tweaks-in-preparation-for-libtasn1.patch | 64 - 0169-libtasn1-import-libtasn1-4.16.0.patch | 8934 ----------------- ...asn1-disable-code-not-needed-in-grub.patch | 307 - ...tasn1-changes-for-grub-compatibility.patch | 202 - 0172-libtasn1-compile-into-asn1-module.patch | 70 - 0173-test_asn1-test-module-for-libtasn1.patch | 1457 --- ...-support-embedding-x509-certificates.patch | 252 - ...res-import-GNUTLS-s-ASN.1-descriptio.patch | 639 -- ...res-parse-PKCS-7-signedData-and-X.50.patch | 1528 --- ...res-support-verifying-appended-signa.patch | 716 -- ...pended-signatures-verification-tests.patch | 897 -- 0179-appended-signatures-documentation.patch | 341 - ...er-lockdown-based-on-ibm-secure-boot.patch | 109 - ...275-drop-HEAP_MAX_ADDR-HEAP_MIN_SIZE.patch | 75 - 0182-ieee1275-claim-more-memory.patch | 252 - ...-memory-with-ibm-client-architecture.patch | 268 - ...-Also-handle-the-Extended-Key-Usage-.patch | 315 - ...eee1275-ofdisk-retry-on-open-failure.patch | 103 - ...ainloading-EFI-apps-from-loop-mounts.patch | 138 - 0187-efinet-Add-DHCP-proxy-support.patch | 53 - ...gnore-checksum-seed-incompat-feature.patch | 54 - ...-cmdline-when-generating-legacy-menu.patch | 36 - 0190-Suppress-gettext-error-message.patch | 33 - ...for-EFI-at-runtime-instead-of-config.patch | 63 - ...or-if-boot-to-firmware-setup-is-not-.patch | 92 - ...x-EFI-loader-kernel-image-allocation.patch | 218 - ...over-the-device-to-read-the-config-f.patch | 123 - ...etting-of-prefix-for-signed-binary-c.patch | 88 - ...adable-filesystem-with-v4-superblock.patch | 118 - ...module-name-on-license-check-failure.patch | 48 - ...pc-ieee1275-load-grub-at-4MB-not-2MB.patch | 106 - ...-mkconfig-restore-umask-for-grub.cfg.patch | 40 - ...btrfs-Use-full-btrfs-bootloader-area.patch | 160 - ...prereqs-for-declaration-of-strchrnul.patch | 42 - 1000-port-Add-LoongArch-support.patch | 3574 ------- ...-the-location-where-initrd-is-loaded.patch | 82 - ...ongarch-Add-EFI-frame-buffer-support.patch | 337 - ...garch-Add-support-for-v4.0-interface.patch | 434 - ...support-for-new-EFI-screen-info-GUID.patch | 62 - ...-initrd-load-address-64KiB-alignment.patch | 26 - ...ment-cache-synchronization-operation.patch | 30 - ...rch-Fix-the-initrd-parameter-passing.patch | 276 - ...garch-Disable-relaxation-relocations.patch | 64 - ...ate-kernel-in-EFI_RUNTIME_SERVICES_C.patch | 85 - add-TPCM-support-with-ipmi-channel.patch | 773 -- ...-Wsign-compare-in-rijndael-do_setkey.patch | 43 - ...fs-Fix-an-OOB-write-when-parsing-the.patch | 96 - ...-OOB-read-when-reading-data-from-the.patch | 61 - ...nel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch | 88 - backport-Fix-partmap_test-for-arm-efi.patch | 35 - ...RISC-V-Handle-R_RISCV_CALL_PLT-reloc.patch | 56 - ...t-grub.d-.cfg-after-etc-default-grub.patch | 213 - ...-iee1275-datetime-Fix-off-by-1-error.patch | 46 - ...mmands-acpi-Use-xsdt_addr-if-present.patch | 38 - ...ot-Add-API-to-pass-context-to-loader.patch | 161 - ...i-efifwsetup-Add-missing-grub_free-s.patch | 56 - ...ing-iteration-when-no-floppy-is-used.patch | 37 - ...port-correct-closing-of-SNP-protocol.patch | 112 - ...kfilter-Check-calloc-result-for-NULL.patch | 37 - ...Don-t-make-a-RAID-array-with-more-th.patch | 45 - ...k-Pass-buffers-with-higher-alignment.patch | 71 - backport-disk-ldm-Fix-resource-leak.patch | 38 - backport-double-grub-x86_64-efi-mm-pool.patch | 44 - backport-enable-http-and-https-boot.patch | 92 - backport-fbutil-Fix-integer-overflow.patch | 85 - ...fix-misspelled-variable-BUILD_LDFAGS.patch | 30 - ...-dereference-when-paring-ICMP6_ROUTE.patch | 26 - ...l_font-to-glyphs-in-ascii_font_glyph.patch | 36 - ...nt-Assign-null_font-to-unknown_glyph.patch | 33 - ...of-grub_malloc-in-ascii_glyph_lookup.patch | 40 - ...ix-an-integer-underflow-in-blit_comb.patch | 91 - ...nt-Fix-integer-overflow-in-BMP-index.patch | 65 - ...nteger-overflow-in-ensure_comb_space.patch | 48 - ...-underflow-in-binary-search-of-char-.patch | 86 - ...-integer-overflows-in-grub_font_cons.patch | 81 - ...erflow-in-grub_font_get_glyph_intern.patch | 113 - ..._font_blit_glyph-and-grub_font_blit_.patch | 75 - ...ve-max_char_width-or-max_char_height.patch | 36 - ...hs-exceeds-font-max_glyph_width-or-f.patch | 33 - ...port-font-Remove-grub_font_dup_glyph.patch | 42 - backport-fs-affs-Fix-resource-leaks.patch | 65 - ...rt-fs-fat-Dont-error-when-mtime-is-0.patch | 69 - ...0-Add-check-to-prevent-infinite-loop.patch | 65 - ...void-reading-past-the-entry-boundary.patch | 54 - ...emory-leaks-in-grub_iso9660_susp_ite.patch | 48 - ...0-Incorrect-check-for-entry-boundary.patch | 53 - ...read-past-the-end-of-system-use-area.patch | 95 - ...-or-ST-at-start-of-continuation-area.patch | 73 - ...OOB-read-when-parsing-a-volume-label.patch | 64 - ...OB-read-when-parsing-bitmaps-for-ind.patch | 54 - ...OB-read-when-parsing-directory-entri.patch | 76 - ...port-fs-ntfs-Make-code-more-readable.patch | 162 - ...emory-leaks-in-grub_squash_iterate_d.patch | 67 - ...port-fs-udf-Fix-out-of-bounds-access.patch | 119 - ...s-xfs-Fix-memory-leaks-in-XFS-module.patch | 53 - ...Remove-interp-section-from-img-files.patch | 35 - ...-arm64-linux.c-do-not-validate-kerne.patch | 58 - ...-efi-chainloader.c-do-not-validate-c.patch | 80 - ...-efi-linux.c-drop-now-unused-grub_li.patch | 83 - ...-i386-efi-linux.c-do-not-validate-ke.patch | 73 - ...uninitialized-variable-in-huft_build.patch | 35 - ...-NULL-when-closing-devices-and-disks.patch | 50 - ...t-kern-acpi-Use-xsdt_addr-if-present.patch | 50 - ...le-NULL-input-pointer-in-grub_buffer.patch | 42 - ...e-after-free-in-finish-boot-services.patch | 47 - ...b-Enforce-verification-of-font-files.patch | 54 - ...ct-non-kernel-files-in-the-shim_lock.patch | 105 - ...-Do-not-leak-device_name-on-error-in.patch | 43 - ...Fix-error-handling-in-grub_file_open.patch | 41 - ...-overflow-in-i386-pc-mode-with-large.patch | 37 - ...e-grub_fs_probe-should-dprint-errors.patch | 49 - ...arser-allocated-memory-is-not-leaked.patch | 66 - ...write-when-initializing-lo-freebytes.patch | 38 - ...e-local-relocator-subchunk-struct-to.patch | 40 - ...ux-Remove-magic-number-header-field-.patch | 45 - ...hainloader-Simplify-the-loader-state.patch | 336 - ...i-chainloader-Use-grub_loader_set_ex.patch | 155 - ...loader-grub_load_and_start_image-doe.patch | 72 - ...linux-Avoid-a-use-after-free-in-the-.patch | 44 - ...linux-Fix-a-memory-leak-in-the-initr.patch | 79 - ...386-efi-linux-Use-grub_loader_set_ex.patch | 299 - ...ux-Fix-uninitialized-scalar-variable.patch | 40 - ...ure-the-newc-pathname-is-NULL-termin.patch | 157 - ...ader-multiboot_elfxx-Fix-memory-leak.patch | 94 - ...-grub_strncasecmp-to-drop-sign-when-.patch | 37 - ...grub_min-and-grub_max-more-resilient.patch | 86 - ...-calling-grub_vprintf-in-grub_printf.patch | 59 - ...against-nb-tail-in-grub_netbuff_pull.patch | 64 - ...rp-Fix-uninitialized-scalar-variable.patch | 42 - ...net-bootp-Fix-unchecked-return-value.patch | 37 - ...tp-Fix-uninitialized-scalar-variable.patch | 38 - ...Dont-read-past-the-end-of-the-string.patch | 75 - ...double-free-addresses-on-corrupt-DNS.patch | 61 - ...ookup-error-when-no-IPv6-is-returned.patch | 102 - ...rt-net-dns-Fix-removal-of-DNS-server.patch | 49 - ...error-handling-of-recv_hook-function.patch | 141 - ...-not-tear-down-socket-if-its-already.patch | 46 - ...or-out-on-headers-with-LF-without-CR.patch | 53 - ...Fix-OOB-write-for-split-http-headers.patch | 51 - ...t-net-ip-Do-IP-fragment-maths-safely.patch | 57 - ...et-Fix-uninitialized-scalar-variable.patch | 38 - ...ff-Block-overly-large-netbuff-allocs.patch | 58 - backport-net-tftp-Avoid-a-trivial-UAF.patch | 40 - ...p-Prevent-a-UAF-and-double-free-from.patch | 117 - ...ix-an-integer-overflow-in-grub_unico.patch | 55 - ...t-Fix-array-out-of-bounds-formatting.patch | 39 - ...e-Fix-two-related-integer-underflows.patch | 83 - ...inux-Fix-md-array-device-enumeration.patch | 91 - ...odify-sector-by-sysfs-as-disk-sector.patch | 75 - ..._text-Prevent-out-of-bounds-writes-t.patch | 36 - ...port-tests-Disable-blkid-cache-usage.patch | 34 - ...fstest-Fix-resource-leaks-in-cmd_cmp.patch | 45 - ...l-common-Fix-memory-leak-in-copy_all.patch | 38 - ...l-grub-install-common-Fix-the-key-of.patch | 43 - ...nt-Fix-memory-leak-in-write_font_pf2.patch | 35 - ...-util-grub-mkfont-Fix-resource-leaks.patch | 45 - ...rescue-Fix-memory-leak-in-write_part.patch | 34 - ...ount-Fix-memory-leak-in-fuse_getattr.patch | 29 - ...he-end-of-the-array-in-read_dep_list.patch | 38 - ...d-artificial-limit-to-image-dimensio.patch | 109 - ...-readers-jpeg-Abort-sooner-if-a-read.patch | 260 - ...eg-Block-int-underflow-wild-pointer-.patch | 79 - ...aders-jpeg-Do-not-reallocate-a-given.patch | 34 - ...aders-jpeg-Refuse-to-handle-multiple.patch | 48 - ...o-readers-png-Abort-sooner-if-a-read.patch | 203 - ...g-Avoid-heap-OOB-R-W-inserting-huff-.patch | 44 - ...g-Drop-greyscale-support-to-fix-heap.patch | 174 - ...use-to-handle-multiple-image-headers.patch | 33 - ...-png-Sanity-check-some-huffman-codes.patch | 45 - disable-some-unsupported-filesystems.patch | 53 - ...ompressed-kernel-verification-failed.patch | 29 - ...upmode-not-available-in-some-machine.patch | 48 - grub-2.06.tar.xz => grub-2.12.tar.xz | Bin 6581924 -> 6675608 bytes grub.patches | 345 - ...rd-prompts-to-enter-the-current-pass.patch | 313 - grub2.spec | 12 +- ...08_fallback_counting.in-apply-grubby.patch | 61 - ...-of-unsupported-filesystems-in-fs.ls.patch | 31 - ...rification-when-not-loading-grub.cfg.patch | 29 - support-TPM2.0.patch | 97 - use-default-timestamp.patch | 57 - 348 files changed, 9 insertions(+), 68612 deletions(-) delete mode 100644 0001-Revert-templates-Fix-user-facing-typo-with-an-incorr.patch delete mode 100644 0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch delete mode 100644 0003-Revert-templates-Disable-the-os-prober-by-default.patch delete mode 100644 0004-Add-support-for-Linux-EFI-stub-loading.patch delete mode 100644 0005-Rework-linux-command.patch delete mode 100644 0006-Rework-linux16-command.patch delete mode 100644 0007-Add-secureboot-support-on-efi-chainloader.patch delete mode 100644 0008-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch delete mode 100644 0009-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch delete mode 100644 0010-re-write-.gitignore.patch delete mode 100644 0011-IBM-client-architecture-CAS-reboot-support.patch delete mode 100644 0012-for-ppc-reset-console-display-attr-when-clear-screen.patch delete mode 100644 0013-Disable-GRUB-video-support-for-IBM-power-machines.patch delete mode 100644 0014-Move-bash-completion-script-922997.patch delete mode 100644 0015-Allow-fallback-to-include-entries-by-title-not-just-.patch delete mode 100644 0016-Make-exit-take-a-return-code.patch delete mode 100644 0017-Make-efi-machines-load-an-env-block-from-a-variable.patch delete mode 100644 0018-Migrate-PPC-from-Yaboot-to-Grub2.patch delete mode 100644 0019-Add-fw_path-variable-revised.patch delete mode 100644 0020-Pass-x-hex-hex-straight-through-unmolested.patch delete mode 100644 0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch delete mode 100644 0022-Add-devicetree-loading.patch delete mode 100644 0023-Enable-pager-by-default.-985860.patch delete mode 100644 0024-Don-t-say-GNU-Linux-in-generated-menus.patch delete mode 100644 0025-Add-.eh_frame-to-list-of-relocations-stripped.patch delete mode 100644 0026-Don-t-require-a-password-to-boot-entries-generated-b.patch delete mode 100644 0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch delete mode 100644 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch delete mode 100644 0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch delete mode 100644 0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch delete mode 100644 0031-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch delete mode 100644 0032-Try-prefix-if-fw_path-doesn-t-work.patch delete mode 100644 0033-Use-rpm-s-sort-for-grub2-mkconfig.patch delete mode 100644 0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch delete mode 100644 0035-Add-friendly-grub2-password-config-tool-985962.patch delete mode 100644 0036-tcp-add-window-scaling-support.patch delete mode 100644 0037-efinet-and-bootp-add-support-for-dhcpv6.patch delete mode 100644 0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch delete mode 100644 0039-bz1374141-fix-incorrect-mask-for-ppc64.patch delete mode 100644 0040-Make-grub_fatal-also-backtrace.patch delete mode 100644 0041-Fix-up-some-man-pages-rpmdiff-noticed.patch delete mode 100644 0042-Make-our-info-pages-say-grub2-where-appropriate.patch delete mode 100644 0043-macos-just-build-chainloader-entries-don-t-try-any-x.patch delete mode 100644 0044-grub2-btrfs-Add-ability-to-boot-from-subvolumes.patch delete mode 100644 0045-export-btrfs_subvol-and-btrfs_subvolid.patch delete mode 100644 0046-grub2-btrfs-03-follow_default.patch delete mode 100644 0047-grub2-btrfs-04-grub2-install.patch delete mode 100644 0048-grub2-btrfs-05-grub2-mkconfig.patch delete mode 100644 0049-grub2-btrfs-06-subvol-mount.patch delete mode 100644 0050-Fallback-to-old-subvol-name-scheme-to-support-old-sn.patch delete mode 100644 0051-Grub-not-working-correctly-with-btrfs-snapshots-bsc-.patch delete mode 100644 0052-Add-grub_efi_allocate_pool-and-grub_efi_free_pool-wr.patch delete mode 100644 0053-Use-grub_efi_.-memory-helpers-where-reasonable.patch delete mode 100644 0054-Add-PRIxGRUB_EFI_STATUS-and-use-it.patch delete mode 100644 0055-don-t-use-int-for-efi-status.patch delete mode 100644 0056-make-GRUB_MOD_INIT-declare-its-function-prototypes.patch delete mode 100644 0057-Don-t-guess-boot-efi-as-HFS-on-ppc-machines-in-grub-.patch delete mode 100644 0058-20_linux_xen-load-xen-or-multiboot-2-modules-as-need.patch delete mode 100644 0059-Make-pmtimer-tsc-calibration-not-take-51-seconds-to-.patch delete mode 100644 0060-align-struct-efi_variable-better.patch delete mode 100644 0061-Add-BLS-support-to-grub-mkconfig.patch delete mode 100644 0062-Don-t-attempt-to-backtrace-on-grub_abort-for-grub-em.patch delete mode 100644 0063-Add-linux-and-initrd-commands-for-grub-emu.patch delete mode 100644 0064-Add-grub2-switch-to-blscfg.patch delete mode 100644 0065-make-better-backtraces.patch delete mode 100644 0066-normal-don-t-draw-our-startup-message-if-debug-is-se.patch delete mode 100644 0067-Work-around-some-minor-include-path-weirdnesses.patch delete mode 100644 0068-Make-it-possible-to-enabled-build-id-sha1.patch delete mode 100644 0069-Add-grub_qdprintf-grub_dprintf-without-the-file-line.patch delete mode 100644 0070-Make-a-gdb-dprintf-that-tells-us-load-addresses.patch delete mode 100644 0071-Fixup-for-newer-compiler.patch delete mode 100644 0072-Don-t-attempt-to-export-the-start-and-_start-symbols.patch delete mode 100644 0073-Fixup-for-newer-compiler.patch delete mode 100644 0074-Add-support-for-non-Ethernet-network-cards.patch delete mode 100644 0075-net-read-bracketed-ipv6-addrs-and-port-numbers.patch delete mode 100644 0076-bootp-New-net_bootp6-command.patch delete mode 100644 0077-efinet-UEFI-IPv6-PXE-support.patch delete mode 100644 0078-grub.texi-Add-net_bootp6-doument.patch delete mode 100644 0079-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch delete mode 100644 0080-efinet-Setting-network-from-UEFI-device-path.patch delete mode 100644 0081-efinet-Setting-DNS-server-from-UEFI-protocol.patch delete mode 100644 0082-Support-UEFI-networking-protocols.patch delete mode 100644 0083-AUDIT-0-http-boot-tracker-bug.patch delete mode 100644 0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch delete mode 100644 0085-Add-auto-hide-menu-support.patch delete mode 100644 0086-Add-grub-set-bootflag-utility.patch delete mode 100644 0087-docs-Add-grub-boot-indeterminate.service-example.patch delete mode 100644 0088-gentpl-add-disable-support.patch delete mode 100644 0089-gentpl-add-pc-firmware-type.patch delete mode 100644 0090-efinet-also-use-the-firmware-acceleration-for-http.patch delete mode 100644 0091-efi-http-Make-root_url-reflect-the-protocol-hostname.patch delete mode 100644 0092-Make-it-so-we-can-tell-configure-which-cflags-utils-.patch delete mode 100644 0093-module-verifier-make-it-possible-to-run-checkers-on-.patch delete mode 100644 0094-Rework-how-the-fdt-command-builds.patch delete mode 100644 0095-Disable-non-wordsize-allocations-on-arm.patch delete mode 100644 0096-Prepend-prefix-when-HTTP-path-is-relative.patch delete mode 100644 0097-Make-grub_error-more-verbose.patch delete mode 100644 0098-Make-reset-an-alias-for-the-reboot-command.patch delete mode 100644 0099-Add-a-version-command.patch delete mode 100644 0100-Add-more-dprintf-and-nerf-dprintf-in-script.c.patch delete mode 100644 0101-arm-arm64-loader-Better-memory-allocation-and-error-.patch delete mode 100644 0102-Try-to-pick-better-locations-for-kernel-and-initrd.patch delete mode 100644 0103-Attempt-to-fix-up-all-the-places-Wsign-compare-error.patch delete mode 100644 0104-Don-t-use-Wno-sign-compare-Wno-conversion-Wno-error-.patch delete mode 100644 0105-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch delete mode 100644 0106-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch delete mode 100644 0107-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch delete mode 100644 0108-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch delete mode 100644 0109-Fix-getroot.c-s-trampolines.patch delete mode 100644 0110-Do-not-allow-stack-trampolines-anywhere.patch delete mode 100644 0111-Reimplement-boot_counter.patch delete mode 100644 0112-Fix-menu-entry-selection-based-on-ID-and-title.patch delete mode 100644 0113-Make-the-menu-entry-users-option-argument-to-be-opti.patch delete mode 100644 0114-Add-efi-export-env-and-efi-load-env-commands.patch delete mode 100644 0115-Make-it-possible-to-subtract-conditions-from-debug.patch delete mode 100644 0116-Export-all-variables-from-the-initial-context-when-c.patch delete mode 100644 0117-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch delete mode 100644 0118-Fix-systemctl-kexec-exit-status-check.patch delete mode 100644 0119-Print-grub-emu-linux-loader-messages-as-debug.patch delete mode 100644 0120-Don-t-assume-that-boot-commands-will-only-return-on-.patch delete mode 100644 0121-Do-better-in-bootstrap.conf.patch delete mode 100644 0122-Use-git-to-apply-gnulib-patches.patch delete mode 100644 0123-grub-set-bootflag-Update-comment-about-running-as-ro.patch delete mode 100644 0124-grub-set-bootflag-Write-new-env-to-tmpfile-and-then-.patch delete mode 100644 0125-grub.d-Fix-boot_indeterminate-getting-set-on-boot_su.patch delete mode 100644 0126-Add-start-symbol-for-RISC-V.patch delete mode 100644 0127-bootstrap.conf-Force-autogen.sh-to-use-python3.patch delete mode 100644 0128-efi-http-Export-fw-http-_path-variables-to-make-them.patch delete mode 100644 0129-efi-http-Enclose-literal-IPv6-addresses-in-square-br.patch delete mode 100644 0130-efi-net-Allow-to-specify-a-port-number-in-addresses.patch delete mode 100644 0131-efi-ip4_config-Improve-check-to-detect-literal-IPv6-.patch delete mode 100644 0132-efi-net-Print-a-debug-message-if-parsing-the-address.patch delete mode 100644 0133-kern-term-Also-accept-F8-as-a-user-interrupt-key.patch delete mode 100644 0134-efi-Set-image-base-address-before-jumping-to-the-PE-.patch delete mode 100644 0135-tpm-Don-t-propagate-TPM-measurement-errors-to-the-ve.patch delete mode 100644 0136-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch delete mode 100644 0137-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch delete mode 100644 0138-Fix-a-missing-return-in-efi-export-env-and-efi-load-.patch delete mode 100644 0139-efi-dhcp-fix-some-allocation-error-checking.patch delete mode 100644 0140-efi-http-fix-some-allocation-error-checking.patch delete mode 100644 0141-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch delete mode 100644 0142-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch delete mode 100644 0143-linuxefi-fail-kernel-validation-without-shim-protoco.patch delete mode 100644 0144-Fix-const-char-pointers-in-grub-core-net-bootp.c.patch delete mode 100644 0145-Fix-const-char-pointers-in-grub-core-net-efi-ip4_con.patch delete mode 100644 0146-Fix-const-char-pointers-in-grub-core-net-efi-ip6_con.patch delete mode 100644 0147-Fix-const-char-pointers-in-grub-core-net-efi-net.c.patch delete mode 100644 0148-Fix-const-char-pointers-in-grub-core-net-efi-pxe.c.patch delete mode 100644 0149-Add-systemd-integration-scripts-to-make-systemctl-re.patch delete mode 100644 0150-systemd-integration.sh-Also-set-old-menu_show_once-g.patch delete mode 100644 0151-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch delete mode 100644 0152-grub-install-disable-support-for-EFI-platforms.patch delete mode 100644 0153-New-with-debug-timestamps-configure-flag-to-prepend-.patch delete mode 100644 0154-Added-debug-statements-to-grub_disk_open-and-grub_di.patch delete mode 100644 0155-Introduce-function-grub_debug_is_enabled-void-return.patch delete mode 100644 0156-Don-t-clear-screen-when-debugging-is-enabled.patch delete mode 100644 0157-grub_file_-instrumentation-new-file-debug-tag.patch delete mode 100644 0158-ieee1275-Avoiding-many-unecessary-open-close.patch delete mode 100644 0159-ieee1275-powerpc-implements-fibre-channel-discovery-.patch delete mode 100644 0160-ieee1275-powerpc-enables-device-mapper-discovery.patch delete mode 100644 0161-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch delete mode 100644 0162-Add-suport-for-signing-grub-with-an-appended-signatu.patch delete mode 100644 0163-docs-grub-Document-signing-grub-under-UEFI.patch delete mode 100644 0164-docs-grub-Document-signing-grub-with-an-appended-sig.patch delete mode 100644 0165-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch delete mode 100644 0166-pgp-factor-out-rsa_pad.patch delete mode 100644 0167-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch delete mode 100644 0168-posix_wrap-tweaks-in-preparation-for-libtasn1.patch delete mode 100644 0169-libtasn1-import-libtasn1-4.16.0.patch delete mode 100644 0170-libtasn1-disable-code-not-needed-in-grub.patch delete mode 100644 0171-libtasn1-changes-for-grub-compatibility.patch delete mode 100644 0172-libtasn1-compile-into-asn1-module.patch delete mode 100644 0173-test_asn1-test-module-for-libtasn1.patch delete mode 100644 0174-grub-install-support-embedding-x509-certificates.patch delete mode 100644 0175-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch delete mode 100644 0176-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch delete mode 100644 0177-appended-signatures-support-verifying-appended-signa.patch delete mode 100644 0178-appended-signatures-verification-tests.patch delete mode 100644 0179-appended-signatures-documentation.patch delete mode 100644 0180-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch delete mode 100644 0181-ieee1275-drop-HEAP_MAX_ADDR-HEAP_MIN_SIZE.patch delete mode 100644 0182-ieee1275-claim-more-memory.patch delete mode 100644 0183-ieee1275-request-memory-with-ibm-client-architecture.patch delete mode 100644 0184-appendedsig-x509-Also-handle-the-Extended-Key-Usage-.patch delete mode 100644 0185-ieee1275-ofdisk-retry-on-open-failure.patch delete mode 100644 0186-Allow-chainloading-EFI-apps-from-loop-mounts.patch delete mode 100644 0187-efinet-Add-DHCP-proxy-support.patch delete mode 100644 0188-fs-ext2-Ignore-checksum-seed-incompat-feature.patch delete mode 100644 0189-Don-t-update-the-cmdline-when-generating-legacy-menu.patch delete mode 100644 0190-Suppress-gettext-error-message.patch delete mode 100644 0192-templates-Check-for-EFI-at-runtime-instead-of-config.patch delete mode 100644 0193-efi-Print-an-error-if-boot-to-firmware-setup-is-not-.patch delete mode 100644 0194-arm64-Fix-EFI-loader-kernel-image-allocation.patch delete mode 100644 0195-normal-main-Discover-the-device-to-read-the-config-f.patch delete mode 100644 0196-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch delete mode 100644 0197-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch delete mode 100644 0198-Print-module-name-on-license-check-failure.patch delete mode 100644 0199-powerpc-ieee1275-load-grub-at-4MB-not-2MB.patch delete mode 100644 0200-grub-mkconfig-restore-umask-for-grub.cfg.patch delete mode 100644 0201-fs-btrfs-Use-full-btrfs-bootloader-area.patch delete mode 100644 0202-rpm-sort-add-prereqs-for-declaration-of-strchrnul.patch delete mode 100644 1000-port-Add-LoongArch-support.patch delete mode 100644 1001-loongarch-Modify-the-location-where-initrd-is-loaded.patch delete mode 100644 1002-loongarch-Add-EFI-frame-buffer-support.patch delete mode 100644 1003-loongarch-Add-support-for-v4.0-interface.patch delete mode 100644 1004-loongarch-Add-support-for-new-EFI-screen-info-GUID.patch delete mode 100644 1005-loongarch-Force-initrd-load-address-64KiB-alignment.patch delete mode 100644 1006-loongarch-Implement-cache-synchronization-operation.patch delete mode 100644 1007-loongarch-Fix-the-initrd-parameter-passing.patch delete mode 100644 1008-loongarch-Disable-relaxation-relocations.patch delete mode 100644 Revert-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_C.patch delete mode 100644 add-TPCM-support-with-ipmi-channel.patch delete mode 100644 backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch delete mode 100644 backport-CVE-2023-4692-fs-ntfs-Fix-an-OOB-write-when-parsing-the.patch delete mode 100644 backport-CVE-2023-4693-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the.patch delete mode 100644 backport-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch delete mode 100644 backport-Fix-partmap_test-for-arm-efi.patch delete mode 100644 backport-RISC-V-Handle-R_RISCV_CALL_PLT-reloc.patch delete mode 100644 backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch delete mode 100644 backport-Revert-iee1275-datetime-Fix-off-by-1-error.patch delete mode 100644 backport-commands-acpi-Use-xsdt_addr-if-present.patch delete mode 100644 backport-commands-boot-Add-API-to-pass-context-to-loader.patch delete mode 100644 backport-commands-efi-efifwsetup-Add-missing-grub_free-s.patch delete mode 100644 backport-commands-search-Fix-bug-stopping-iteration-when-no-floppy-is-used.patch delete mode 100644 backport-correct-closing-of-SNP-protocol.patch delete mode 100644 backport-disk-diskfilter-Check-calloc-result-for-NULL.patch delete mode 100644 backport-disk-diskfilter-Don-t-make-a-RAID-array-with-more-th.patch delete mode 100644 backport-disk-efi-efidisk-Pass-buffers-with-higher-alignment.patch delete mode 100644 backport-disk-ldm-Fix-resource-leak.patch delete mode 100644 backport-double-grub-x86_64-efi-mm-pool.patch delete mode 100644 backport-enable-http-and-https-boot.patch delete mode 100644 backport-fbutil-Fix-integer-overflow.patch delete mode 100644 backport-fix-misspelled-variable-BUILD_LDFAGS.patch delete mode 100644 backport-fix-null-pointer-dereference-when-paring-ICMP6_ROUTE.patch delete mode 100644 backport-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch delete mode 100644 backport-font-Assign-null_font-to-unknown_glyph.patch delete mode 100644 backport-font-Check-return-value-of-grub_malloc-in-ascii_glyph_lookup.patch delete mode 100644 backport-font-Fix-an-integer-underflow-in-blit_comb.patch delete mode 100644 backport-font-Fix-integer-overflow-in-BMP-index.patch delete mode 100644 backport-font-Fix-integer-overflow-in-ensure_comb_space.patch delete mode 100644 backport-font-Fix-integer-underflow-in-binary-search-of-char-.patch delete mode 100644 backport-font-Fix-several-integer-overflows-in-grub_font_cons.patch delete mode 100644 backport-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch delete mode 100644 backport-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch delete mode 100644 backport-font-Reject-fonts-with-negative-max_char_width-or-max_char_height.patch delete mode 100644 backport-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch delete mode 100644 backport-font-Remove-grub_font_dup_glyph.patch delete mode 100644 backport-fs-affs-Fix-resource-leaks.patch delete mode 100644 backport-fs-fat-Dont-error-when-mtime-is-0.patch delete mode 100644 backport-fs-iso9660-Add-check-to-prevent-infinite-loop.patch delete mode 100644 backport-fs-iso9660-Avoid-reading-past-the-entry-boundary.patch delete mode 100644 backport-fs-iso9660-Fix-memory-leaks-in-grub_iso9660_susp_ite.patch delete mode 100644 backport-fs-iso9660-Incorrect-check-for-entry-boundary.patch delete mode 100644 backport-fs-iso9660-Prevent-read-past-the-end-of-system-use-area.patch delete mode 100644 backport-fs-iso9660-Prevent-skipping-CE-or-ST-at-start-of-continuation-area.patch delete mode 100644 backport-fs-ntfs-Fix-an-OOB-read-when-parsing-a-volume-label.patch delete mode 100644 backport-fs-ntfs-Fix-an-OOB-read-when-parsing-bitmaps-for-ind.patch delete mode 100644 backport-fs-ntfs-Fix-an-OOB-read-when-parsing-directory-entri.patch delete mode 100644 backport-fs-ntfs-Make-code-more-readable.patch delete mode 100644 backport-fs-squash4-Fix-memory-leaks-in-grub_squash_iterate_d.patch delete mode 100644 backport-fs-udf-Fix-out-of-bounds-access.patch delete mode 100644 backport-fs-xfs-Fix-memory-leaks-in-XFS-module.patch delete mode 100644 backport-gentpl_py-Remove-interp-section-from-img-files.patch delete mode 100644 backport-grub-core-loader-arm64-linux.c-do-not-validate-kerne.patch delete mode 100644 backport-grub-core-loader-efi-chainloader.c-do-not-validate-c.patch delete mode 100644 backport-grub-core-loader-efi-linux.c-drop-now-unused-grub_li.patch delete mode 100644 backport-grub-core-loader-i386-efi-linux.c-do-not-validate-ke.patch delete mode 100644 backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch delete mode 100644 backport-kern-Check-for-NULL-when-closing-devices-and-disks.patch delete mode 100644 backport-kern-acpi-Use-xsdt_addr-if-present.patch delete mode 100644 backport-kern-buffer-Handle-NULL-input-pointer-in-grub_buffer.patch delete mode 100644 backport-kern-efi-mm-Fix-use-after-free-in-finish-boot-services.patch delete mode 100644 backport-kern-efi-sb-Enforce-verification-of-font-files.patch delete mode 100644 backport-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch delete mode 100644 backport-kern-file-Do-not-leak-device_name-on-error-in.patch delete mode 100644 backport-kern-file-Fix-error-handling-in-grub_file_open.patch delete mode 100644 backport-kern-fs-Fix-possible-integer-overflow-in-i386-pc-mode-with-large.patch delete mode 100644 backport-kern-fs-The-grub_fs_probe-should-dprint-errors.patch delete mode 100644 backport-kern-rescue_parser-Ensure-that-parser-allocated-memory-is-not-leaked.patch delete mode 100644 backport-lib-relocator-Fix-OOB-write-when-initializing-lo-freebytes.patch delete mode 100644 backport-lib-relocator-Initialize-local-relocator-subchunk-struct-to.patch delete mode 100644 backport-loader-arm64-linux-Remove-magic-number-header-field-.patch delete mode 100644 backport-loader-efi-chainloader-Simplify-the-loader-state.patch delete mode 100644 backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch delete mode 100644 backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch delete mode 100644 backport-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch delete mode 100644 backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch delete mode 100644 backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch delete mode 100644 backport-loader-i386-pc-linux-Fix-uninitialized-scalar-variable.patch delete mode 100644 backport-loader-linux-Ensure-the-newc-pathname-is-NULL-termin.patch delete mode 100644 backport-loader-multiboot_elfxx-Fix-memory-leak.patch delete mode 100644 backport-misc-Add-cast-in-grub_strncasecmp-to-drop-sign-when-.patch delete mode 100644 backport-misc-Make-grub_min-and-grub_max-more-resilient.patch delete mode 100644 backport-mm-Temporarily-disable-grub_mm_debug-while-calling-grub_vprintf-in-grub_printf.patch delete mode 100644 backport-net-Check-against-nb-tail-in-grub_netbuff_pull.patch delete mode 100644 backport-net-arp-Fix-uninitialized-scalar-variable.patch delete mode 100644 backport-net-bootp-Fix-unchecked-return-value.patch delete mode 100644 backport-net-bootp-Fix-uninitialized-scalar-variable.patch delete mode 100644 backport-net-dns-Dont-read-past-the-end-of-the-string.patch delete mode 100644 backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch delete mode 100644 backport-net-dns-Fix-lookup-error-when-no-IPv6-is-returned.patch delete mode 100644 backport-net-dns-Fix-removal-of-DNS-server.patch delete mode 100644 backport-net-dns-Simplify-error-handling-of-recv_hook-function.patch delete mode 100644 backport-net-http-Do-not-tear-down-socket-if-its-already.patch delete mode 100644 backport-net-http-Error-out-on-headers-with-LF-without-CR.patch delete mode 100644 backport-net-http-Fix-OOB-write-for-split-http-headers.patch delete mode 100644 backport-net-ip-Do-IP-fragment-maths-safely.patch delete mode 100644 backport-net-net-Fix-uninitialized-scalar-variable.patch delete mode 100644 backport-net-netbuff-Block-overly-large-netbuff-allocs.patch delete mode 100644 backport-net-tftp-Avoid-a-trivial-UAF.patch delete mode 100644 backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch delete mode 100644 backport-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch delete mode 100644 backport-normal-charset-Fix-array-out-of-bounds-formatting.patch delete mode 100644 backport-normal-cmdline-Fix-two-related-integer-underflows.patch delete mode 100644 backport-osdep-linux-Fix-md-array-device-enumeration.patch delete mode 100644 backport-osdep-linux-hostdisk-Modify-sector-by-sysfs-as-disk-sector.patch delete mode 100644 backport-term-i386-pc-vga_text-Prevent-out-of-bounds-writes-t.patch delete mode 100644 backport-tests-Disable-blkid-cache-usage.patch delete mode 100644 backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch delete mode 100644 backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch delete mode 100644 backport-util-grub-install-common-Fix-the-key-of.patch delete mode 100644 backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch delete mode 100644 backport-util-grub-mkfont-Fix-resource-leaks.patch delete mode 100644 backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch delete mode 100644 backport-util-grub-mount-Fix-memory-leak-in-fuse_getattr.patch delete mode 100644 backport-util-resolve-Do-not-read-past-the-end-of-the-array-in-read_dep_list.patch delete mode 100644 backport-video-readers-Add-artificial-limit-to-image-dimensio.patch delete mode 100644 backport-video-readers-jpeg-Abort-sooner-if-a-read.patch delete mode 100644 backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch delete mode 100644 backport-video-readers-jpeg-Do-not-reallocate-a-given.patch delete mode 100644 backport-video-readers-jpeg-Refuse-to-handle-multiple.patch delete mode 100644 backport-video-readers-png-Abort-sooner-if-a-read.patch delete mode 100644 backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch delete mode 100644 backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch delete mode 100644 backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch delete mode 100644 backport-video-readers-png-Sanity-check-some-huffman-codes.patch delete mode 100644 disable-some-unsupported-filesystems.patch delete mode 100644 fix-compressed-kernel-verification-failed.patch delete mode 100644 fix-setupmode-not-available-in-some-machine.patch rename grub-2.06.tar.xz => grub-2.12.tar.xz (47%) delete mode 100644 grub2-set-password-prompts-to-enter-the-current-pass.patch delete mode 100644 remove-08_fallback_counting.in-apply-grubby.patch delete mode 100644 remove-the-items-of-unsupported-filesystems-in-fs.ls.patch delete mode 100644 skip-verification-when-not-loading-grub.cfg.patch delete mode 100644 support-TPM2.0.patch delete mode 100644 use-default-timestamp.patch diff --git a/0001-Revert-templates-Fix-user-facing-typo-with-an-incorr.patch b/0001-Revert-templates-Fix-user-facing-typo-with-an-incorr.patch deleted file mode 100644 index fcc7825..0000000 --- a/0001-Revert-templates-Fix-user-facing-typo-with-an-incorr.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Jun 2021 12:10:45 +0200 -Subject: [PATCH] Revert "templates: Fix user-facing typo with an incorrect use - of "it's"" - -This reverts commit 722737630889607c3b5761f1f5a48f1674cd2821. ---- - util/grub.d/30_os-prober.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 5984e92d291..94622481284 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -36,7 +36,7 @@ if ! command -v os-prober > /dev/null || ! command -v linux-boot-prober > /dev/n - exit 0 - fi - --grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIts output will be used to detect bootable binaries on them and create new boot entries.")" -+grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" - - OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" - if [ -z "${OSPROBED}" ] ; then diff --git a/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch b/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch deleted file mode 100644 index 4187765..0000000 --- a/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Jun 2021 12:10:54 +0200 -Subject: [PATCH] Revert "templates: Properly disable the os-prober by default" - -This reverts commit 54e0a1bbf1e9106901a557195bb35e5e20fb3925. ---- - util/grub-mkconfig.in | 5 +---- - util/grub.d/30_os-prober.in | 8 ++++---- - 2 files changed, 5 insertions(+), 8 deletions(-) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index f8cbb8d7a2b..d3e879b8e5c 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -140,9 +140,6 @@ GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2 - GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" - GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true - --# Disable os-prober by default due to security reasons. --GRUB_DISABLE_OS_PROBER="true" -- - # Filesystem for the device containing our userland. Used for stuff like - # choosing Hurd filesystem module. - GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`" -@@ -204,7 +201,6 @@ export GRUB_DEVICE \ - GRUB_DEVICE_PARTUUID \ - GRUB_DEVICE_BOOT \ - GRUB_DEVICE_BOOT_UUID \ -- GRUB_DISABLE_OS_PROBER \ - GRUB_FS \ - GRUB_FONT \ - GRUB_PRELOAD_MODULES \ -@@ -246,6 +242,7 @@ export GRUB_DEFAULT \ - GRUB_BACKGROUND \ - GRUB_THEME \ - GRUB_GFXPAYLOAD_LINUX \ -+ GRUB_DISABLE_OS_PROBER \ - GRUB_INIT_TUNE \ - GRUB_SAVEDEFAULT \ - GRUB_ENABLE_CRYPTODISK \ -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 94622481284..80685b15f4d 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -26,8 +26,8 @@ export TEXTDOMAINDIR="@localedir@" - - . "$pkgdatadir/grub-mkconfig_lib" - --if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then -- grub_warn "$(gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.")" -+if [ "x${GRUB_DISABLE_OS_PROBER}" = "xfalse" ]; then -+ gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.\n" - exit 0 - fi - -@@ -36,12 +36,12 @@ if ! command -v os-prober > /dev/null || ! command -v linux-boot-prober > /dev/n - exit 0 - fi - --grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" -- - OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" - if [ -z "${OSPROBED}" ] ; then - # empty os-prober output, nothing doing - exit 0 -+else -+ grub_warn "$(gettext_printf "os-prober was executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" - fi - - osx_entry() { diff --git a/0003-Revert-templates-Disable-the-os-prober-by-default.patch b/0003-Revert-templates-Disable-the-os-prober-by-default.patch deleted file mode 100644 index 68cacfc..0000000 --- a/0003-Revert-templates-Disable-the-os-prober-by-default.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Jun 2021 12:10:58 +0200 -Subject: [PATCH] Revert "templates: Disable the os-prober by default" - -This reverts commit e346414725a70e5c74ee87ca14e580c66f517666. ---- - docs/grub.texi | 18 ++++++++---------- - util/grub.d/30_os-prober.in | 5 +---- - 2 files changed, 9 insertions(+), 14 deletions(-) - -diff --git a/docs/grub.texi b/docs/grub.texi -index f8b4b3b21a7..69f08d289f9 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -1519,13 +1519,10 @@ boot sequence. If you have problems, set this option to @samp{text} and - GRUB will tell Linux to boot in normal text mode. - - @item GRUB_DISABLE_OS_PROBER --The @command{grub-mkconfig} has a feature to use the external --@command{os-prober} program to discover other operating systems installed on --the same machine and generate appropriate menu entries for them. It is disabled --by default since automatic and silent execution of @command{os-prober}, and --creating boot entries based on that data, is a potential attack vector. Set --this option to @samp{false} to enable this feature in the --@command{grub-mkconfig} command. -+Normally, @command{grub-mkconfig} will try to use the external -+@command{os-prober} program, if installed, to discover other operating -+systems installed on the same system and generate appropriate menu entries -+for them. Set this option to @samp{true} to disable this. - - @item GRUB_OS_PROBER_SKIP_LIST - List of space-separated FS UUIDs of filesystems to be ignored from os-prober -@@ -1853,9 +1850,10 @@ than zero; otherwise 0. - @section Multi-boot manual config - - Currently autogenerating config files for multi-boot environments depends on --os-prober and has several shortcomings. Due to that it is disabled by default. --It is advised to use the power of GRUB syntax and do it yourself. A possible --configuration is detailed here, feel free to adjust to your needs. -+os-prober and has several shortcomings. While fixing it is scheduled for the -+next release, meanwhile you can make use of the power of GRUB syntax and do it -+yourself. A possible configuration is detailed here, feel free to adjust to your -+needs. - - First create a separate GRUB partition, big enough to hold GRUB. Some of the - following entries show how to load OS installer images from this same partition, -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 80685b15f4d..1b91c102f35 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -26,8 +26,7 @@ export TEXTDOMAINDIR="@localedir@" - - . "$pkgdatadir/grub-mkconfig_lib" - --if [ "x${GRUB_DISABLE_OS_PROBER}" = "xfalse" ]; then -- gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.\n" -+if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then - exit 0 - fi - -@@ -40,8 +39,6 @@ OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" - if [ -z "${OSPROBED}" ] ; then - # empty os-prober output, nothing doing - exit 0 --else -- grub_warn "$(gettext_printf "os-prober was executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" - fi - - osx_entry() { diff --git a/0004-Add-support-for-Linux-EFI-stub-loading.patch b/0004-Add-support-for-Linux-EFI-stub-loading.patch deleted file mode 100644 index 73d231a..0000000 --- a/0004-Add-support-for-Linux-EFI-stub-loading.patch +++ /dev/null @@ -1,983 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Tue, 10 Jul 2012 11:58:52 -0400 -Subject: [PATCH] Add support for Linux EFI stub loading. - -Also: - -commit 71c843745f22f81e16d259e2e19c99bf3c1855c1 -Author: Colin Watson -Date: Tue Oct 23 10:40:49 2012 -0400 - -Don't allow insmod when secure boot is enabled. - -Hi, - -Fedora's patch to forbid insmod in UEFI Secure Boot environments is fine -as far as it goes. However, the insmod command is not the only way that -modules can be loaded. In particular, the 'normal' command, which -implements the usual GRUB menu and the fully-featured command prompt, -will implicitly load commands not currently loaded into memory. This -permits trivial Secure Boot violations by writing commands implementing -whatever you want to do and pointing $prefix at the malicious code. - -I'm currently test-building this patch (replacing your current -grub-2.00-no-insmod-on-sb.patch), but this should be more correct. It -moves the check into grub_dl_load_file. ---- - grub-core/Makefile.core.def | 16 +- - grub-core/kern/dl.c | 21 +++ - grub-core/kern/efi/efi.c | 28 ++++ - grub-core/kern/efi/mm.c | 32 ++++ - grub-core/loader/arm64/linux.c | 118 +++++++------- - grub-core/loader/arm64/xen_boot.c | 1 - - grub-core/loader/efi/linux.c | 70 ++++++++ - grub-core/loader/i386/efi/linux.c | 335 ++++++++++++++++++++++++++++++++++++++ - grub-core/loader/i386/pc/linux.c | 10 +- - include/grub/arm/linux.h | 9 + - include/grub/arm64/linux.h | 9 + - include/grub/efi/efi.h | 7 +- - include/grub/efi/linux.h | 31 ++++ - 13 files changed, 618 insertions(+), 69 deletions(-) - create mode 100644 grub-core/loader/efi/linux.c - create mode 100644 grub-core/loader/i386/efi/linux.c - create mode 100644 include/grub/efi/linux.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 8022e1c0a79..45d3edaa4dc 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -1734,13 +1734,6 @@ module = { - enable = i386_pc; - }; - -- --module = { -- name = linux16; -- common = loader/i386/pc/linux.c; -- enable = x86; --}; -- - module = { - name = ntldr; - i386_pc = loader/i386/pc/ntldr.c; -@@ -1796,7 +1789,9 @@ module = { - - module = { - name = linux; -- x86 = loader/i386/linux.c; -+ i386_pc = loader/i386/pc/linux.c; -+ x86_64_efi = loader/i386/efi/linux.c; -+ i386_efi = loader/i386/efi/linux.c; - i386_xen_pvh = loader/i386/linux.c; - xen = loader/i386/xen.c; - i386_pc = lib/i386/pc/vesa_modes_table.c; -@@ -1811,9 +1806,14 @@ module = { - arm64 = loader/arm64/linux.c; - riscv32 = loader/riscv/linux.c; - riscv64 = loader/riscv/linux.c; -+ emu = loader/emu/linux.c; -+ fdt = lib/fdt.c; -+ - common = loader/linux.c; - common = lib/cmdline.c; - enable = noemu; -+ -+ efi = loader/efi/linux.c; - }; - - module = { -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 48f8a79073d..b7149370950 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -38,6 +38,14 @@ - #define GRUB_MODULES_MACHINE_READONLY - #endif - -+#ifdef GRUB_MACHINE_EMU -+#include -+#endif -+ -+#ifdef GRUB_MACHINE_EFI -+#include -+#endif -+ - - - #pragma GCC diagnostic ignored "-Wcast-align" -@@ -695,6 +703,19 @@ grub_dl_load_file (const char *filename) - void *core = 0; - grub_dl_t mod = 0; - -+#ifdef GRUB_MACHINE_EFI -+ if (grub_efi_secure_boot ()) -+ { -+#if 0 -+ /* This is an error, but grub2-mkconfig still generates a pile of -+ * insmod commands, so emitting it would be mostly just obnoxious. */ -+ grub_error (GRUB_ERR_ACCESS_DENIED, -+ "Secure Boot forbids loading module from %s", filename); -+#endif -+ return 0; -+ } -+#endif -+ - grub_boot_time ("Loading module %s", filename); - - file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE); -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 8cff7be0289..35b8f670602 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -286,6 +286,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, - return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL); - } - -+grub_efi_boolean_t -+grub_efi_secure_boot (void) -+{ -+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ grub_size_t datasize; -+ char *secure_boot = NULL; -+ char *setup_mode = NULL; -+ grub_efi_boolean_t ret = 0; -+ -+ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); -+ -+ if (datasize != 1 || !secure_boot) -+ goto out; -+ -+ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); -+ -+ if (datasize != 1 || !setup_mode) -+ goto out; -+ -+ if (*secure_boot && !*setup_mode) -+ ret = 1; -+ -+ out: -+ grub_free (secure_boot); -+ grub_free (setup_mode); -+ return ret; -+} -+ - #pragma GCC diagnostic ignored "-Wcast-align" - - /* Search the mods section from the PE32/PE32+ image. This code uses -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 9838fb2f50d..f6aef0ef649 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -113,6 +113,38 @@ grub_efi_drop_alloc (grub_efi_physical_address_t address, - } - } - -+/* Allocate pages below a specified address */ -+void * -+grub_efi_allocate_pages_max (grub_efi_physical_address_t max, -+ grub_efi_uintn_t pages) -+{ -+ grub_efi_status_t status; -+ grub_efi_boot_services_t *b; -+ grub_efi_physical_address_t address = max; -+ -+ if (max > 0xffffffff) -+ return 0; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ -+ if (address == 0) -+ { -+ /* Uggh, the address 0 was allocated... This is too annoying, -+ so reallocate another one. */ -+ address = max; -+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); -+ grub_efi_free_pages (0, pages); -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ } -+ -+ return (void *) ((grub_addr_t) address); -+} -+ - /* Allocate pages. Return the pointer to the first of allocated pages. */ - void * - grub_efi_allocate_pages_real (grub_efi_physical_address_t address, -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index ef3e9f9444c..a312c668685 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -41,6 +42,7 @@ static int loaded; - - static void *kernel_addr; - static grub_uint64_t kernel_size; -+static grub_uint32_t handover_offset; - - static char *linux_args; - static grub_uint32_t cmdline_size; -@@ -67,7 +69,8 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) - static grub_err_t - finalize_params_linux (void) - { -- int node, retval; -+ grub_efi_loaded_image_t *loaded_image = NULL; -+ int node, retval, len; - - void *fdt; - -@@ -102,79 +105,70 @@ finalize_params_linux (void) - if (grub_fdt_install() != GRUB_ERR_NONE) - goto failure; - -- return GRUB_ERR_NONE; -- --failure: -- grub_fdt_unload(); -- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); --} -- --grub_err_t --grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) --{ -- grub_efi_memory_mapped_device_path_t *mempath; -- grub_efi_handle_t image_handle; -- grub_efi_boot_services_t *b; -- grub_efi_status_t status; -- grub_efi_loaded_image_t *loaded_image; -- int len; -- -- mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); -- if (!mempath) -- return grub_errno; -- -- mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; -- mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; -- mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); -- mempath[0].memory_type = GRUB_EFI_LOADER_DATA; -- mempath[0].start_address = addr; -- mempath[0].end_address = addr + size; -- -- mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; -- mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -- mempath[1].header.length = sizeof (grub_efi_device_path_t); -- -- b = grub_efi_system_table->boot_services; -- status = b->load_image (0, grub_efi_image_handle, -- (grub_efi_device_path_t *) mempath, -- (void *) addr, size, &image_handle); -- if (status != GRUB_EFI_SUCCESS) -- return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); -- -- grub_dprintf ("linux", "linux command line: '%s'\n", args); -+ grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n", -+ fdt); - - /* Convert command line to UCS-2 */ -- loaded_image = grub_efi_get_loaded_image (image_handle); -+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); -+ if (!loaded_image) -+ goto failure; -+ - loaded_image->load_options_size = len = -- (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); -+ (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t); - loaded_image->load_options = - grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); - if (!loaded_image->load_options) -- return grub_errno; -+ return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters"); - - loaded_image->load_options_size = - 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, -- (grub_uint8_t *) args, len, NULL); -+ (grub_uint8_t *) linux_args, len, NULL); - -- grub_dprintf ("linux", "starting image %p\n", image_handle); -- status = b->start_image (image_handle, 0, NULL); -+ return GRUB_ERR_NONE; - -- /* When successful, not reached */ -- b->unload_image (image_handle); -- grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, -- GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); -+failure: -+ grub_fdt_unload(); -+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+} - -- return grub_errno; -+static void -+free_params (void) -+{ -+ grub_efi_loaded_image_t *loaded_image = NULL; -+ -+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); -+ if (loaded_image) -+ { -+ if (loaded_image->load_options) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_efi_uintn_t)loaded_image->load_options, -+ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); -+ loaded_image->load_options = NULL; -+ loaded_image->load_options_size = 0; -+ } -+} -+ -+grub_err_t -+grub_arch_efi_linux_boot_image (grub_addr_t addr, char *args) -+{ -+ grub_err_t retval; -+ -+ retval = finalize_params_linux (); -+ if (retval != GRUB_ERR_NONE) -+ return grub_errno; -+ -+ grub_dprintf ("linux", "linux command line: '%s'\n", args); -+ -+ retval = grub_efi_linux_boot ((char *)addr, handover_offset, (void *)addr); -+ -+ /* Never reached... */ -+ free_params(); -+ return retval; - } - - static grub_err_t - grub_linux_boot (void) - { -- if (finalize_params_linux () != GRUB_ERR_NONE) -- return grub_errno; -- -- return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr, -- kernel_size, linux_args)); -+ return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr, linux_args)); - } - - static grub_err_t -@@ -288,6 +282,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - { - grub_file_t file = 0; - struct linux_arch_kernel_header lh; -+ struct grub_armxx_linux_pe_header *pe; - grub_err_t err; - - grub_dl_ref (my_mod); -@@ -333,6 +328,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); - -+ if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size)) -+ { -+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); -+ goto fail; -+ } -+ -+ pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset); -+ handover_offset = pe->opt.entry_addr; -+ - cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); - linux_args = grub_malloc (cmdline_size); - if (!linux_args) -diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c -index 22cc25eccd9..d9b7a9ba400 100644 ---- a/grub-core/loader/arm64/xen_boot.c -+++ b/grub-core/loader/arm64/xen_boot.c -@@ -266,7 +266,6 @@ xen_boot (void) - return err; - - return grub_arch_efi_linux_boot_image (xen_hypervisor->start, -- xen_hypervisor->size, - xen_hypervisor->cmdline); - } - -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -new file mode 100644 -index 00000000000..c24202a5dd1 ---- /dev/null -+++ b/grub-core/loader/efi/linux.c -@@ -0,0 +1,70 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2014 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define SHIM_LOCK_GUID \ -+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} } -+ -+struct grub_efi_shim_lock -+{ -+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); -+}; -+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; -+ -+grub_efi_boolean_t -+grub_linuxefi_secure_validate (void *data, grub_uint32_t size) -+{ -+ grub_efi_guid_t guid = SHIM_LOCK_GUID; -+ grub_efi_shim_lock_t *shim_lock; -+ -+ shim_lock = grub_efi_locate_protocol(&guid, NULL); -+ -+ if (!shim_lock) -+ return 1; -+ -+ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) -+ return 1; -+ -+ return 0; -+} -+ -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wcast-align" -+ -+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *); -+ -+grub_err_t -+grub_efi_linux_boot (void *kernel_addr, grub_off_t offset, -+ void *kernel_params) -+{ -+ handover_func hf; -+ -+ hf = (handover_func)((char *)kernel_addr + offset); -+ hf (grub_efi_image_handle, grub_efi_system_table, kernel_params); -+ -+ return GRUB_ERR_BUG; -+} -+ -+#pragma GCC diagnostic pop -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -new file mode 100644 -index 00000000000..bb2616a8092 ---- /dev/null -+++ b/grub-core/loader/i386/efi/linux.c -@@ -0,0 +1,335 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2012 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_dl_t my_mod; -+static int loaded; -+static void *kernel_mem; -+static grub_uint64_t kernel_size; -+static grub_uint8_t *initrd_mem; -+static grub_uint32_t handover_offset; -+struct linux_kernel_params *params; -+static char *linux_cmdline; -+ -+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) -+ -+static grub_err_t -+grub_linuxefi_boot (void) -+{ -+ int offset = 0; -+ -+#ifdef __x86_64__ -+ offset = 512; -+#endif -+ asm volatile ("cli"); -+ -+ return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset, -+ params); -+} -+ -+static grub_err_t -+grub_linuxefi_unload (void) -+{ -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ if (initrd_mem) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, -+ BYTES_TO_PAGES(params->ramdisk_size)); -+ if (linux_cmdline) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) -+ linux_cmdline, -+ BYTES_TO_PAGES(params->cmdline_size + 1)); -+ if (kernel_mem) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -+ BYTES_TO_PAGES(kernel_size)); -+ if (params) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, -+ BYTES_TO_PAGES(16384)); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ grub_file_t *files = 0; -+ int i, nfiles = 0; -+ grub_size_t size = 0; -+ grub_uint8_t *ptr; -+ -+ if (argc == 0) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ goto fail; -+ } -+ -+ if (!loaded) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); -+ goto fail; -+ } -+ -+ files = grub_zalloc (argc * sizeof (files[0])); -+ if (!files) -+ goto fail; -+ -+ for (i = 0; i < argc; i++) -+ { -+ files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD | GRUB_FILE_TYPE_NO_DECOMPRESS); -+ if (! files[i]) -+ goto fail; -+ nfiles++; -+ size += ALIGN_UP (grub_file_size (files[i]), 4); -+ } -+ -+ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); -+ if (!initrd_mem) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); -+ goto fail; -+ } -+ -+ params->ramdisk_size = size; -+ params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem; -+ -+ ptr = initrd_mem; -+ -+ for (i = 0; i < nfiles; i++) -+ { -+ grub_ssize_t cursize = grub_file_size (files[i]); -+ if (grub_file_read (files[i], ptr, cursize) != cursize) -+ { -+ if (!grub_errno) -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), -+ argv[i]); -+ goto fail; -+ } -+ ptr += cursize; -+ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); -+ ptr += ALIGN_UP_OVERHEAD (cursize, 4); -+ } -+ -+ params->ramdisk_size = size; -+ -+ fail: -+ for (i = 0; i < nfiles; i++) -+ grub_file_close (files[i]); -+ grub_free (files); -+ -+ if (initrd_mem && grub_errno) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, -+ BYTES_TO_PAGES(size)); -+ -+ return grub_errno; -+} -+ -+static grub_err_t -+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ grub_file_t file = 0; -+ struct linux_i386_kernel_header lh; -+ grub_ssize_t len, start, filelen; -+ void *kernel = NULL; -+ -+ grub_dl_ref (my_mod); -+ -+ if (argc == 0) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ goto fail; -+ } -+ -+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); -+ if (! file) -+ goto fail; -+ -+ filelen = grub_file_size (file); -+ -+ kernel = grub_malloc(filelen); -+ -+ if (!kernel) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -+ goto fail; -+ } -+ -+ if (grub_file_read (file, kernel, filelen) != filelen) -+ { -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); -+ goto fail; -+ } -+ -+ if (! grub_linuxefi_secure_validate (kernel, filelen)) -+ { -+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), -+ argv[0]); -+ goto fail; -+ } -+ -+ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); -+ -+ if (! params) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); -+ goto fail; -+ } -+ -+ grub_memset (params, 0, 16384); -+ -+ grub_memcpy (&lh, kernel, sizeof (lh)); -+ -+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); -+ goto fail; -+ } -+ -+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); -+ goto fail; -+ } -+ -+ if (lh.version < grub_cpu_to_le16 (0x020b)) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); -+ goto fail; -+ } -+ -+ if (!lh.handover_offset) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); -+ goto fail; -+ } -+ -+ grub_dprintf ("linux", "setting up cmdline\n"); -+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, -+ BYTES_TO_PAGES(lh.cmdline_size + 1)); -+ -+ if (!linux_cmdline) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); -+ goto fail; -+ } -+ -+ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); -+ grub_create_loader_cmdline (argc, argv, -+ linux_cmdline + sizeof (LINUX_IMAGE) - 1, -+ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1), -+ GRUB_VERIFY_KERNEL_CMDLINE); -+ -+ lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; -+ -+ handover_offset = lh.handover_offset; -+ -+ start = (lh.setup_sects + 1) * 512; -+ len = grub_file_size(file) - start; -+ -+ kernel_mem = grub_efi_allocate_pages_max(lh.pref_address, -+ BYTES_TO_PAGES(lh.init_size)); -+ -+ if (!kernel_mem) -+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, -+ BYTES_TO_PAGES(lh.init_size)); -+ -+ if (!kernel_mem) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); -+ goto fail; -+ } -+ -+ grub_memcpy (kernel_mem, (char *)kernel + start, len); -+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); -+ loaded=1; -+ -+ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; -+ grub_memcpy (params, &lh, 2 * 512); -+ -+ params->type_of_loader = 0x21; -+ -+ fail: -+ -+ if (file) -+ grub_file_close (file); -+ -+ if (kernel) -+ grub_free (kernel); -+ -+ if (grub_errno != GRUB_ERR_NONE) -+ { -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ } -+ -+ if (linux_cmdline && !loaded) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) -+ linux_cmdline, -+ BYTES_TO_PAGES(lh.cmdline_size + 1)); -+ -+ if (kernel_mem && !loaded) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -+ BYTES_TO_PAGES(kernel_size)); -+ -+ if (params && !loaded) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, -+ BYTES_TO_PAGES(16384)); -+ -+ return grub_errno; -+} -+ -+static grub_command_t cmd_linux, cmd_initrd; -+static grub_command_t cmd_linuxefi, cmd_initrdefi; -+ -+GRUB_MOD_INIT(linux) -+{ -+ cmd_linux = -+ grub_register_command ("linux", grub_cmd_linux, -+ 0, N_("Load Linux.")); -+ cmd_linuxefi = -+ grub_register_command ("linuxefi", grub_cmd_linux, -+ 0, N_("Load Linux.")); -+ cmd_initrd = -+ grub_register_command ("initrd", grub_cmd_initrd, -+ 0, N_("Load initrd.")); -+ cmd_initrdefi = -+ grub_register_command ("initrdefi", grub_cmd_initrd, -+ 0, N_("Load initrd.")); -+ my_mod = mod; -+} -+ -+GRUB_MOD_FINI(linux) -+{ -+ grub_unregister_command (cmd_linux); -+ grub_unregister_command (cmd_linuxefi); -+ grub_unregister_command (cmd_initrd); -+ grub_unregister_command (cmd_initrdefi); -+} -diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c -index 2a299520160..8be4c3b3f48 100644 ---- a/grub-core/loader/i386/pc/linux.c -+++ b/grub-core/loader/i386/pc/linux.c -@@ -474,14 +474,20 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - return grub_errno; - } - --static grub_command_t cmd_linux, cmd_initrd; -+static grub_command_t cmd_linux, cmd_linux16, cmd_initrd, cmd_initrd16; - - GRUB_MOD_INIT(linux16) - { - cmd_linux = -+ grub_register_command ("linux", grub_cmd_linux, -+ 0, N_("Load Linux.")); -+ cmd_linux16 = - grub_register_command ("linux16", grub_cmd_linux, - 0, N_("Load Linux.")); - cmd_initrd = -+ grub_register_command ("initrd", grub_cmd_initrd, -+ 0, N_("Load initrd.")); -+ cmd_initrd16 = - grub_register_command ("initrd16", grub_cmd_initrd, - 0, N_("Load initrd.")); - my_mod = mod; -@@ -490,5 +496,7 @@ GRUB_MOD_INIT(linux16) - GRUB_MOD_FINI(linux16) - { - grub_unregister_command (cmd_linux); -+ grub_unregister_command (cmd_linux16); - grub_unregister_command (cmd_initrd); -+ grub_unregister_command (cmd_initrd16); - } -diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h -index bcd5a7eb186..b582f67f661 100644 ---- a/include/grub/arm/linux.h -+++ b/include/grub/arm/linux.h -@@ -20,6 +20,7 @@ - #ifndef GRUB_ARM_LINUX_HEADER - #define GRUB_ARM_LINUX_HEADER 1 - -+#include - #include "system.h" - - #define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818 -@@ -34,9 +35,17 @@ struct linux_arm_kernel_header { - grub_uint32_t hdr_offset; - }; - -+struct grub_arm_linux_pe_header -+{ -+ grub_uint32_t magic; -+ struct grub_pe32_coff_header coff; -+ struct grub_pe32_optional_header opt; -+}; -+ - #if defined(__arm__) - # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE - # define linux_arch_kernel_header linux_arm_kernel_header -+# define grub_armxx_linux_pe_header grub_arm_linux_pe_header - #endif - - #if defined GRUB_MACHINE_UBOOT -diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h -index 7e22b4ab699..ea030312df3 100644 ---- a/include/grub/arm64/linux.h -+++ b/include/grub/arm64/linux.h -@@ -19,6 +19,7 @@ - #ifndef GRUB_ARM64_LINUX_HEADER - #define GRUB_ARM64_LINUX_HEADER 1 - -+#include - #include - - #define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */ -@@ -38,9 +39,17 @@ struct linux_arm64_kernel_header - grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ - }; - -+struct grub_arm64_linux_pe_header -+{ -+ grub_uint32_t magic; -+ struct grub_pe32_coff_header coff; -+ struct grub_pe64_optional_header opt; -+}; -+ - #if defined(__aarch64__) - # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE - # define linux_arch_kernel_header linux_arm64_kernel_header -+# define grub_armxx_linux_pe_header grub_arm64_linux_pe_header - #endif - - #endif /* ! GRUB_ARM64_LINUX_HEADER */ -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 83d958f9945..6295df85f3f 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -47,6 +47,9 @@ EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address, - grub_efi_uintn_t pages); - void * - EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages); -+void * -+EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, -+ grub_efi_uintn_t pages); - void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, - grub_efi_uintn_t pages); - grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); -@@ -88,6 +91,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, - const grub_efi_guid_t *guid, - void *data, - grub_size_t datasize); -+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); - int - EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, - const grub_efi_device_path_t *dp2); -@@ -101,8 +105,7 @@ void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); - grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); - #include - grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); --grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, -- char *args); -+grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args); - #endif - - grub_addr_t grub_efi_modules_addr (void); -diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h -new file mode 100644 -index 00000000000..d9ede36773b ---- /dev/null -+++ b/include/grub/efi/linux.h -@@ -0,0 +1,31 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2014 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+#ifndef GRUB_EFI_LINUX_HEADER -+#define GRUB_EFI_LINUX_HEADER 1 -+ -+#include -+#include -+#include -+ -+grub_efi_boolean_t -+EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size); -+grub_err_t -+EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset, -+ void *kernel_param); -+ -+#endif /* ! GRUB_EFI_LINUX_HEADER */ diff --git a/0005-Rework-linux-command.patch b/0005-Rework-linux-command.patch deleted file mode 100644 index 9954dd0..0000000 --- a/0005-Rework-linux-command.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Sun, 9 Aug 2015 16:12:39 -0700 -Subject: [PATCH] Rework linux command - -We want a single buffer that contains the entire kernel image in order to -perform a TPM measurement. Allocate one and copy the entire kernel into it -before pulling out the individual blocks later on. - -Signed-off-by: Matthew Garrett ---- - grub-core/loader/i386/linux.c | 35 +++++++++++++++++++++++------------ - 1 file changed, 23 insertions(+), 12 deletions(-) - -diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index 9f74a96b19a..dccf3bb3005 100644 ---- a/grub-core/loader/i386/linux.c -+++ b/grub-core/loader/i386/linux.c -@@ -649,13 +649,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - { - grub_file_t file = 0; - struct linux_i386_kernel_header lh; -+ grub_uint8_t *linux_params_ptr; - grub_uint8_t setup_sects; -- grub_size_t real_size, prot_size, prot_file_size; -+ grub_size_t real_size, prot_size, prot_file_size, kernel_offset; - grub_ssize_t len; - int i; - grub_size_t align, min_align; - int relocatable; - grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; -+ grub_uint8_t *kernel = NULL; - - grub_dl_ref (my_mod); - -@@ -669,7 +671,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - if (! file) - goto fail; - -- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) -+ len = grub_file_size (file); -+ kernel = grub_malloc (len); -+ if (!kernel) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -+ goto fail; -+ } -+ -+ if (grub_file_read (file, kernel, len) != len) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -@@ -677,6 +687,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_memcpy (&lh, kernel, sizeof (lh)); -+ kernel_offset = sizeof (lh); -+ - if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) - { - grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); -@@ -784,13 +797,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - /* We've already read lh so there is no need to read it second time. */ - len -= sizeof(lh); - -- if ((len > 0) && -- (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len)) -+ linux_params_ptr = (void *)&linux_params; -+ if (len > 0) - { -- if (!grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -- argv[0]); -- goto fail; -+ grub_memcpy (linux_params_ptr + sizeof (lh), kernel + kernel_offset, len); -+ kernel_offset += len; - } - - linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; -@@ -853,7 +864,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - /* The other parameters are filled when booting. */ - -- grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); -+ kernel_offset = real_size + GRUB_DISK_SECTOR_SIZE; - - grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n", - (unsigned) real_size, (unsigned) prot_size); -@@ -1007,9 +1018,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - - len = prot_file_size; -- if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -- argv[0]); -+ grub_memcpy (prot_mode_mem, kernel + kernel_offset, len); - - if (grub_errno == GRUB_ERR_NONE) - { -@@ -1020,6 +1029,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - fail: - -+ grub_free (kernel); -+ - if (file) - grub_file_close (file); - diff --git a/0006-Rework-linux16-command.patch b/0006-Rework-linux16-command.patch deleted file mode 100644 index 2c2d6f0..0000000 --- a/0006-Rework-linux16-command.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Sun, 9 Aug 2015 16:20:58 -0700 -Subject: [PATCH] Rework linux16 command - -We want a single buffer that contains the entire kernel image in order to -perform a TPM measurement. Allocate one and copy the entire kernel int it -before pulling out the individual blocks later on. - -Signed-off-by: Matthew Garrett ---- - grub-core/loader/i386/pc/linux.c | 33 +++++++++++++++++++++------------ - 1 file changed, 21 insertions(+), 12 deletions(-) - -diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c -index 8be4c3b3f48..4b1750e360e 100644 ---- a/grub-core/loader/i386/pc/linux.c -+++ b/grub-core/loader/i386/pc/linux.c -@@ -124,13 +124,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_file_t file = 0; - struct linux_i386_kernel_header lh; - grub_uint8_t setup_sects; -- grub_size_t real_size; -+ grub_size_t real_size, kernel_offset = 0; - grub_ssize_t len; - int i; - char *grub_linux_prot_chunk; - int grub_linux_is_bzimage; - grub_addr_t grub_linux_prot_target; - grub_err_t err; -+ grub_uint8_t *kernel = NULL; - - grub_dl_ref (my_mod); - -@@ -144,7 +145,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - if (! file) - goto fail; - -- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) -+ len = grub_file_size (file); -+ kernel = grub_malloc (len); -+ if (!kernel) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -+ goto fail; -+ } -+ -+ if (grub_file_read (file, kernel, len) != len) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -@@ -152,6 +161,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_memcpy (&lh, kernel, sizeof (lh)); -+ kernel_offset = sizeof (lh); -+ - if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) - { - grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); -@@ -320,13 +332,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh)); - - len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh); -- if (grub_file_read (file, grub_linux_real_chunk + sizeof (lh), len) != len) -- { -- if (!grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -- argv[0]); -- goto fail; -- } -+ grub_memcpy (grub_linux_real_chunk + sizeof (lh), kernel + kernel_offset, -+ len); -+ kernel_offset += len; - - if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) - || grub_le_to_cpu16 (lh.version) < 0x0200) -@@ -364,9 +372,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - - len = grub_linux16_prot_size; -- if (grub_file_read (file, grub_linux_prot_chunk, len) != len && !grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -- argv[0]); -+ grub_memcpy (grub_linux_prot_chunk, kernel + kernel_offset, len); -+ kernel_offset += len; - - if (grub_errno == GRUB_ERR_NONE) - { -@@ -376,6 +383,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - fail: - -+ grub_free (kernel); -+ - if (file) - grub_file_close (file); - diff --git a/0007-Add-secureboot-support-on-efi-chainloader.patch b/0007-Add-secureboot-support-on-efi-chainloader.patch deleted file mode 100644 index 6826cce..0000000 --- a/0007-Add-secureboot-support-on-efi-chainloader.patch +++ /dev/null @@ -1,1401 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Raymund Will -Date: Mon, 8 Jul 2019 11:55:18 +0200 -Subject: [PATCH] Add secureboot support on efi chainloader - -Expand the chainloader to be able to verify the image by means of shim -lock protocol. The PE/COFF image is loaded and relocated by the -chainloader instead of calling LoadImage and StartImage UEFI boot -Service as they require positive verification result from keys enrolled -in KEK or DB. The shim will use MOK in addition to firmware enrolled -keys to verify the image. - -The chainloader module could be used to load other UEFI bootloaders, -such as xen.efi, and could be signed by any of MOK, KEK or DB. - -Based on https://build.opensuse.org/package/view_file/openSUSE:Factory/grub2/grub2-secureboot-chainloader.patch - -Signed-off-by: Peter Jones - -Also: - -commit cd7a8984d4fda905877b5bfe466339100156b3bc -Author: Raymund Will -Date: Fri Apr 10 01:45:02 2015 -0400 - -Use device part of chainloader target, if present. - -Otherwise chainloading is restricted to '$root', which might not even -be readable by EFI! - -v1. use grub_file_get_device_name() to get device name - -Signed-off-by: Michael Chang -Signed-off-by: Peter Jones - -Also: - -commit 0872a2310a0eeac4ecfe9e1b49dd2d72ab373039 -Author: Peter Jones -Date: Fri Jun 10 14:06:15 2016 -0400 - -Rework even more of efi chainload so non-sb cases work right. - -This ensures that if shim protocol is not loaded, or is loaded but shim -is disabled, we will fall back to a correct load method for the efi -chain loader. - -Here's what I tested with this version: - -results expected actual ------------------------------------------------------------- -sb + enabled + shim + fedora success success -sb + enabled + shim + win success success -sb + enabled + grub + fedora fail fail -sb + enabled + grub + win fail fail - -sb + mokdisabled + shim + fedora success success -sb + mokdisabled + shim + win success success -sb + mokdisabled + grub + fedora fail fail -sb + mokdisabled + grub + win fail fail - -sb disabled + shim + fedora success success* -sb disabled + shim + win success success* -sb disabled + grub + fedora success success -sb disabled + grub + win success success - -nosb + shim + fedora success success* -nosb + shim + win success success* -nosb + grub + fedora success success -nosb + grub + win success success - -* for some reason shim protocol is being installed in these cases, and I - can't see why, but I think it may be this firmware build returning an - erroneous value. But this effectively falls back to the mokdisabled - behavior, which works correctly, and the presence of the "grub" (i.e. - no shim) tests effectively tests the desired behavior here. - -Resolves: rhbz#1344512 - -Signed-off-by: Peter Jones - -Also: - -commit ff7b1cb7f69487870211aeb69ff4f54470fbcb58 -Author: Laszlo Ersek -Date: Mon Nov 21 15:34:00 2016 +0100 - -efi/chainloader: fix wrong sanity check in relocate_coff() - -In relocate_coff(), the relocation entries are parsed from the original -image (not the section-wise copied image). The original image is -pointed-to by the "orig" pointer. The current check - - (void *)reloc_end < data - -compares the addresses of independent memory allocations. "data" is a typo -here, it should be "orig". - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1347291 -Signed-off-by: Laszlo Ersek -Tested-by: Bogdan Costescu -Tested-by: Juan Orti - -Also: - -commit ab4ba9997ad4832449e54d930fa2aac6a160d0e9 -Author: Laszlo Ersek -Date: Wed Nov 23 06:27:09 2016 +0100 - -efi/chainloader: truncate overlong relocation section - -The UEFI Windows 7 boot loader ("EFI/Microsoft/Boot/bootmgfw.efi", SHA1 -31b410e029bba87d2068c65a80b88882f9f8ea25) has inconsistent headers. - -Compare: - -> The Data Directory -> ... -> Entry 5 00000000000d9000 00000574 Base Relocation Directory [.reloc] - -Versus: - -> Sections: -> Idx Name Size VMA LMA File off ... -> ... -> 10 .reloc 00000e22 00000000100d9000 00000000100d9000 000a1800 ... - -That is, the size reported by the RelocDir entry (0x574) is smaller than -the virtual size of the .reloc section (0xe22). - -Quoting the grub2 debug log for the same: - -> chainloader.c:595: reloc_dir: 0xd9000 reloc_size: 0x00000574 -> chainloader.c:603: reloc_base: 0x7d208000 reloc_base_end: 0x7d208573 -> ... -> chainloader.c:620: Section 10 ".reloc" at 0x7d208000..0x7d208e21 -> chainloader.c:661: section is not reloc section? -> chainloader.c:663: rds: 0x00001000, vs: 00000e22 -> chainloader.c:664: base: 0x7d208000 end: 0x7d208e21 -> chainloader.c:666: reloc_base: 0x7d208000 reloc_base_end: 0x7d208573 -> chainloader.c:671: Section characteristics are 42000040 -> chainloader.c:673: Section virtual size: 00000e22 -> chainloader.c:675: Section raw_data size: 00001000 -> chainloader.c:678: Discarding section - -After hexdumping "bootmgfw.efi" and manually walking its relocation blocks -(yes, really), I determined that the (smaller) RelocDir value is correct. -The remaining area that extends up to the .reloc section size (== 0xe22 - -0x574 == 0x8ae bytes) exists as zero padding in the file. - -This zero padding shouldn't be passed to relocate_coff() for parsing. In -order to cope with it, split the handling of .reloc sections into the -following branches: - -- original case (equal size): original behavior (--> relocation - attempted), - -- overlong .reloc section (longer than reported by RelocDir): truncate the - section to the RelocDir size for the purposes of relocate_coff(), and - attempt relocation, - -- .reloc section is too short, or other checks fail: original behavior - (--> relocation not attempted). - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1347291 -Signed-off-by: Laszlo Ersek - -Also: - -commit cc06f149fbd2d8c1da1e83173d21629ba97e0d92 -Author: Raymund Will - -chainloader: Define machine types for RISC-V - -The commit "Add secureboot support on efi chainloader" didn't add machine -types for RISC-V, so this patch adds them. - -Note, that grub-core/loader/riscv/linux.c is skipped because Linux is not -supported yet. This patch might need a new revision once that's the case. - -Signed-off-by: David Abdurachmanov ---- - grub-core/kern/efi/efi.c | 14 +- - grub-core/loader/arm64/linux.c | 4 +- - grub-core/loader/efi/chainloader.c | 820 +++++++++++++++++++++++++++++++++---- - grub-core/loader/efi/linux.c | 25 +- - grub-core/loader/i386/efi/linux.c | 17 +- - include/grub/efi/linux.h | 2 +- - include/grub/efi/pe32.h | 52 ++- - 7 files changed, 844 insertions(+), 90 deletions(-) - -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 35b8f670602..4a2259aa1c7 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -296,14 +296,20 @@ grub_efi_secure_boot (void) - grub_efi_boolean_t ret = 0; - - secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); -- - if (datasize != 1 || !secure_boot) -- goto out; -+ { -+ grub_dprintf ("secureboot", "No SecureBoot variable\n"); -+ goto out; -+ } -+ grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot); - - setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); -- - if (datasize != 1 || !setup_mode) -- goto out; -+ { -+ grub_dprintf ("secureboot", "No SetupMode variable\n"); -+ goto out; -+ } -+ grub_dprintf ("secureboot", "SetupMode: %d\n", *setup_mode); - - if (*secure_boot && !*setup_mode) - ret = 1; -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index a312c668685..04994d5c67d 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -284,6 +284,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - struct linux_arch_kernel_header lh; - struct grub_armxx_linux_pe_header *pe; - grub_err_t err; -+ int rc; - - grub_dl_ref (my_mod); - -@@ -328,7 +329,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); - -- if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size)) -+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size); -+ if (rc < 0) - { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); - goto fail; -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 2bd80f4db3d..e6a8d4ad0e9 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -32,6 +32,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -46,9 +48,14 @@ static grub_dl_t my_mod; - - static grub_efi_physical_address_t address; - static grub_efi_uintn_t pages; -+static grub_ssize_t fsize; - static grub_efi_device_path_t *file_path; - static grub_efi_handle_t image_handle; - static grub_efi_char16_t *cmdline; -+static grub_ssize_t cmdline_len; -+static grub_efi_handle_t dev_handle; -+ -+static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table); - - static grub_err_t - grub_chainloader_unload (void) -@@ -63,6 +70,7 @@ grub_chainloader_unload (void) - grub_free (cmdline); - cmdline = 0; - file_path = 0; -+ dev_handle = 0; - - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -@@ -213,20 +221,694 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) - return file_path; - } - -+#define SHIM_LOCK_GUID \ -+ { 0x605dab50, 0xe046, 0x4300, { 0xab,0xb6,0x3d,0xd8,0x10,0xdd,0x8b,0x23 } } -+ -+typedef union -+{ -+ struct grub_pe32_header_32 pe32; -+ struct grub_pe32_header_64 pe32plus; -+} grub_pe_header_t; -+ -+struct pe_coff_loader_image_context -+{ -+ grub_efi_uint64_t image_address; -+ grub_efi_uint64_t image_size; -+ grub_efi_uint64_t entry_point; -+ grub_efi_uintn_t size_of_headers; -+ grub_efi_uint16_t image_type; -+ grub_efi_uint16_t number_of_sections; -+ grub_efi_uint32_t section_alignment; -+ struct grub_pe32_section_table *first_section; -+ struct grub_pe32_data_directory *reloc_dir; -+ struct grub_pe32_data_directory *sec_dir; -+ grub_efi_uint64_t number_of_rva_and_sizes; -+ grub_pe_header_t *pe_hdr; -+}; -+ -+typedef struct pe_coff_loader_image_context pe_coff_loader_image_context_t; -+ -+struct grub_efi_shim_lock -+{ -+ grub_efi_status_t (*verify)(void *buffer, -+ grub_efi_uint32_t size); -+ grub_efi_status_t (*hash)(void *data, -+ grub_efi_int32_t datasize, -+ pe_coff_loader_image_context_t *context, -+ grub_efi_uint8_t *sha256hash, -+ grub_efi_uint8_t *sha1hash); -+ grub_efi_status_t (*context)(void *data, -+ grub_efi_uint32_t size, -+ pe_coff_loader_image_context_t *context); -+}; -+ -+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; -+ -+static grub_efi_boolean_t -+read_header (void *data, grub_efi_uint32_t size, -+ pe_coff_loader_image_context_t *context) -+{ -+ grub_efi_guid_t guid = SHIM_LOCK_GUID; -+ grub_efi_shim_lock_t *shim_lock; -+ grub_efi_status_t status; -+ -+ shim_lock = grub_efi_locate_protocol (&guid, NULL); -+ if (!shim_lock) -+ { -+ grub_dprintf ("chain", "no shim lock protocol"); -+ return 0; -+ } -+ -+ status = shim_lock->context (data, size, context); -+ -+ if (status == GRUB_EFI_SUCCESS) -+ { -+ grub_dprintf ("chain", "context success\n"); -+ return 1; -+ } -+ -+ switch (status) -+ { -+ case GRUB_EFI_UNSUPPORTED: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported"); -+ break; -+ case GRUB_EFI_INVALID_PARAMETER: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter"); -+ break; -+ default: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code"); -+ break; -+ } -+ -+ return -1; -+} -+ -+static void* -+image_address (void *image, grub_efi_uint64_t sz, grub_efi_uint64_t adr) -+{ -+ if (adr > sz) -+ return NULL; -+ -+ return ((grub_uint8_t*)image + adr); -+} -+ -+static int -+image_is_64_bit (grub_pe_header_t *pe_hdr) -+{ -+ /* .Magic is the same offset in all cases */ -+ if (pe_hdr->pe32plus.optional_header.magic == GRUB_PE32_PE64_MAGIC) -+ return 1; -+ return 0; -+} -+ -+static const grub_uint16_t machine_type __attribute__((__unused__)) = -+#if defined(__x86_64__) -+ GRUB_PE32_MACHINE_X86_64; -+#elif defined(__aarch64__) -+ GRUB_PE32_MACHINE_ARM64; -+#elif defined(__arm__) -+ GRUB_PE32_MACHINE_ARMTHUMB_MIXED; -+#elif defined(__i386__) || defined(__i486__) || defined(__i686__) -+ GRUB_PE32_MACHINE_I386; -+#elif defined(__ia64__) -+ GRUB_PE32_MACHINE_IA64; -+#elif defined(__riscv) && (__riscv_xlen == 32) -+ GRUB_PE32_MACHINE_RISCV32; -+#elif defined(__riscv) && (__riscv_xlen == 64) -+ GRUB_PE32_MACHINE_RISCV64; -+#else -+#error this architecture is not supported by grub2 -+#endif -+ -+static grub_efi_status_t -+relocate_coff (pe_coff_loader_image_context_t *context, -+ struct grub_pe32_section_table *section, -+ void *orig, void *data) -+{ -+ struct grub_pe32_data_directory *reloc_base, *reloc_base_end; -+ grub_efi_uint64_t adjust; -+ struct grub_pe32_fixup_block *reloc, *reloc_end; -+ char *fixup, *fixup_base, *fixup_data = NULL; -+ grub_efi_uint16_t *fixup_16; -+ grub_efi_uint32_t *fixup_32; -+ grub_efi_uint64_t *fixup_64; -+ grub_efi_uint64_t size = context->image_size; -+ void *image_end = (char *)orig + size; -+ int n = 0; -+ -+ if (image_is_64_bit (context->pe_hdr)) -+ context->pe_hdr->pe32plus.optional_header.image_base = -+ (grub_uint64_t)(unsigned long)data; -+ else -+ context->pe_hdr->pe32.optional_header.image_base = -+ (grub_uint32_t)(unsigned long)data; -+ -+ /* Alright, so here's how this works: -+ * -+ * context->reloc_dir gives us two things: -+ * - the VA the table of base relocation blocks are (maybe) to be -+ * mapped at (reloc_dir->rva) -+ * - the virtual size (reloc_dir->size) -+ * -+ * The .reloc section (section here) gives us some other things: -+ * - the name! kind of. (section->name) -+ * - the virtual size (section->virtual_size), which should be the same -+ * as RelocDir->Size -+ * - the virtual address (section->virtual_address) -+ * - the file section size (section->raw_data_size), which is -+ * a multiple of optional_header->file_alignment. Only useful for image -+ * validation, not really useful for iteration bounds. -+ * - the file address (section->raw_data_offset) -+ * - a bunch of stuff we don't use that's 0 in our binaries usually -+ * - Flags (section->characteristics) -+ * -+ * and then the thing that's actually at the file address is an array -+ * of struct grub_pe32_fixup_block structs with some values packed behind -+ * them. The block_size field of this structure includes the -+ * structure itself, and adding it to that structure's address will -+ * yield the next entry in the array. -+ */ -+ -+ reloc_base = image_address (orig, size, section->raw_data_offset); -+ reloc_base_end = image_address (orig, size, section->raw_data_offset -+ + section->virtual_size); -+ -+ grub_dprintf ("chain", "relocate_coff(): reloc_base %p reloc_base_end %p\n", -+ reloc_base, reloc_base_end); -+ -+ if (!reloc_base && !reloc_base_end) -+ return GRUB_EFI_SUCCESS; -+ -+ if (!reloc_base || !reloc_base_end) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary"); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ -+ adjust = (grub_uint64_t)(grub_efi_uintn_t)data - context->image_address; -+ if (adjust == 0) -+ return GRUB_EFI_SUCCESS; -+ -+ while (reloc_base < reloc_base_end) -+ { -+ grub_uint16_t *entry; -+ reloc = (struct grub_pe32_fixup_block *)((char*)reloc_base); -+ -+ if ((reloc_base->size == 0) || -+ (reloc_base->size > context->reloc_dir->size)) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Reloc %d block size %d is invalid\n", n, -+ reloc_base->size); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ -+ entry = &reloc->entries[0]; -+ reloc_end = (struct grub_pe32_fixup_block *) -+ ((char *)reloc_base + reloc_base->size); -+ -+ if ((void *)reloc_end < orig || (void *)reloc_end > image_end) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc entry %d overflows binary", -+ n); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ -+ fixup_base = image_address(data, size, reloc_base->rva); -+ -+ if (!fixup_base) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc %d Invalid fixupbase", n); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ -+ while ((void *)entry < (void *)reloc_end) -+ { -+ fixup = fixup_base + (*entry & 0xFFF); -+ switch ((*entry) >> 12) -+ { -+ case GRUB_PE32_REL_BASED_ABSOLUTE: -+ break; -+ case GRUB_PE32_REL_BASED_HIGH: -+ fixup_16 = (grub_uint16_t *)fixup; -+ *fixup_16 = (grub_uint16_t) -+ (*fixup_16 + ((grub_uint16_t)((grub_uint32_t)adjust >> 16))); -+ if (fixup_data != NULL) -+ { -+ *(grub_uint16_t *) fixup_data = *fixup_16; -+ fixup_data = fixup_data + sizeof (grub_uint16_t); -+ } -+ break; -+ case GRUB_PE32_REL_BASED_LOW: -+ fixup_16 = (grub_uint16_t *)fixup; -+ *fixup_16 = (grub_uint16_t) (*fixup_16 + (grub_uint16_t)adjust); -+ if (fixup_data != NULL) -+ { -+ *(grub_uint16_t *) fixup_data = *fixup_16; -+ fixup_data = fixup_data + sizeof (grub_uint16_t); -+ } -+ break; -+ case GRUB_PE32_REL_BASED_HIGHLOW: -+ fixup_32 = (grub_uint32_t *)fixup; -+ *fixup_32 = *fixup_32 + (grub_uint32_t)adjust; -+ if (fixup_data != NULL) -+ { -+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint32_t)); -+ *(grub_uint32_t *) fixup_data = *fixup_32; -+ fixup_data += sizeof (grub_uint32_t); -+ } -+ break; -+ case GRUB_PE32_REL_BASED_DIR64: -+ fixup_64 = (grub_uint64_t *)fixup; -+ *fixup_64 = *fixup_64 + (grub_uint64_t)adjust; -+ if (fixup_data != NULL) -+ { -+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint64_t)); -+ *(grub_uint64_t *) fixup_data = *fixup_64; -+ fixup_data += sizeof (grub_uint64_t); -+ } -+ break; -+ default: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Reloc %d unknown relocation type %d", -+ n, (*entry) >> 12); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ entry += 1; -+ } -+ reloc_base = (struct grub_pe32_data_directory *)reloc_end; -+ n++; -+ } -+ -+ return GRUB_EFI_SUCCESS; -+} -+ -+static grub_efi_device_path_t * -+grub_efi_get_media_file_path (grub_efi_device_path_t *dp) -+{ -+ while (1) -+ { -+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); -+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); -+ -+ if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) -+ break; -+ else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE -+ && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) -+ return dp; -+ -+ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); -+ } -+ -+ return NULL; -+} -+ -+static grub_efi_boolean_t -+handle_image (void *data, grub_efi_uint32_t datasize) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_loaded_image_t *li, li_bak; -+ grub_efi_status_t efi_status; -+ char *buffer = NULL; -+ char *buffer_aligned = NULL; -+ grub_efi_uint32_t i; -+ struct grub_pe32_section_table *section; -+ char *base, *end; -+ pe_coff_loader_image_context_t context; -+ grub_uint32_t section_alignment; -+ grub_uint32_t buffer_size; -+ int found_entry_point = 0; -+ int rc; -+ -+ b = grub_efi_system_table->boot_services; -+ -+ rc = read_header (data, datasize, &context); -+ if (rc < 0) -+ { -+ grub_dprintf ("chain", "Failed to read header\n"); -+ goto error_exit; -+ } -+ else if (rc == 0) -+ { -+ grub_dprintf ("chain", "Secure Boot is not enabled\n"); -+ return 0; -+ } -+ else -+ { -+ grub_dprintf ("chain", "Header read without error\n"); -+ } -+ -+ /* -+ * The spec says, uselessly, of SectionAlignment: -+ * ===== -+ * The alignment (in bytes) of sections when they are loaded into -+ * memory. It must be greater than or equal to FileAlignment. The -+ * default is the page size for the architecture. -+ * ===== -+ * Which doesn't tell you whose responsibility it is to enforce the -+ * "default", or when. It implies that the value in the field must -+ * be > FileAlignment (also poorly defined), but it appears visual -+ * studio will happily write 512 for FileAlignment (its default) and -+ * 0 for SectionAlignment, intending to imply PAGE_SIZE. -+ * -+ * We only support one page size, so if it's zero, nerf it to 4096. -+ */ -+ section_alignment = context.section_alignment; -+ if (section_alignment == 0) -+ section_alignment = 4096; -+ -+ buffer_size = context.image_size + section_alignment; -+ grub_dprintf ("chain", "image size is %08"PRIxGRUB_UINT64_T", datasize is %08x\n", -+ context.image_size, datasize); -+ -+ efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, -+ buffer_size, &buffer); -+ -+ if (efi_status != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto error_exit; -+ } -+ -+ buffer_aligned = (char *)ALIGN_UP ((grub_addr_t)buffer, section_alignment); -+ if (!buffer_aligned) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto error_exit; -+ } -+ -+ grub_memcpy (buffer_aligned, data, context.size_of_headers); -+ -+ entry_point = image_address (buffer_aligned, context.image_size, -+ context.entry_point); -+ -+ grub_dprintf ("chain", "entry_point: %p\n", entry_point); -+ if (!entry_point) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid entry point"); -+ goto error_exit; -+ } -+ -+ char *reloc_base, *reloc_base_end; -+ grub_dprintf ("chain", "reloc_dir: %p reloc_size: 0x%08x\n", -+ (void *)(unsigned long)context.reloc_dir->rva, -+ context.reloc_dir->size); -+ reloc_base = image_address (buffer_aligned, context.image_size, -+ context.reloc_dir->rva); -+ /* RelocBaseEnd here is the address of the last byte of the table */ -+ reloc_base_end = image_address (buffer_aligned, context.image_size, -+ context.reloc_dir->rva -+ + context.reloc_dir->size - 1); -+ grub_dprintf ("chain", "reloc_base: %p reloc_base_end: %p\n", -+ reloc_base, reloc_base_end); -+ -+ struct grub_pe32_section_table *reloc_section = NULL, fake_reloc_section; -+ -+ section = context.first_section; -+ for (i = 0; i < context.number_of_sections; i++, section++) -+ { -+ char name[9]; -+ -+ base = image_address (buffer_aligned, context.image_size, -+ section->virtual_address); -+ end = image_address (buffer_aligned, context.image_size, -+ section->virtual_address + section->virtual_size -1); -+ -+ grub_strncpy(name, section->name, 9); -+ name[8] = '\0'; -+ grub_dprintf ("chain", "Section %d \"%s\" at %p..%p\n", i, -+ name, base, end); -+ -+ if (end < base) -+ { -+ grub_dprintf ("chain", " base is %p but end is %p... bad.\n", -+ base, end); -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Image has invalid negative size"); -+ goto error_exit; -+ } -+ -+ if (section->virtual_address <= context.entry_point && -+ (section->virtual_address + section->raw_data_size - 1) -+ > context.entry_point) -+ { -+ found_entry_point++; -+ grub_dprintf ("chain", " section contains entry point\n"); -+ } -+ -+ /* We do want to process .reloc, but it's often marked -+ * discardable, so we don't want to memcpy it. */ -+ if (grub_memcmp (section->name, ".reloc\0\0", 8) == 0) -+ { -+ if (reloc_section) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Image has multiple relocation sections"); -+ goto error_exit; -+ } -+ -+ /* If it has nonzero sizes, and our bounds check -+ * made sense, and the VA and size match RelocDir's -+ * versions, then we believe in this section table. */ -+ if (section->raw_data_size && section->virtual_size && -+ base && end && reloc_base == base) -+ { -+ if (reloc_base_end == end) -+ { -+ grub_dprintf ("chain", " section is relocation section\n"); -+ reloc_section = section; -+ } -+ else if (reloc_base_end && reloc_base_end < end) -+ { -+ /* Bogus virtual size in the reloc section -- RelocDir -+ * reported a smaller Base Relocation Directory. Decrease -+ * the section's virtual size so that it equal RelocDir's -+ * idea, but only for the purposes of relocate_coff(). */ -+ grub_dprintf ("chain", -+ " section is (overlong) relocation section\n"); -+ grub_memcpy (&fake_reloc_section, section, sizeof *section); -+ fake_reloc_section.virtual_size -= (end - reloc_base_end); -+ reloc_section = &fake_reloc_section; -+ } -+ } -+ -+ if (!reloc_section) -+ { -+ grub_dprintf ("chain", " section is not reloc section?\n"); -+ grub_dprintf ("chain", " rds: 0x%08x, vs: %08x\n", -+ section->raw_data_size, section->virtual_size); -+ grub_dprintf ("chain", " base: %p end: %p\n", base, end); -+ grub_dprintf ("chain", " reloc_base: %p reloc_base_end: %p\n", -+ reloc_base, reloc_base_end); -+ } -+ } -+ -+ grub_dprintf ("chain", " Section characteristics are %08x\n", -+ section->characteristics); -+ grub_dprintf ("chain", " Section virtual size: %08x\n", -+ section->virtual_size); -+ grub_dprintf ("chain", " Section raw_data size: %08x\n", -+ section->raw_data_size); -+ if (section->characteristics & GRUB_PE32_SCN_MEM_DISCARDABLE) -+ { -+ grub_dprintf ("chain", " Discarding section\n"); -+ continue; -+ } -+ -+ if (!base || !end) -+ { -+ grub_dprintf ("chain", " section is invalid\n"); -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid section size"); -+ goto error_exit; -+ } -+ -+ if (section->characteristics & GRUB_PE32_SCN_CNT_UNINITIALIZED_DATA) -+ { -+ if (section->raw_data_size != 0) -+ grub_dprintf ("chain", " UNINITIALIZED_DATA section has data?\n"); -+ } -+ else if (section->virtual_address < context.size_of_headers || -+ section->raw_data_offset < context.size_of_headers) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Section %d is inside image headers", i); -+ goto error_exit; -+ } -+ -+ if (section->raw_data_size > 0) -+ { -+ grub_dprintf ("chain", " copying 0x%08x bytes to %p\n", -+ section->raw_data_size, base); -+ grub_memcpy (base, -+ (grub_efi_uint8_t*)data + section->raw_data_offset, -+ section->raw_data_size); -+ } -+ -+ if (section->raw_data_size < section->virtual_size) -+ { -+ grub_dprintf ("chain", " padding with 0x%08x bytes at %p\n", -+ section->virtual_size - section->raw_data_size, -+ base + section->raw_data_size); -+ grub_memset (base + section->raw_data_size, 0, -+ section->virtual_size - section->raw_data_size); -+ } -+ -+ grub_dprintf ("chain", " finished section %s\n", name); -+ } -+ -+ /* 5 == EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC */ -+ if (context.number_of_rva_and_sizes <= 5) -+ { -+ grub_dprintf ("chain", "image has no relocation entry\n"); -+ goto error_exit; -+ } -+ -+ if (context.reloc_dir->size && reloc_section) -+ { -+ /* run the relocation fixups */ -+ efi_status = relocate_coff (&context, reloc_section, data, -+ buffer_aligned); -+ -+ if (efi_status != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "relocation failed"); -+ goto error_exit; -+ } -+ } -+ -+ if (!found_entry_point) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "entry point is not within sections"); -+ goto error_exit; -+ } -+ if (found_entry_point > 1) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "%d sections contain entry point", -+ found_entry_point); -+ goto error_exit; -+ } -+ -+ li = grub_efi_get_loaded_image (grub_efi_image_handle); -+ if (!li) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no loaded image available"); -+ goto error_exit; -+ } -+ -+ grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t)); -+ li->image_base = buffer_aligned; -+ li->image_size = context.image_size; -+ li->load_options = cmdline; -+ li->load_options_size = cmdline_len; -+ li->file_path = grub_efi_get_media_file_path (file_path); -+ li->device_handle = dev_handle; -+ if (!li->file_path) -+ { -+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found"); -+ goto error_exit; -+ } -+ -+ grub_dprintf ("chain", "booting via entry point\n"); -+ efi_status = efi_call_2 (entry_point, grub_efi_image_handle, -+ grub_efi_system_table); -+ -+ grub_dprintf ("chain", "entry_point returned %ld\n", efi_status); -+ grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); -+ efi_status = efi_call_1 (b->free_pool, buffer); -+ -+ return 1; -+ -+error_exit: -+ grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno); -+ if (buffer) -+ efi_call_1 (b->free_pool, buffer); -+ -+ return 0; -+} -+ -+static grub_err_t -+grub_secureboot_chainloader_unload (void) -+{ -+ grub_efi_boot_services_t *b; -+ -+ b = grub_efi_system_table->boot_services; -+ efi_call_2 (b->free_pages, address, pages); -+ grub_free (file_path); -+ grub_free (cmdline); -+ cmdline = 0; -+ file_path = 0; -+ dev_handle = 0; -+ -+ grub_dl_unref (my_mod); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_load_and_start_image(void *boot_image) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_status_t status; -+ grub_efi_loaded_image_t *loaded_image; -+ -+ b = grub_efi_system_table->boot_services; -+ -+ status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, -+ boot_image, fsize, &image_handle); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ if (status == GRUB_EFI_OUT_OF_RESOURCES) -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); -+ else -+ grub_error (GRUB_ERR_BAD_OS, "cannot load image"); -+ return -1; -+ } -+ -+ /* LoadImage does not set a device handler when the image is -+ loaded from memory, so it is necessary to set it explicitly here. -+ This is a mess. */ -+ loaded_image = grub_efi_get_loaded_image (image_handle); -+ if (! loaded_image) -+ { -+ grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); -+ return -1; -+ } -+ loaded_image->device_handle = dev_handle; -+ -+ if (cmdline) -+ { -+ loaded_image->load_options = cmdline; -+ loaded_image->load_options_size = cmdline_len; -+ } -+ -+ return 0; -+} -+ -+static grub_err_t -+grub_secureboot_chainloader_boot (void) -+{ -+ int rc; -+ rc = handle_image ((void *)(unsigned long)address, fsize); -+ if (rc == 0) -+ { -+ grub_load_and_start_image((void *)(unsigned long)address); -+ } -+ -+ grub_loader_unset (); -+ return grub_errno; -+} -+ - static grub_err_t - grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) - { - grub_file_t file = 0; -- grub_ssize_t size; - grub_efi_status_t status; - grub_efi_boot_services_t *b; - grub_device_t dev = 0; - grub_efi_device_path_t *dp = 0; -- grub_efi_loaded_image_t *loaded_image; - char *filename; - void *boot_image = 0; -- grub_efi_handle_t dev_handle = 0; -+ int rc; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -@@ -238,15 +920,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - address = 0; - image_handle = 0; - file_path = 0; -+ dev_handle = 0; - - b = grub_efi_system_table->boot_services; - -+ if (argc > 1) -+ { -+ int i; -+ grub_efi_char16_t *p16; -+ -+ for (i = 1, cmdline_len = 0; i < argc; i++) -+ cmdline_len += grub_strlen (argv[i]) + 1; -+ -+ cmdline_len *= sizeof (grub_efi_char16_t); -+ cmdline = p16 = grub_malloc (cmdline_len); -+ if (! cmdline) -+ goto fail; -+ -+ for (i = 1; i < argc; i++) -+ { -+ char *p8; -+ -+ p8 = argv[i]; -+ while (*p8) -+ *(p16++) = *(p8++); -+ -+ *(p16++) = ' '; -+ } -+ *(--p16) = 0; -+ } -+ - file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE); - if (! file) - goto fail; - -- /* Get the root device's device path. */ -- dev = grub_device_open (0); -+ /* Get the device path from filename. */ -+ char *devname = grub_file_get_device_name (filename); -+ dev = grub_device_open (devname); -+ if (devname) -+ grub_free (devname); - if (! dev) - goto fail; - -@@ -283,17 +995,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - if (! file_path) - goto fail; - -- grub_printf ("file path: "); -- grub_efi_print_device_path (file_path); -- -- size = grub_file_size (file); -- if (!size) -+ fsize = grub_file_size (file); -+ if (!fsize) - { - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - goto fail; - } -- pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12); -+ pages = (((grub_efi_uintn_t) fsize + ((1 << 12) - 1)) >> 12); - - status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, - GRUB_EFI_LOADER_CODE, -@@ -307,7 +1016,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - } - - boot_image = (void *) ((grub_addr_t) address); -- if (grub_file_read (file, boot_image, size) != size) -+ if (grub_file_read (file, boot_image, fsize) != fsize) - { - if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -@@ -317,7 +1026,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - } - - #if defined (__i386__) || defined (__x86_64__) -- if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header)) -+ if (fsize >= (grub_ssize_t) sizeof (struct grub_macho_fat_header)) - { - struct grub_macho_fat_header *head = boot_image; - if (head->magic -@@ -326,6 +1035,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_uint32_t i; - struct grub_macho_fat_arch *archs - = (struct grub_macho_fat_arch *) (head + 1); -+ -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ { -+ grub_error (GRUB_ERR_BAD_OS, -+ "MACHO binaries are forbidden with Secure Boot"); -+ goto fail; -+ } -+ - for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++) - { - if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype)) -@@ -340,79 +1057,39 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - > ~grub_cpu_to_le32 (archs[i].size) - || grub_cpu_to_le32 (archs[i].offset) - + grub_cpu_to_le32 (archs[i].size) -- > (grub_size_t) size) -+ > (grub_size_t) fsize) - { - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - goto fail; - } - boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset); -- size = grub_cpu_to_le32 (archs[i].size); -+ fsize = grub_cpu_to_le32 (archs[i].size); - } - } - #endif - -- status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, -- boot_image, size, -- &image_handle); -- if (status != GRUB_EFI_SUCCESS) -+ rc = grub_linuxefi_secure_validate((void *)(unsigned long)address, fsize); -+ grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc); -+ if (rc > 0) - { -- if (status == GRUB_EFI_OUT_OF_RESOURCES) -- grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); -- else -- grub_error (GRUB_ERR_BAD_OS, "cannot load image"); -- -- goto fail; -+ grub_file_close (file); -+ grub_device_close (dev); -+ grub_loader_set (grub_secureboot_chainloader_boot, -+ grub_secureboot_chainloader_unload, 0); -+ return 0; - } -- -- /* LoadImage does not set a device handler when the image is -- loaded from memory, so it is necessary to set it explicitly here. -- This is a mess. */ -- loaded_image = grub_efi_get_loaded_image (image_handle); -- if (! loaded_image) -+ else if (rc == 0) - { -- grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); -- goto fail; -- } -- loaded_image->device_handle = dev_handle; -- -- if (argc > 1) -- { -- int i, len; -- grub_efi_char16_t *p16; -- -- for (i = 1, len = 0; i < argc; i++) -- len += grub_strlen (argv[i]) + 1; -- -- len *= sizeof (grub_efi_char16_t); -- cmdline = p16 = grub_malloc (len); -- if (! cmdline) -- goto fail; -+ grub_load_and_start_image(boot_image); -+ grub_file_close (file); -+ grub_device_close (dev); -+ grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); - -- for (i = 1; i < argc; i++) -- { -- char *p8; -- -- p8 = argv[i]; -- while (*p8) -- *(p16++) = *(p8++); -- -- *(p16++) = ' '; -- } -- *(--p16) = 0; -- -- loaded_image->load_options = cmdline; -- loaded_image->load_options_size = len; -+ return 0; - } - -- grub_file_close (file); -- grub_device_close (dev); -- -- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); -- return 0; -- -- fail: -- -+fail: - if (dev) - grub_device_close (dev); - -@@ -424,6 +1101,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - if (address) - efi_call_2 (b->free_pages, address, pages); - -+ if (cmdline) -+ grub_free (cmdline); -+ - grub_dl_unref (my_mod); - - return grub_errno; -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index c24202a5dd1..c8ecce6dfd0 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -33,21 +33,34 @@ struct grub_efi_shim_lock - }; - typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; - --grub_efi_boolean_t -+int - grub_linuxefi_secure_validate (void *data, grub_uint32_t size) - { - grub_efi_guid_t guid = SHIM_LOCK_GUID; - grub_efi_shim_lock_t *shim_lock; -+ grub_efi_status_t status; - - shim_lock = grub_efi_locate_protocol(&guid, NULL); -- -+ grub_dprintf ("secureboot", "shim_lock: %p\n", shim_lock); - if (!shim_lock) -- return 1; -+ { -+ grub_dprintf ("secureboot", "shim not available\n"); -+ return 0; -+ } - -- if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS) -- return 1; -+ grub_dprintf ("secureboot", "Asking shim to verify kernel signature\n"); -+ status = shim_lock->verify (data, size); -+ grub_dprintf ("secureboot", "shim_lock->verify(): %ld\n", (long int)status); -+ if (status == GRUB_EFI_SUCCESS) -+ { -+ grub_dprintf ("secureboot", "Kernel signature verification passed\n"); -+ return 1; -+ } - -- return 0; -+ grub_dprintf ("secureboot", "Kernel signature verification failed (0x%lx)\n", -+ (unsigned long) status); -+ -+ return -1; - } - - #pragma GCC diagnostic push -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index bb2616a8092..6b24cbb9483 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -117,6 +117,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_dprintf ("linux", "initrd_mem = %lx\n", (unsigned long) initrd_mem); -+ - params->ramdisk_size = size; - params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem; - -@@ -159,6 +161,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - struct linux_i386_kernel_header lh; - grub_ssize_t len, start, filelen; - void *kernel = NULL; -+ int rc; - - grub_dl_ref (my_mod); - -@@ -184,11 +187,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - if (grub_file_read (file, kernel, filelen) != filelen) - { -- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), -+ argv[0]); - goto fail; - } - -- if (! grub_linuxefi_secure_validate (kernel, filelen)) -+ rc = grub_linuxefi_secure_validate (kernel, filelen); -+ if (rc < 0) - { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), - argv[0]); -@@ -203,6 +208,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_dprintf ("linux", "params = %lx\n", (unsigned long) params); -+ - grub_memset (params, 0, 16384); - - grub_memcpy (&lh, kernel, sizeof (lh)); -@@ -241,6 +248,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_dprintf ("linux", "linux_cmdline = %lx\n", -+ (unsigned long)linux_cmdline); -+ - grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - linux_cmdline + sizeof (LINUX_IMAGE) - 1, -@@ -275,9 +285,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_memcpy (params, &lh, 2 * 512); - - params->type_of_loader = 0x21; -+ grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n", -+ kernel_mem, handover_offset); - - fail: -- - if (file) - grub_file_close (file); - -diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h -index d9ede36773b..0033d9305a9 100644 ---- a/include/grub/efi/linux.h -+++ b/include/grub/efi/linux.h -@@ -22,7 +22,7 @@ - #include - #include - --grub_efi_boolean_t -+int - EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size); - grub_err_t - EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset, -diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h -index 0ed8781f037..a43adf27464 100644 ---- a/include/grub/efi/pe32.h -+++ b/include/grub/efi/pe32.h -@@ -223,7 +223,11 @@ struct grub_pe64_optional_header - struct grub_pe32_section_table - { - char name[8]; -- grub_uint32_t virtual_size; -+ union -+ { -+ grub_uint32_t physical_address; -+ grub_uint32_t virtual_size; -+ }; - grub_uint32_t virtual_address; - grub_uint32_t raw_data_size; - grub_uint32_t raw_data_offset; -@@ -234,12 +238,18 @@ struct grub_pe32_section_table - grub_uint32_t characteristics; - }; - -+#define GRUB_PE32_SCN_TYPE_NO_PAD 0x00000008 - #define GRUB_PE32_SCN_CNT_CODE 0x00000020 - #define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040 --#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000 --#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000 --#define GRUB_PE32_SCN_MEM_READ 0x40000000 --#define GRUB_PE32_SCN_MEM_WRITE 0x80000000 -+#define GRUB_PE32_SCN_CNT_UNINITIALIZED_DATA 0x00000080 -+#define GRUB_PE32_SCN_LNK_OTHER 0x00000100 -+#define GRUB_PE32_SCN_LNK_INFO 0x00000200 -+#define GRUB_PE32_SCN_LNK_REMOVE 0x00000800 -+#define GRUB_PE32_SCN_LNK_COMDAT 0x00001000 -+#define GRUB_PE32_SCN_GPREL 0x00008000 -+#define GRUB_PE32_SCN_MEM_16BIT 0x00020000 -+#define GRUB_PE32_SCN_MEM_LOCKED 0x00040000 -+#define GRUB_PE32_SCN_MEM_PRELOAD 0x00080000 - - #define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000 - #define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000 -@@ -248,10 +258,28 @@ struct grub_pe32_section_table - #define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000 - #define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000 - #define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000 -+#define GRUB_PE32_SCN_ALIGN_128BYTES 0x00800000 -+#define GRUB_PE32_SCN_ALIGN_256BYTES 0x00900000 -+#define GRUB_PE32_SCN_ALIGN_512BYTES 0x00A00000 -+#define GRUB_PE32_SCN_ALIGN_1024BYTES 0x00B00000 -+#define GRUB_PE32_SCN_ALIGN_2048BYTES 0x00C00000 -+#define GRUB_PE32_SCN_ALIGN_4096BYTES 0x00D00000 -+#define GRUB_PE32_SCN_ALIGN_8192BYTES 0x00E00000 - - #define GRUB_PE32_SCN_ALIGN_SHIFT 20 - #define GRUB_PE32_SCN_ALIGN_MASK 7 - -+#define GRUB_PE32_SCN_LNK_NRELOC_OVFL 0x01000000 -+#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000 -+#define GRUB_PE32_SCN_MEM_NOT_CACHED 0x04000000 -+#define GRUB_PE32_SCN_MEM_NOT_PAGED 0x08000000 -+#define GRUB_PE32_SCN_MEM_SHARED 0x10000000 -+#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000 -+#define GRUB_PE32_SCN_MEM_READ 0x40000000 -+#define GRUB_PE32_SCN_MEM_WRITE 0x80000000 -+ -+ -+ - #define GRUB_PE32_SIGNATURE_SIZE 4 - - struct grub_pe32_header -@@ -274,6 +302,20 @@ struct grub_pe32_header - #endif - }; - -+struct grub_pe32_header_32 -+{ -+ char signature[GRUB_PE32_SIGNATURE_SIZE]; -+ struct grub_pe32_coff_header coff_header; -+ struct grub_pe32_optional_header optional_header; -+}; -+ -+struct grub_pe32_header_64 -+{ -+ char signature[GRUB_PE32_SIGNATURE_SIZE]; -+ struct grub_pe32_coff_header coff_header; -+ struct grub_pe64_optional_header optional_header; -+}; -+ - struct grub_pe32_fixup_block - { - grub_uint32_t page_rva; diff --git a/0008-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch b/0008-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch deleted file mode 100644 index 030c71c..0000000 --- a/0008-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch +++ /dev/null @@ -1,390 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 6 Oct 2015 16:09:25 -0400 -Subject: [PATCH] Make any of the loaders that link in efi mode honor secure - boot. - -And in this case "honor" means "even if somebody does link this in, they -won't register commands if SB is enabled." - -Signed-off-by: Peter Jones ---- - grub-core/commands/iorw.c | 7 +++++++ - grub-core/commands/memrw.c | 7 +++++++ - grub-core/kern/dl.c | 3 ++- - grub-core/kern/efi/efi.c | 34 ---------------------------------- - grub-core/loader/efi/appleloader.c | 7 +++++++ - grub-core/loader/efi/chainloader.c | 1 + - grub-core/loader/i386/bsd.c | 7 +++++++ - grub-core/loader/i386/linux.c | 7 +++++++ - grub-core/loader/i386/pc/linux.c | 7 +++++++ - grub-core/loader/multiboot.c | 7 +++++++ - grub-core/loader/xnu.c | 7 +++++++ - include/grub/efi/efi.h | 1 - - include/grub/ia64/linux.h | 0 - include/grub/mips/linux.h | 0 - include/grub/powerpc/linux.h | 0 - include/grub/sparc64/linux.h | 0 - 16 files changed, 59 insertions(+), 36 deletions(-) - create mode 100644 include/grub/ia64/linux.h - create mode 100644 include/grub/mips/linux.h - create mode 100644 include/grub/powerpc/linux.h - create mode 100644 include/grub/sparc64/linux.h - -diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c -index 584baec8f91..7b2999b14b5 100644 ---- a/grub-core/commands/iorw.c -+++ b/grub-core/commands/iorw.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -119,6 +120,9 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) - - GRUB_MOD_INIT(memrw) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_read_byte = - grub_register_extcmd ("inb", grub_cmd_read, 0, - N_("PORT"), N_("Read 8-bit value from PORT."), -@@ -147,6 +151,9 @@ GRUB_MOD_INIT(memrw) - - GRUB_MOD_FINI(memrw) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_extcmd (cmd_read_byte); - grub_unregister_extcmd (cmd_read_word); - grub_unregister_extcmd (cmd_read_dword); -diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c -index d401a6db0ef..39cf3a06dbd 100644 ---- a/grub-core/commands/memrw.c -+++ b/grub-core/commands/memrw.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -121,6 +122,9 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) - - GRUB_MOD_INIT(memrw) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_read_byte = - grub_register_extcmd ("read_byte", grub_cmd_read, 0, - N_("ADDR"), N_("Read 8-bit value from ADDR."), -@@ -149,6 +153,9 @@ GRUB_MOD_INIT(memrw) - - GRUB_MOD_FINI(memrw) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_extcmd (cmd_read_byte); - grub_unregister_extcmd (cmd_read_word); - grub_unregister_extcmd (cmd_read_dword); -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index b7149370950..7afb9e6f724 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - /* Platforms where modules are in a readonly area of memory. */ - #if defined(GRUB_MACHINE_QEMU) -@@ -704,7 +705,7 @@ grub_dl_load_file (const char *filename) - grub_dl_t mod = 0; - - #ifdef GRUB_MACHINE_EFI -- if (grub_efi_secure_boot ()) -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { - #if 0 - /* This is an error, but grub2-mkconfig still generates a pile of -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 4a2259aa1c7..8cff7be0289 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -286,40 +286,6 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, - return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL); - } - --grub_efi_boolean_t --grub_efi_secure_boot (void) --{ -- grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; -- grub_size_t datasize; -- char *secure_boot = NULL; -- char *setup_mode = NULL; -- grub_efi_boolean_t ret = 0; -- -- secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); -- if (datasize != 1 || !secure_boot) -- { -- grub_dprintf ("secureboot", "No SecureBoot variable\n"); -- goto out; -- } -- grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot); -- -- setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); -- if (datasize != 1 || !setup_mode) -- { -- grub_dprintf ("secureboot", "No SetupMode variable\n"); -- goto out; -- } -- grub_dprintf ("secureboot", "SetupMode: %d\n", *setup_mode); -- -- if (*secure_boot && !*setup_mode) -- ret = 1; -- -- out: -- grub_free (secure_boot); -- grub_free (setup_mode); -- return ret; --} -- - #pragma GCC diagnostic ignored "-Wcast-align" - - /* Search the mods section from the PE32/PE32+ image. This code uses -diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c -index 74888c463ba..585f2b57385 100644 ---- a/grub-core/loader/efi/appleloader.c -+++ b/grub-core/loader/efi/appleloader.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -227,6 +228,9 @@ static grub_command_t cmd; - - GRUB_MOD_INIT(appleloader) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd = grub_register_command ("appleloader", grub_cmd_appleloader, - N_("[OPTS]"), - /* TRANSLATORS: This command is used on EFI to -@@ -238,5 +242,8 @@ GRUB_MOD_INIT(appleloader) - - GRUB_MOD_FINI(appleloader) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_command (cmd); - } -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index e6a8d4ad0e9..07c4937898d 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c -index 5f3290ce17b..54befc26626 100644 ---- a/grub-core/loader/i386/bsd.c -+++ b/grub-core/loader/i386/bsd.c -@@ -40,6 +40,7 @@ - #ifdef GRUB_MACHINE_PCBIOS - #include - #endif -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -2137,6 +2138,9 @@ static grub_command_t cmd_netbsd_module_elf, cmd_openbsd_ramdisk; - - GRUB_MOD_INIT (bsd) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - /* Net and OpenBSD kernels are often compressed. */ - grub_dl_load ("gzio"); - -@@ -2176,6 +2180,9 @@ GRUB_MOD_INIT (bsd) - - GRUB_MOD_FINI (bsd) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_extcmd (cmd_freebsd); - grub_unregister_extcmd (cmd_openbsd); - grub_unregister_extcmd (cmd_netbsd); -diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index dccf3bb3005..4aeb0e4b9a6 100644 ---- a/grub-core/loader/i386/linux.c -+++ b/grub-core/loader/i386/linux.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -1138,6 +1139,9 @@ static grub_command_t cmd_linux, cmd_initrd; - - GRUB_MOD_INIT(linux) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_linux = grub_register_command ("linux", grub_cmd_linux, - 0, N_("Load Linux.")); - cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, -@@ -1147,6 +1151,9 @@ GRUB_MOD_INIT(linux) - - GRUB_MOD_FINI(linux) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_initrd); - } -diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c -index 4b1750e360e..e3fa1221e81 100644 ---- a/grub-core/loader/i386/pc/linux.c -+++ b/grub-core/loader/i386/pc/linux.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -487,6 +488,9 @@ static grub_command_t cmd_linux, cmd_linux16, cmd_initrd, cmd_initrd16; - - GRUB_MOD_INIT(linux16) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_linux = - grub_register_command ("linux", grub_cmd_linux, - 0, N_("Load Linux.")); -@@ -504,6 +508,9 @@ GRUB_MOD_INIT(linux16) - - GRUB_MOD_FINI(linux16) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_linux16); - grub_unregister_command (cmd_initrd); -diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c -index facb13f3d36..47e481f4576 100644 ---- a/grub-core/loader/multiboot.c -+++ b/grub-core/loader/multiboot.c -@@ -50,6 +50,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -444,6 +445,9 @@ static grub_command_t cmd_multiboot, cmd_module; - - GRUB_MOD_INIT(multiboot) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_multiboot = - #ifdef GRUB_USE_MULTIBOOT2 - grub_register_command ("multiboot2", grub_cmd_multiboot, -@@ -464,6 +468,9 @@ GRUB_MOD_INIT(multiboot) - - GRUB_MOD_FINI(multiboot) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_command (cmd_multiboot); - grub_unregister_command (cmd_module); - } -diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c -index 1c0cf6a430a..baa54e652ab 100644 ---- a/grub-core/loader/xnu.c -+++ b/grub-core/loader/xnu.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -1497,6 +1498,9 @@ static grub_extcmd_t cmd_splash; - - GRUB_MOD_INIT(xnu) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0, - N_("Load XNU image.")); - cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64, -@@ -1540,6 +1544,9 @@ GRUB_MOD_INIT(xnu) - - GRUB_MOD_FINI(xnu) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - #ifndef GRUB_MACHINE_EMU - grub_unregister_command (cmd_resume); - #endif -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 6295df85f3f..585fa6662b6 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -91,7 +91,6 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, - const grub_efi_guid_t *guid, - void *data, - grub_size_t datasize); --grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); - int - EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, - const grub_efi_device_path_t *dp2); -diff --git a/include/grub/ia64/linux.h b/include/grub/ia64/linux.h -new file mode 100644 -index 00000000000..e69de29bb2d -diff --git a/include/grub/mips/linux.h b/include/grub/mips/linux.h -new file mode 100644 -index 00000000000..e69de29bb2d -diff --git a/include/grub/powerpc/linux.h b/include/grub/powerpc/linux.h -new file mode 100644 -index 00000000000..e69de29bb2d -diff --git a/include/grub/sparc64/linux.h b/include/grub/sparc64/linux.h -new file mode 100644 -index 00000000000..e69de29bb2d diff --git a/0009-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch b/0009-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch deleted file mode 100644 index f3aae38..0000000 --- a/0009-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch +++ /dev/null @@ -1,264 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 8 Jul 2019 12:32:37 +0200 -Subject: [PATCH] Handle multi-arch (64-on-32) boot in linuxefi loader. - -Allow booting 64-bit kernels on 32-bit EFI on x86. - -Signed-off-by: Peter Jones ---- - grub-core/loader/efi/linux.c | 9 +++- - grub-core/loader/i386/efi/linux.c | 110 ++++++++++++++++++++++++++------------ - include/grub/i386/linux.h | 7 ++- - 3 files changed, 89 insertions(+), 37 deletions(-) - -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index c8ecce6dfd0..0622dfa48d4 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -69,12 +69,17 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size) - typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *); - - grub_err_t --grub_efi_linux_boot (void *kernel_addr, grub_off_t offset, -+grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, - void *kernel_params) - { - handover_func hf; -+ int offset = 0; - -- hf = (handover_func)((char *)kernel_addr + offset); -+#ifdef __x86_64__ -+ offset = 512; -+#endif -+ -+ hf = (handover_func)((char *)kernel_addr + handover_offset + offset); - hf (grub_efi_image_handle, grub_efi_system_table, kernel_params); - - return GRUB_ERR_BUG; -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 6b24cbb9483..3017d0f3e52 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -44,14 +44,10 @@ static char *linux_cmdline; - static grub_err_t - grub_linuxefi_boot (void) - { -- int offset = 0; -- --#ifdef __x86_64__ -- offset = 512; --#endif - asm volatile ("cli"); - -- return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset, -+ return grub_efi_linux_boot ((char *)kernel_mem, -+ handover_offset, - params); - } - -@@ -153,14 +149,20 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - return grub_errno; - } - -+#define MIN(a, b) \ -+ ({ typeof (a) _a = (a); \ -+ typeof (b) _b = (b); \ -+ _a < _b ? _a : _b; }) -+ - static grub_err_t - grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) - { - grub_file_t file = 0; -- struct linux_i386_kernel_header lh; -- grub_ssize_t len, start, filelen; -+ struct linux_i386_kernel_header *lh = NULL; -+ grub_ssize_t start, filelen; - void *kernel = NULL; -+ int setup_header_end_offset; - int rc; - - grub_dl_ref (my_mod); -@@ -200,48 +202,79 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); -- -+ params = grub_efi_allocate_pages_max (0x3fffffff, -+ BYTES_TO_PAGES(sizeof(*params))); - if (! params) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); - goto fail; - } - -- grub_dprintf ("linux", "params = %lx\n", (unsigned long) params); -+ grub_dprintf ("linux", "params = %p\n", params); - -- grub_memset (params, 0, 16384); -+ grub_memset (params, 0, sizeof(*params)); - -- grub_memcpy (&lh, kernel, sizeof (lh)); -- -- if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) -+ setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); -+ grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", -+ MIN((grub_size_t)0x202+setup_header_end_offset, -+ sizeof (*params)) - 0x1f1, -+ (grub_uint8_t *)kernel + 0x1f1, -+ (grub_uint8_t *)params + 0x1f1); -+ grub_memcpy ((grub_uint8_t *)params + 0x1f1, -+ (grub_uint8_t *)kernel + 0x1f1, -+ MIN((grub_size_t)0x202+setup_header_end_offset,sizeof (*params)) - 0x1f1); -+ lh = (struct linux_i386_kernel_header *)params; -+ grub_dprintf ("linux", "lh is at %p\n", lh); -+ grub_dprintf ("linux", "checking lh->boot_flag\n"); -+ if (lh->boot_flag != grub_cpu_to_le16 (0xaa55)) - { - grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); - goto fail; - } - -- if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) -+ grub_dprintf ("linux", "checking lh->setup_sects\n"); -+ if (lh->setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) - { - grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); - goto fail; - } - -- if (lh.version < grub_cpu_to_le16 (0x020b)) -+ grub_dprintf ("linux", "checking lh->version\n"); -+ if (lh->version < grub_cpu_to_le16 (0x020b)) - { - grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); - goto fail; - } - -- if (!lh.handover_offset) -+ grub_dprintf ("linux", "checking lh->handover_offset\n"); -+ if (!lh->handover_offset) - { - grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); - goto fail; - } - -+#if defined(__x86_64__) || defined(__aarch64__) -+ grub_dprintf ("linux", "checking lh->xloadflags\n"); -+ if (!(lh->xloadflags & LINUX_XLF_KERNEL_64)) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support 64-bit CPUs")); -+ goto fail; -+ } -+#endif -+ -+#if defined(__i386__) -+ if ((lh->xloadflags & LINUX_XLF_KERNEL_64) && -+ !(lh->xloadflags & LINUX_XLF_EFI_HANDOVER_32)) -+ { -+ grub_error (GRUB_ERR_BAD_OS, -+ N_("kernel doesn't support 32-bit handover")); -+ goto fail; -+ } -+#endif -+ - grub_dprintf ("linux", "setting up cmdline\n"); - linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, -- BYTES_TO_PAGES(lh.cmdline_size + 1)); -- -+ BYTES_TO_PAGES(lh->cmdline_size + 1)); - if (!linux_cmdline) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); -@@ -254,22 +287,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - linux_cmdline + sizeof (LINUX_IMAGE) - 1, -- lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1), -+ lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1), - GRUB_VERIFY_KERNEL_CMDLINE); - -- lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; -+ grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); -+ grub_dprintf ("linux", "setting lh->cmd_line_ptr\n"); -+ lh->cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; - -- handover_offset = lh.handover_offset; -+ grub_dprintf ("linux", "computing handover offset\n"); -+ handover_offset = lh->handover_offset; - -- start = (lh.setup_sects + 1) * 512; -- len = grub_file_size(file) - start; -+ start = (lh->setup_sects + 1) * 512; - -- kernel_mem = grub_efi_allocate_pages_max(lh.pref_address, -- BYTES_TO_PAGES(lh.init_size)); -+ kernel_mem = grub_efi_allocate_pages_max(lh->pref_address, -+ BYTES_TO_PAGES(lh->init_size)); - - if (!kernel_mem) - kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, -- BYTES_TO_PAGES(lh.init_size)); -+ BYTES_TO_PAGES(lh->init_size)); - - if (!kernel_mem) - { -@@ -277,14 +312,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- grub_memcpy (kernel_mem, (char *)kernel + start, len); -+ grub_dprintf ("linux", "kernel_mem = %lx\n", (unsigned long) kernel_mem); -+ - grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); - loaded=1; -+ grub_dprintf ("linux", "setting lh->code32_start to %p\n", kernel_mem); -+ lh->code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; - -- lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; -- grub_memcpy (params, &lh, 2 * 512); -+ grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start); - -- params->type_of_loader = 0x21; -+ grub_dprintf ("linux", "setting lh->type_of_loader\n"); -+ lh->type_of_loader = 0x6; -+ -+ grub_dprintf ("linux", "setting lh->ext_loader_{type,ver}\n"); -+ params->ext_loader_type = 0; -+ params->ext_loader_ver = 2; - grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n", - kernel_mem, handover_offset); - -@@ -301,10 +343,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - loaded = 0; - } - -- if (linux_cmdline && !loaded) -+ if (linux_cmdline && lh && !loaded) - grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) - linux_cmdline, -- BYTES_TO_PAGES(lh.cmdline_size + 1)); -+ BYTES_TO_PAGES(lh->cmdline_size + 1)); - - if (kernel_mem && !loaded) - grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h -index eddf9251d9a..25ef52c04eb 100644 ---- a/include/grub/i386/linux.h -+++ b/include/grub/i386/linux.h -@@ -138,7 +138,12 @@ struct linux_i386_kernel_header - grub_uint32_t kernel_alignment; - grub_uint8_t relocatable; - grub_uint8_t min_alignment; -- grub_uint8_t pad[2]; -+#define LINUX_XLF_KERNEL_64 (1<<0) -+#define LINUX_XLF_CAN_BE_LOADED_ABOVE_4G (1<<1) -+#define LINUX_XLF_EFI_HANDOVER_32 (1<<2) -+#define LINUX_XLF_EFI_HANDOVER_64 (1<<3) -+#define LINUX_XLF_EFI_KEXEC (1<<4) -+ grub_uint16_t xloadflags; - grub_uint32_t cmdline_size; - grub_uint32_t hardware_subarch; - grub_uint64_t hardware_subarch_data; diff --git a/0010-re-write-.gitignore.patch b/0010-re-write-.gitignore.patch deleted file mode 100644 index 74cb0da..0000000 --- a/0010-re-write-.gitignore.patch +++ /dev/null @@ -1,248 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 8 Jul 2019 12:55:29 +0200 -Subject: [PATCH] re-write .gitignore - ---- - .gitignore | 152 ++++++++++++++++++++++++++++++++++++++ - docs/.gitignore | 5 ++ - grub-core/.gitignore | 16 ++++ - grub-core/lib/.gitignore | 1 + - include/grub/gcrypt/.gitignore | 2 + - po/.gitignore | 5 ++ - util/bash-completion.d/.gitignore | 2 + - 7 files changed, 183 insertions(+) - create mode 100644 docs/.gitignore - create mode 100644 grub-core/.gitignore - create mode 100644 grub-core/lib/.gitignore - create mode 100644 include/grub/gcrypt/.gitignore - create mode 100644 po/.gitignore - create mode 100644 util/bash-completion.d/.gitignore - -diff --git a/.gitignore b/.gitignore -index f6a1bd05175..594d0134d33 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -275,3 +275,155 @@ widthspec.bin - /xfs_test - /xzcompress_test - /zfs_test -+======= -+# things ./autogen.sh will create -+/Makefile.utilgcry.def -+/ABOUT-NLS -+/aclocal.m4 -+/autom4te.cache -+/build-aux -+/configure -+/gnulib -+/grub-core/lib/gnulib/ -+/Makefile -+ -+# things very common editors create that we never want -+*~ -+.*.sw? -+*.patch -+ -+# stuff you're likely to make while building test trees -+grub.cfg -+/build*/ -+ -+# built objects across the whole tree -+Makefile.in -+*.a -+*.am -+*.efi -+*.exec -+*.image -+*.img -+*.info -+*.lst -+*.marker -+/m4 -+*.mod -+*.module -+*.o -+*.pf2 -+*.yy.[ch] -+.deps/ -+.deps-core/ -+.deps-util/ -+.dirstamp -+ -+# next are things you get if you do ./configure in the topdir (for e.g. -+# "make dist" invocation. -+/config-util.h -+/config.h -+/include/grub/cpu -+/include/grub/machine -+/INSTALL -+/INSTALL.grub -+/po/Makefile.in.in -+/po/Makevars -+/po/Makevars.template -+/po/POTFILES -+/po/Rules-quot -+/stamp-h -+/stamp-h1 -+bootstrap.log -+config.log -+config.status -+ -+# stuff "make dist" creates -+ChangeLog -+grub-*.tar -+grub-*.tar.* -+ -+# stuff "make" creates -+/[[:digit:]][[:digit:]]_?* -+/ascii.h -+/build-grub-gen-asciih -+/build-grub-gen-widthspec -+/build-grub-mkfont -+/config-util.h.in -+/garbage-gen -+/grub*-bios-setup -+/grub*-bios-setup.8 -+/grub*-editenv -+/grub*-editenv.1 -+/grub*-file -+/grub*-file.1 -+/grub*-fs-tester -+/grub*-fstest -+/grub*-fstest.1 -+/grub*-get-kernel-settings -+/grub*-get-kernel-settings.3 -+/grub*-glue-efi -+/grub*-glue-efi.1 -+/grub*-install -+/grub*-install.8 -+/grub*-kbdcomp -+/grub*-kbdcomp.1 -+/grub*-macbless -+/grub*-macbless.8 -+/grub*-menulst2cfg -+/grub*-menulst2cfg.1 -+/grub*-mount -+/grub*-mount.1 -+/grub*-mkconfig -+/grub*-mkconfig.8 -+/grub*-mkconfig_lib -+/grub*-mkfont -+/grub*-mkfont.1 -+/grub*-mkimage -+/grub*-mkimage.1 -+/grub*-mklayout -+/grub*-mklayout.1 -+/grub*-mknetdir -+/grub*-mknetdir.1 -+/grub*-mkpasswd-pbkdf2 -+/grub*-mkpasswd-pbkdf2.1 -+/grub*-mkrelpath -+/grub*-mkrelpath.1 -+/grub*-mkrescue -+/grub*-mkrescue.1 -+/grub*-mkstandalone -+/grub*-mkstandalone.1 -+/grub*-ofpathname -+/grub*-ofpathname.8 -+/grub*-probe -+/grub*-probe.8 -+/grub*-reboot -+/grub*-reboot.8 -+/grub*-render-label -+/grub*-render-label.1 -+/grub*-rpm-sort -+/grub*-rpm-sort.8 -+/grub*-script-check -+/grub*-script-check.1 -+/grub*-set-bootflag -+/grub*-set-bootflag.1 -+/grub*-set-default -+/grub*-set-default.8 -+/grub*-set-password -+/grub*-set-password.8 -+/grub*-shell -+/grub*-shell-tester -+/grub*-sparc64-setup -+/grub*-sparc64-setup.8 -+/grub*-syslinux2cfg -+/grub*-syslinux2cfg.1 -+/grub*-switch-to-blscfg -+/grub*-switch-to-blscfg.8 -+/grub_fstest.pp -+/grub_fstest_init.c -+/grub_fstest_init.lst -+/grub_script.tab.[ch] -+/libgrub.pp -+/libgrub_a_init.c -+/libgrub_a_init.lst -+/stamp-h.in -+/widthspec.h -diff --git a/docs/.gitignore b/docs/.gitignore -new file mode 100644 -index 00000000000..e1d849ef95b ---- /dev/null -+++ b/docs/.gitignore -@@ -0,0 +1,5 @@ -+/*.in -+/Makefile -+/stamp-1 -+/stamp-vti -+/version*.texi -diff --git a/grub-core/.gitignore b/grub-core/.gitignore -new file mode 100644 -index 00000000000..2acce281159 ---- /dev/null -+++ b/grub-core/.gitignore -@@ -0,0 +1,16 @@ -+/*.lst -+/Makefile -+/Makefile.gcry.def -+/unidata.c -+/build-grub-module-verifier -+/gdb_grub -+/genmod.sh -+/gensyminfo.sh -+/gentrigtables -+/gmodule.pl -+/grub_script.tab.[ch] -+/modinfo.sh -+/rs_decoder.h -+/symlist.c -+/symlist.h -+/trigtables.c -diff --git a/grub-core/lib/.gitignore b/grub-core/lib/.gitignore -new file mode 100644 -index 00000000000..68154591404 ---- /dev/null -+++ b/grub-core/lib/.gitignore -@@ -0,0 +1 @@ -+/libgcrypt-grub/ -diff --git a/include/grub/gcrypt/.gitignore b/include/grub/gcrypt/.gitignore -new file mode 100644 -index 00000000000..8fbf5646246 ---- /dev/null -+++ b/include/grub/gcrypt/.gitignore -@@ -0,0 +1,2 @@ -+g10lib.h -+gcrypt.h -diff --git a/po/.gitignore b/po/.gitignore -new file mode 100644 -index 00000000000..f507e7741e3 ---- /dev/null -+++ b/po/.gitignore -@@ -0,0 +1,5 @@ -+/Makefile -+/POTFILES*.in -+/grub.pot -+/remove-potcdate.sed -+/stamp-po -diff --git a/util/bash-completion.d/.gitignore b/util/bash-completion.d/.gitignore -new file mode 100644 -index 00000000000..6813a527ad3 ---- /dev/null -+++ b/util/bash-completion.d/.gitignore -@@ -0,0 +1,2 @@ -+Makefile -+grub diff --git a/0011-IBM-client-architecture-CAS-reboot-support.patch b/0011-IBM-client-architecture-CAS-reboot-support.patch deleted file mode 100644 index 431a443..0000000 --- a/0011-IBM-client-architecture-CAS-reboot-support.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Thu, 20 Sep 2012 18:07:39 -0300 -Subject: [PATCH] IBM client architecture (CAS) reboot support - -This is an implementation of IBM client architecture (CAS) reboot for GRUB. - -There are cases where the POWER firmware must reboot in order to support -specific features requested by a kernel. The kernel calls -ibm,client-architecture-support and it may either return or reboot with -the new feature set. eg: - -Calling ibm,client-architecture-support.../ -Elapsed time since release of system processors: 70959 mins 50 secs -Welcome to GRUB! - -Instead of return to the GRUB menu, it will check if the flag for CAS -reboot is set. If so, grub will automatically boot the last booted -kernel using the same parameters - -Signed-off-by: Paulo Flabiano Smorigo -[rharwood@redhat.com: commit message rewrap] -Signed-off-by: Robbie Harwood ---- - grub-core/kern/ieee1275/openfw.c | 63 ++++++++++++++++++++++++++++++++++++++++ - grub-core/normal/main.c | 19 ++++++++++++ - grub-core/script/execute.c | 7 +++++ - include/grub/ieee1275/ieee1275.h | 2 ++ - 4 files changed, 91 insertions(+) - -diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c -index 4d493ab7661..3a6689abb11 100644 ---- a/grub-core/kern/ieee1275/openfw.c -+++ b/grub-core/kern/ieee1275/openfw.c -@@ -591,3 +591,66 @@ grub_ieee1275_get_boot_dev (void) - - return bootpath; - } -+ -+/* Check if it's a CAS reboot. If so, set the script to be executed. */ -+int -+grub_ieee1275_cas_reboot (char *script) -+{ -+ grub_uint32_t ibm_ca_support_reboot; -+ grub_uint32_t ibm_fw_nbr_reboots; -+ char property_value[10]; -+ grub_ssize_t actual; -+ grub_ieee1275_ihandle_t options; -+ -+ if (grub_ieee1275_finddevice ("/options", &options) < 0) -+ return -1; -+ -+ /* Check two properties, one is enough to get cas reboot value */ -+ ibm_ca_support_reboot = 0; -+ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, -+ "ibm,client-architecture-support-reboot", -+ &ibm_ca_support_reboot, -+ sizeof (ibm_ca_support_reboot), -+ &actual) >= 0) -+ grub_dprintf("ieee1275", "ibm,client-architecture-support-reboot: %u\n", -+ ibm_ca_support_reboot); -+ -+ ibm_fw_nbr_reboots = 0; -+ if (grub_ieee1275_get_property (options, "ibm,fw-nbr-reboots", -+ property_value, sizeof (property_value), -+ &actual) >= 0) -+ { -+ property_value[sizeof (property_value) - 1] = 0; -+ ibm_fw_nbr_reboots = (grub_uint8_t) grub_strtoul (property_value, 0, 10); -+ grub_dprintf("ieee1275", "ibm,fw-nbr-reboots: %u\n", ibm_fw_nbr_reboots); -+ } -+ -+ if (ibm_ca_support_reboot || ibm_fw_nbr_reboots) -+ { -+ if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual)) -+ { -+ if (actual > 1024) -+ script = grub_realloc (script, actual + 1); -+ grub_ieee1275_get_property (options, "boot-last-label", script, actual, -+ &actual); -+ return 0; -+ } -+ } -+ -+ grub_ieee1275_set_boot_last_label (""); -+ -+ return -1; -+} -+ -+int grub_ieee1275_set_boot_last_label (const char *text) -+{ -+ grub_ieee1275_ihandle_t options; -+ grub_ssize_t actual; -+ -+ grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text)); -+ if (! grub_ieee1275_finddevice ("/options", &options) && -+ options != (grub_ieee1275_ihandle_t) -1) -+ grub_ieee1275_set_property (options, "boot-last-label", text, -+ grub_strlen (text), &actual); -+ return 0; -+} -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index c4ebe9e22ad..70614de1565 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -34,6 +34,9 @@ - #include - #include - #include -+#ifdef GRUB_MACHINE_IEEE1275 -+#include -+#endif - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -276,6 +279,22 @@ grub_normal_execute (const char *config, int nested, int batch) - { - menu = read_config_file (config); - -+#ifdef GRUB_MACHINE_IEEE1275 -+ int boot; -+ boot = 0; -+ char *script; -+ script = grub_malloc (1024); -+ if (! grub_ieee1275_cas_reboot (script)) -+ { -+ char *dummy[1] = { NULL }; -+ if (! grub_script_execute_sourcecode (script)) -+ boot = 1; -+ } -+ grub_free (script); -+ if (boot) -+ grub_command_execute ("boot", 0, 0); -+#endif -+ - /* Ignore any error. */ - grub_errno = GRUB_ERR_NONE; - } -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index 25158407dd8..ad80399246a 100644 ---- a/grub-core/script/execute.c -+++ b/grub-core/script/execute.c -@@ -28,6 +28,9 @@ - #include - #include - #include -+#ifdef GRUB_MACHINE_IEEE1275 -+#include -+#endif - - /* Max digits for a char is 3 (0xFF is 255), similarly for an int it - is sizeof (int) * 3, and one extra for a possible -ve sign. */ -@@ -883,6 +886,10 @@ grub_script_execute_sourcecode (const char *source) - grub_err_t ret = 0; - struct grub_script *parsed_script; - -+#ifdef GRUB_MACHINE_IEEE1275 -+ grub_ieee1275_set_boot_last_label (source); -+#endif -+ - while (source) - { - char *line; -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index 73e2f464475..0a599607f31 100644 ---- a/include/grub/ieee1275/ieee1275.h -+++ b/include/grub/ieee1275/ieee1275.h -@@ -254,6 +254,8 @@ int EXPORT_FUNC(grub_ieee1275_devalias_next) (struct grub_ieee1275_devalias *ali - void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias); - void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath, - struct grub_ieee1275_devalias *alias); -+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script); -+int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text); - - char *EXPORT_FUNC(grub_ieee1275_get_boot_dev) (void); - diff --git a/0012-for-ppc-reset-console-display-attr-when-clear-screen.patch b/0012-for-ppc-reset-console-display-attr-when-clear-screen.patch deleted file mode 100644 index c8ccc7e..0000000 --- a/0012-for-ppc-reset-console-display-attr-when-clear-screen.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Wed, 24 Apr 2013 10:51:48 -0300 -Subject: [PATCH] for ppc, reset console display attr when clear screen - -v2: Also use \x0c instead of a literal ^L to make future patches less -awkward. - -This should fix this bugzilla: -https://bugzilla.redhat.com/show_bug.cgi?id=908519 - -Signed-off-by: Peter Jones -Signed-off-by: Paulo Flabiano Smorigo -Signed-off-by: Robbie Harwood ---- - grub-core/term/terminfo.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c -index 85ecf06b4df..05c88dcf49e 100644 ---- a/grub-core/term/terminfo.c -+++ b/grub-core/term/terminfo.c -@@ -151,7 +151,7 @@ grub_terminfo_set_current (struct grub_term_output *term, - /* Clear the screen. Using serial console, screen(1) only recognizes the - * ANSI escape sequence. Using video console, Apple Open Firmware - * (version 3.1.1) only recognizes the literal ^L. So use both. */ -- data->cls = grub_strdup (" \e[2J"); -+ data->cls = grub_strdup ("\x0c\e[2J\e[m"); - data->reverse_video_on = grub_strdup ("\e[7m"); - data->reverse_video_off = grub_strdup ("\e[m"); - if (grub_strcmp ("ieee1275", str) == 0) diff --git a/0013-Disable-GRUB-video-support-for-IBM-power-machines.patch b/0013-Disable-GRUB-video-support-for-IBM-power-machines.patch deleted file mode 100644 index e8aa367..0000000 --- a/0013-Disable-GRUB-video-support-for-IBM-power-machines.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Tue, 11 Jun 2013 15:14:05 -0300 -Subject: [PATCH] Disable GRUB video support for IBM power machines - -Should fix the problem in bugzilla: -https://bugzilla.redhat.com/show_bug.cgi?id=973205 - -Signed-off-by: Paulo Flabiano Smorigo -Signed-off-by: Robbie Harwood ---- - grub-core/kern/ieee1275/cmain.c | 5 ++++- - grub-core/video/ieee1275.c | 9 ++++++--- - include/grub/ieee1275/ieee1275.h | 2 ++ - 3 files changed, 12 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c -index 20cbbd761ec..04df9d2c667 100644 ---- a/grub-core/kern/ieee1275/cmain.c -+++ b/grub-core/kern/ieee1275/cmain.c -@@ -90,7 +90,10 @@ grub_ieee1275_find_options (void) - } - - if (rc >= 0 && grub_strncmp (tmp, "IBM", 3) == 0) -- grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS); -+ { -+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS); -+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT); -+ } - - /* Old Macs have no key repeat, newer ones have fully working one. - The ones inbetween when repeated key generates an escaoe sequence -diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c -index 17a3dbbb575..b8e4b3feb32 100644 ---- a/grub-core/video/ieee1275.c -+++ b/grub-core/video/ieee1275.c -@@ -352,9 +352,12 @@ static struct grub_video_adapter grub_video_ieee1275_adapter = - - GRUB_MOD_INIT(ieee1275_fb) - { -- find_display (); -- if (display) -- grub_video_register (&grub_video_ieee1275_adapter); -+ if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT)) -+ { -+ find_display (); -+ if (display) -+ grub_video_register (&grub_video_ieee1275_adapter); -+ } - } - - GRUB_MOD_FINI(ieee1275_fb) -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index 0a599607f31..b5a1d49bbc3 100644 ---- a/include/grub/ieee1275/ieee1275.h -+++ b/include/grub/ieee1275/ieee1275.h -@@ -148,6 +148,8 @@ enum grub_ieee1275_flag - GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN, - - GRUB_IEEE1275_FLAG_RAW_DEVNAMES, -+ -+ GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT - }; - - extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff --git a/0014-Move-bash-completion-script-922997.patch b/0014-Move-bash-completion-script-922997.patch deleted file mode 100644 index 6bf0b4b..0000000 --- a/0014-Move-bash-completion-script-922997.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 3 Apr 2013 14:35:34 -0400 -Subject: [PATCH] Move bash completion script (#922997) - -Apparently these go in a new place now. ---- - configure.ac | 11 +++++++++++ - util/bash-completion.d/Makefile.am | 1 - - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 7517fc49d98..8331f95b645 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -314,6 +314,14 @@ AC_SUBST(grubdirname) - AC_DEFINE_UNQUOTED(GRUB_DIR_NAME, "$grubdirname", - [Default grub directory name]) - -+PKG_PROG_PKG_CONFIG -+AS_IF([$($PKG_CONFIG --exists bash-completion)], [ -+ bashcompletiondir=$($PKG_CONFIG --variable=completionsdir bash-completion) -+] , [ -+ bashcompletiondir=${datadir}/bash-completion/completions -+]) -+AC_SUBST(bashcompletiondir) -+ - # - # Checks for build programs. - # -@@ -525,6 +533,9 @@ HOST_CFLAGS="$HOST_CFLAGS $grub_cv_cc_w_extra_flags" - # Check for target programs. - # - -+# This makes sure pkg.m4 is available. -+m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config]) -+ - # Find tools for the target. - if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then - tmp_ac_tool_prefix="$ac_tool_prefix" -diff --git a/util/bash-completion.d/Makefile.am b/util/bash-completion.d/Makefile.am -index 136287cf1bf..61108f05429 100644 ---- a/util/bash-completion.d/Makefile.am -+++ b/util/bash-completion.d/Makefile.am -@@ -6,7 +6,6 @@ EXTRA_DIST = $(bash_completion_source) - - CLEANFILES = $(bash_completion_script) config.log - --bashcompletiondir = $(sysconfdir)/bash_completion.d - bashcompletion_DATA = $(bash_completion_script) - - $(bash_completion_script): $(bash_completion_source) $(top_builddir)/config.status diff --git a/0015-Allow-fallback-to-include-entries-by-title-not-just-.patch b/0015-Allow-fallback-to-include-entries-by-title-not-just-.patch deleted file mode 100644 index f2a4a82..0000000 --- a/0015-Allow-fallback-to-include-entries-by-title-not-just-.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 5 Sep 2014 10:07:04 -0400 -Subject: [PATCH] Allow "fallback" to include entries by title, not just - number. - -Resolves: rhbz#1026084 - -Signed-off-by: Peter Jones ---- - grub-core/normal/menu.c | 85 +++++++++++++++++++++++++++++++++---------------- - 1 file changed, 58 insertions(+), 27 deletions(-) - -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index 8397886fa05..d7a222e681b 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -163,15 +163,40 @@ grub_menu_set_timeout (int timeout) - } - } - -+static int -+menuentry_eq (const char *id, const char *spec) -+{ -+ const char *ptr1, *ptr2; -+ ptr1 = id; -+ ptr2 = spec; -+ while (1) -+ { -+ if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) -+ return ptr2 - spec; -+ if (*ptr2 == '>' && ptr2[1] != '>') -+ return 0; -+ if (*ptr2 == '>') -+ ptr2++; -+ if (*ptr1 != *ptr2) -+ return 0; -+ if (*ptr1 == 0) -+ return ptr1 - id; -+ ptr1++; -+ ptr2++; -+ } -+ return 0; -+} -+ - /* Get the first entry number from the value of the environment variable NAME, - which is a space-separated list of non-negative integers. The entry number - which is returned is stripped from the value of NAME. If no entry number - can be found, -1 is returned. */ - static int --get_and_remove_first_entry_number (const char *name) -+get_and_remove_first_entry_number (grub_menu_t menu, const char *name) - { - const char *val, *tail; - int entry; -+ int sz = 0; - - val = grub_env_get (name); - if (! val) -@@ -181,9 +206,39 @@ get_and_remove_first_entry_number (const char *name) - - entry = (int) grub_strtoul (val, &tail, 0); - -+ if (grub_errno == GRUB_ERR_BAD_NUMBER) -+ { -+ /* See if the variable matches the title of a menu entry. */ -+ grub_menu_entry_t e = menu->entry_list; -+ int i; -+ -+ for (i = 0; e; i++) -+ { -+ sz = menuentry_eq (e->title, val); -+ if (sz < 1) -+ sz = menuentry_eq (e->id, val); -+ -+ if (sz >= 1) -+ { -+ entry = i; -+ break; -+ } -+ e = e->next; -+ } -+ -+ if (sz > 0) -+ grub_errno = GRUB_ERR_NONE; -+ -+ if (! e) -+ entry = -1; -+ } -+ - if (grub_errno == GRUB_ERR_NONE) - { -- /* Skip whitespace to find the next digit. */ -+ if (sz > 0) -+ tail += sz; -+ -+ /* Skip whitespace to find the next entry. */ - while (*tail && grub_isspace (*tail)) - tail++; - grub_env_set (name, tail); -@@ -346,7 +401,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu, - grub_menu_execute_entry (entry, 1); - - /* Deal with fallback entries. */ -- while ((fallback_entry = get_and_remove_first_entry_number ("fallback")) -+ while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback")) - >= 0) - { - grub_print_error (); -@@ -464,30 +519,6 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer) - viewers = viewer; - } - --static int --menuentry_eq (const char *id, const char *spec) --{ -- const char *ptr1, *ptr2; -- ptr1 = id; -- ptr2 = spec; -- while (1) -- { -- if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) -- return 1; -- if (*ptr2 == '>' && ptr2[1] != '>') -- return 0; -- if (*ptr2 == '>') -- ptr2++; -- if (*ptr1 != *ptr2) -- return 0; -- if (*ptr1 == 0) -- return 1; -- ptr1++; -- ptr2++; -- } --} -- -- - /* Get the entry number from the variable NAME. */ - static int - get_entry_number (grub_menu_t menu, const char *name) diff --git a/0016-Make-exit-take-a-return-code.patch b/0016-Make-exit-take-a-return-code.patch deleted file mode 100644 index 39d7057..0000000 --- a/0016-Make-exit-take-a-return-code.patch +++ /dev/null @@ -1,267 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 26 Feb 2014 21:49:12 -0500 -Subject: [PATCH] Make "exit" take a return code. - -This adds "exit" with a return code. With this patch, any "exit" -command /may/ include a return code, and on platforms that support -returning with an exit status, we will do so. By default we return the -same exit status we did before this patch. - -Signed-off-by: Peter Jones ---- - grub-core/commands/minicmd.c | 20 ++++++++++++++++---- - grub-core/kern/efi/efi.c | 9 +++++++-- - grub-core/kern/emu/main.c | 2 +- - grub-core/kern/emu/misc.c | 5 +++-- - grub-core/kern/i386/coreboot/init.c | 2 +- - grub-core/kern/i386/qemu/init.c | 2 +- - grub-core/kern/ieee1275/init.c | 2 +- - grub-core/kern/mips/arc/init.c | 2 +- - grub-core/kern/mips/loongson/init.c | 2 +- - grub-core/kern/mips/qemu_mips/init.c | 2 +- - grub-core/kern/misc.c | 11 ++++++++++- - grub-core/kern/uboot/init.c | 6 +++--- - grub-core/kern/xen/init.c | 2 +- - include/grub/misc.h | 2 +- - 14 files changed, 48 insertions(+), 21 deletions(-) - -diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c -index fa498931ed2..2bd3ac76f2d 100644 ---- a/grub-core/commands/minicmd.c -+++ b/grub-core/commands/minicmd.c -@@ -182,12 +182,24 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), - } - - /* exit */ --static grub_err_t __attribute__ ((noreturn)) -+static grub_err_t - grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)), -- int argc __attribute__ ((unused)), -- char *argv[] __attribute__ ((unused))) -+ int argc, char *argv[]) - { -- grub_exit (); -+ int retval = -1; -+ unsigned long n; -+ -+ if (argc < 0 || argc > 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); -+ -+ if (argc == 1) -+ { -+ n = grub_strtoul (argv[0], 0, 10); -+ if (n != ~0UL) -+ retval = n; -+ } -+ -+ grub_exit (retval); - /* Not reached. */ - } - -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 8cff7be0289..05d8237a9b2 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -165,11 +165,16 @@ grub_reboot (void) - } - - void --grub_exit (void) -+grub_exit (int retval) - { -+ int rc = GRUB_EFI_LOAD_ERROR; -+ -+ if (retval == 0) -+ rc = GRUB_EFI_SUCCESS; -+ - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); - efi_call_4 (grub_efi_system_table->boot_services->exit, -- grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0); -+ grub_efi_image_handle, rc, 0, 0); - for (;;) ; - } - -diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c -index 425bb960347..55ea5a11ccd 100644 ---- a/grub-core/kern/emu/main.c -+++ b/grub-core/kern/emu/main.c -@@ -67,7 +67,7 @@ grub_reboot (void) - } - - void --grub_exit (void) -+grub_exit (int retval __attribute__((unused))) - { - grub_reboot (); - } -diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c -index dfd8a8ec488..0ff13bcaf8c 100644 ---- a/grub-core/kern/emu/misc.c -+++ b/grub-core/kern/emu/misc.c -@@ -151,9 +151,10 @@ xasprintf (const char *fmt, ...) - - #if !defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL) - void --grub_exit (void) -+__attribute__ ((noreturn)) -+grub_exit (int rc) - { -- exit (1); -+ exit (rc < 0 ? 1 : rc); - } - #endif - -diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c -index 3314f027fec..36f9134b7b7 100644 ---- a/grub-core/kern/i386/coreboot/init.c -+++ b/grub-core/kern/i386/coreboot/init.c -@@ -41,7 +41,7 @@ extern grub_uint8_t _end[]; - extern grub_uint8_t _edata[]; - - void __attribute__ ((noreturn)) --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - /* We can't use grub_fatal() in this function. This would create an infinite - loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */ -diff --git a/grub-core/kern/i386/qemu/init.c b/grub-core/kern/i386/qemu/init.c -index 271b6fbfabd..9fafe98f015 100644 ---- a/grub-core/kern/i386/qemu/init.c -+++ b/grub-core/kern/i386/qemu/init.c -@@ -42,7 +42,7 @@ extern grub_uint8_t _end[]; - extern grub_uint8_t _edata[]; - - void __attribute__ ((noreturn)) --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - /* We can't use grub_fatal() in this function. This would create an infinite - loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */ -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index d483e35eed2..e71d1584164 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -71,7 +71,7 @@ grub_addr_t grub_ieee1275_original_stack; - #endif - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - grub_ieee1275_exit (); - } -diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c -index 2ed3ff3191e..5c40c34078d 100644 ---- a/grub-core/kern/mips/arc/init.c -+++ b/grub-core/kern/mips/arc/init.c -@@ -276,7 +276,7 @@ grub_halt (void) - } - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - GRUB_ARC_FIRMWARE_VECTOR->exit (); - -diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c -index 7b96531b983..dff598ca7b0 100644 ---- a/grub-core/kern/mips/loongson/init.c -+++ b/grub-core/kern/mips/loongson/init.c -@@ -304,7 +304,7 @@ grub_halt (void) - } - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - grub_halt (); - } -diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c -index be88b77d22d..8b6c55ffc01 100644 ---- a/grub-core/kern/mips/qemu_mips/init.c -+++ b/grub-core/kern/mips/qemu_mips/init.c -@@ -75,7 +75,7 @@ grub_machine_fini (int flags __attribute__ ((unused))) - } - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - grub_halt (); - } -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 3af336ee227..63b586d09cb 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -1209,9 +1209,18 @@ grub_abort (void) - grub_getkey (); - } - -- grub_exit (); -+ grub_exit (1); - } - -+#if defined (__clang__) && !defined (GRUB_UTIL) -+/* clang emits references to abort(). */ -+void __attribute__ ((noreturn)) -+abort (void) -+{ -+ grub_abort (); -+} -+#endif -+ - void - grub_fatal (const char *fmt, ...) - { -diff --git a/grub-core/kern/uboot/init.c b/grub-core/kern/uboot/init.c -index 3e338645c57..be2a5be1d07 100644 ---- a/grub-core/kern/uboot/init.c -+++ b/grub-core/kern/uboot/init.c -@@ -39,9 +39,9 @@ extern grub_size_t grub_total_module_size; - static unsigned long timer_start; - - void --grub_exit (void) -+grub_exit (int rc) - { -- grub_uboot_return (0); -+ grub_uboot_return (rc < 0 ? 1 : rc); - } - - static grub_uint64_t -@@ -78,7 +78,7 @@ grub_machine_init (void) - if (!ver) - { - /* Don't even have a console to log errors to... */ -- grub_exit (); -+ grub_exit (-1); - } - else if (ver > API_SIG_VERSION) - { -diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c -index 782ca72952a..708b060f324 100644 ---- a/grub-core/kern/xen/init.c -+++ b/grub-core/kern/xen/init.c -@@ -584,7 +584,7 @@ grub_machine_init (void) - } - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - struct sched_shutdown arg; - -diff --git a/include/grub/misc.h b/include/grub/misc.h -index 7d2b5519690..fd18e6320b8 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -353,7 +353,7 @@ int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, - char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) - __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT; - char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT; --void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); -+void EXPORT_FUNC(grub_exit) (int rc) __attribute__ ((noreturn)); - grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, - grub_uint64_t d, - grub_uint64_t *r); diff --git a/0017-Make-efi-machines-load-an-env-block-from-a-variable.patch b/0017-Make-efi-machines-load-an-env-block-from-a-variable.patch deleted file mode 100644 index d061461..0000000 --- a/0017-Make-efi-machines-load-an-env-block-from-a-variable.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 7 Dec 2015 14:20:49 -0500 -Subject: [PATCH] Make efi machines load an env block from a variable - -Signed-off-by: Peter Jones ---- - grub-core/Makefile.core.def | 1 + - grub-core/kern/efi/init.c | 36 +++++++++++++++++++++++++++++++++++- - 2 files changed, 36 insertions(+), 1 deletion(-) - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 45d3edaa4dc..c865a08b027 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -207,6 +207,7 @@ kernel = { - efi = kern/efi/acpi.c; - efi = kern/efi/sb.c; - efi = kern/lockdown.c; -+ efi = lib/envblk.c; - i386_coreboot = kern/i386/pc/acpi.c; - i386_multiboot = kern/i386/pc/acpi.c; - i386_coreboot = kern/acpi.c; -diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c -index 7facacf09c7..6d39bd3ad29 100644 ---- a/grub-core/kern/efi/init.c -+++ b/grub-core/kern/efi/init.c -@@ -27,8 +27,11 @@ - #include - #include - #include -+ - #include - -+#include -+ - #ifdef GRUB_STACK_PROTECTOR - - static grub_efi_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID; -@@ -82,6 +85,36 @@ stack_protector_init (void) - - grub_addr_t grub_modbase; - -+#define GRUB_EFI_GRUB_VARIABLE_GUID \ -+ { 0x91376aff, 0xcba6, 0x42be, \ -+ { 0x94, 0x9d, 0x06, 0xfd, 0xe8, 0x11, 0x28, 0xe8 } \ -+ } -+ -+/* Helper for grub_efi_env_init */ -+static int -+set_var (const char *name, const char *value, -+ void *whitelist __attribute__((__unused__))) -+{ -+ grub_env_set (name, value); -+ return 0; -+} -+ -+static void -+grub_efi_env_init (void) -+{ -+ grub_efi_guid_t efi_grub_guid = GRUB_EFI_GRUB_VARIABLE_GUID; -+ struct grub_envblk envblk_s = { NULL, 0 }; -+ grub_envblk_t envblk = &envblk_s; -+ -+ grub_efi_get_variable ("GRUB_ENV", &efi_grub_guid, &envblk_s.size, -+ (void **) &envblk_s.buf); -+ if (!envblk_s.buf || envblk_s.size < 1) -+ return; -+ -+ grub_envblk_iterate (envblk, NULL, set_var); -+ grub_free (envblk_s.buf); -+} -+ - void - grub_efi_init (void) - { -@@ -108,10 +141,11 @@ grub_efi_init (void) - efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer, - 0, 0, 0, NULL); - -+ grub_efi_env_init (); - grub_efidisk_init (); - } - --void (*grub_efi_net_config) (grub_efi_handle_t hnd, -+void (*grub_efi_net_config) (grub_efi_handle_t hnd, - char **device, - char **path); - diff --git a/0018-Migrate-PPC-from-Yaboot-to-Grub2.patch b/0018-Migrate-PPC-from-Yaboot-to-Grub2.patch deleted file mode 100644 index 5cbe731..0000000 --- a/0018-Migrate-PPC-from-Yaboot-to-Grub2.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Mark Hamzy -Date: Wed, 28 Mar 2012 14:46:41 -0500 -Subject: [PATCH] Migrate PPC from Yaboot to Grub2 - -Add configuration support for serial terminal consoles. This will set -the maximum screen size so that text is not overwritten. - -Signed-off-by: Mark Hamzy -Signed-off-by: Robbie Harwood ---- - Makefile.util.def | 7 +++ - util/grub.d/20_ppc_terminfo.in | 114 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 121 insertions(+) - create mode 100644 util/grub.d/20_ppc_terminfo.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index f8b356cc1fa..2c9b283a230 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -508,6 +508,13 @@ script = { - condition = COND_HOST_LINUX; - }; - -+script = { -+ name = '20_ppc_terminfo'; -+ common = util/grub.d/20_ppc_terminfo.in; -+ installdir = grubconf; -+ condition = COND_HOST_LINUX; -+}; -+ - script = { - name = '30_os-prober'; - common = util/grub.d/30_os-prober.in; -diff --git a/util/grub.d/20_ppc_terminfo.in b/util/grub.d/20_ppc_terminfo.in -new file mode 100644 -index 00000000000..10d66586820 ---- /dev/null -+++ b/util/grub.d/20_ppc_terminfo.in -@@ -0,0 +1,114 @@ -+#! /bin/sh -+set -e -+ -+# grub-mkconfig helper script. -+# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. -+# -+# GRUB is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+# -+# GRUB is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with GRUB. If not, see . -+ -+prefix=@prefix@ -+exec_prefix=@exec_prefix@ -+bindir=@bindir@ -+libdir=@libdir@ -+. "@datadir@/@PACKAGE@/grub-mkconfig_lib" -+ -+export TEXTDOMAIN=@PACKAGE@ -+export TEXTDOMAINDIR=@localedir@ -+ -+X=80 -+Y=24 -+TERMINAL=ofconsole -+ -+argument () { -+ opt=$1 -+ shift -+ -+ if test $# -eq 0; then -+ echo "$0: option requires an argument -- '$opt'" 1>&2 -+ exit 1 -+ fi -+ echo $1 -+} -+ -+check_terminfo () { -+ -+ while test $# -gt 0 -+ do -+ option=$1 -+ shift -+ -+ case "$option" in -+ terminfo | TERMINFO) -+ ;; -+ -+ -g) -+ NEWXY=`argument $option "$@"` -+ NEWX=`echo $NEWXY | cut -d x -f 1` -+ NEWY=`echo $NEWXY | cut -d x -f 2` -+ -+ if [ ${NEWX} -ge 80 ] ; then -+ X=${NEWX} -+ else -+ echo "Warning: ${NEWX} is less than the minimum size of 80" -+ fi -+ -+ if [ ${NEWY} -ge 24 ] ; then -+ Y=${NEWY} -+ else -+ echo "Warning: ${NEWY} is less than the minimum size of 24" -+ fi -+ -+ shift -+ ;; -+ -+ *) -+# # accept console or ofconsole -+# if [ "$option" != "console" -a "$option" != "ofconsole" ] ; then -+# echo "Error: GRUB_TERMINFO unknown console: $option" -+# exit 1 -+# fi -+# # perfer console -+# TERMINAL=console -+ # accept ofconsole -+ if [ "$option" != "ofconsole" ] ; then -+ echo "Error: GRUB_TERMINFO unknown console: $option" -+ exit 1 -+ fi -+ # perfer console -+ TERMINAL=ofconsole -+ ;; -+ esac -+ -+ done -+ -+} -+ -+if ! uname -m | grep -q ppc ; then -+ exit 0 -+fi -+ -+if [ "x${GRUB_TERMINFO}" != "x" ] ; then -+ F1=`echo ${GRUB_TERMINFO} | cut -d " " -f 1` -+ -+ if [ "${F1}" != "terminfo" ] ; then -+ echo "Error: GRUB_TERMINFO is set to \"${GRUB_TERMINFO}\" The first word should be terminfo." -+ exit 1 -+ fi -+ -+ check_terminfo ${GRUB_TERMINFO} -+fi -+ -+cat << EOF -+ terminfo -g ${X}x${Y} ${TERMINAL} -+EOF diff --git a/0019-Add-fw_path-variable-revised.patch b/0019-Add-fw_path-variable-revised.patch deleted file mode 100644 index a8491e8..0000000 --- a/0019-Add-fw_path-variable-revised.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Wed, 19 Sep 2012 21:22:55 -0300 -Subject: [PATCH] Add fw_path variable (revised) - -This patch makes grub look for its config file on efi where the app was -found. It was originally written by Matthew Garrett, and adapted to fix the -"No modules are loaded on grub2 network boot" issue: - -https://bugzilla.redhat.com/show_bug.cgi?id=857936 - -Signed-off-by: Paulo Flabiano Smorigo -Signed-off-by: Robbie Harwood ---- - grub-core/kern/main.c | 13 ++++++------- - grub-core/normal/main.c | 25 ++++++++++++++++++++++++- - 2 files changed, 30 insertions(+), 8 deletions(-) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index 73967e2f5b0..d1de9fa6873 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -128,16 +128,15 @@ grub_set_prefix_and_root (void) - - grub_machine_get_bootlocation (&fwdevice, &fwpath); - -- if (fwdevice) -+ if (fwdevice && fwpath) - { -- char *cmdpath; -+ char *fw_path; - -- cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : ""); -- if (cmdpath) -+ fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath); -+ if (fw_path) - { -- grub_env_set ("cmdpath", cmdpath); -- grub_env_export ("cmdpath"); -- grub_free (cmdpath); -+ grub_env_set ("fw_path", fw_path); -+ grub_free (fw_path); - } - } - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 70614de1565..62571e6dfcc 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -339,7 +339,30 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - /* Guess the config filename. It is necessary to make CONFIG static, - so that it won't get broken by longjmp. */ - char *config; -- const char *prefix; -+ const char *prefix, *fw_path; -+ -+ fw_path = grub_env_get ("fw_path"); -+ if (fw_path) -+ { -+ config = grub_xasprintf ("%s/grub.cfg", fw_path); -+ if (config) -+ { -+ grub_file_t file; -+ -+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -+ if (file) -+ { -+ grub_file_close (file); -+ grub_enter_normal_mode (config); -+ } -+ else -+ { -+ /* Ignore all errors. */ -+ grub_errno = 0; -+ } -+ grub_free (config); -+ } -+ } - - prefix = grub_env_get ("prefix"); - if (prefix) diff --git a/0020-Pass-x-hex-hex-straight-through-unmolested.patch b/0020-Pass-x-hex-hex-straight-through-unmolested.patch deleted file mode 100644 index b81abb5..0000000 --- a/0020-Pass-x-hex-hex-straight-through-unmolested.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 1 Oct 2012 13:24:37 -0400 -Subject: [PATCH] Pass "\x[[:hex:]][[:hex:]]" straight through unmolested. - -Don't munge raw spaces when we're doing our cmdline escaping (#923374) - -Signed-off-by: Peter Jones ---- - grub-core/commands/wildcard.c | 16 +++++++++++++++- - grub-core/lib/cmdline.c | 25 +++++++++++++++++++++++-- - grub-core/script/execute.c | 43 +++++++++++++++++++++++++++++++++++++------ - 3 files changed, 75 insertions(+), 9 deletions(-) - -diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c -index cc3290311f0..8f67a4be7f0 100644 ---- a/grub-core/commands/wildcard.c -+++ b/grub-core/commands/wildcard.c -@@ -488,6 +488,12 @@ check_file (const char *dir, const char *basename) - return ctx.found; - } - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static void - unescape (char *out, const char *in, const char *end) - { -@@ -496,7 +502,15 @@ unescape (char *out, const char *in, const char *end) - - for (optr = out, iptr = in; iptr < end;) - { -- if (*iptr == '\\' && iptr + 1 < end) -+ if (*iptr == '\\' && iptr + 3 < end && iptr[1] == 'x' && is_hex(iptr[2]) && is_hex(iptr[3])) -+ { -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ continue; -+ } -+ else if (*iptr == '\\' && iptr + 1 < end) - { - *optr++ = iptr[1]; - iptr += 2; -diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c -index ed0b149dca5..8e2294d8ff6 100644 ---- a/grub-core/lib/cmdline.c -+++ b/grub-core/lib/cmdline.c -@@ -20,6 +20,12 @@ - #include - #include - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static unsigned int check_arg (char *c, int *has_space) - { - int space = 0; -@@ -27,7 +33,13 @@ static unsigned int check_arg (char *c, int *has_space) - - while (*c) - { -- if (*c == '\\' || *c == '\'' || *c == '"') -+ if (*c == '\\' && *(c+1) == 'x' && is_hex(*(c+2)) && is_hex(*(c+3))) -+ { -+ size += 4; -+ c += 4; -+ continue; -+ } -+ else if (*c == '\\' || *c == '\'' || *c == '"') - size++; - else if (*c == ' ') - space = 1; -@@ -86,7 +98,16 @@ grub_create_loader_cmdline (int argc, char *argv[], char *buf, - - while (*c) - { -- if (*c == '\\' || *c == '\'' || *c == '"') -+ if (*c == '\\' && *(c+1) == 'x' && -+ is_hex(*(c+2)) && is_hex(*(c+3))) -+ { -+ *buf++ = *c++; -+ *buf++ = *c++; -+ *buf++ = *c++; -+ *buf++ = *c++; -+ continue; -+ } -+ else if (*c == '\\' || *c == '\'' || *c == '"') - *buf++ = '\\'; - - *buf++ = *c; -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index ad80399246a..0c6dd9c5201 100644 ---- a/grub-core/script/execute.c -+++ b/grub-core/script/execute.c -@@ -56,6 +56,12 @@ static struct grub_script_scope *scope = 0; - /* Wildcard translator for GRUB script. */ - struct grub_script_wildcard_translator *grub_wildcard_translator; - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static char* - wildcard_escape (const char *s) - { -@@ -72,7 +78,15 @@ wildcard_escape (const char *s) - i = 0; - while ((ch = *s++)) - { -- if (ch == '*' || ch == '\\' || ch == '?') -+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2])) -+ { -+ p[i++] = ch; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ continue; -+ } -+ else if (ch == '*' || ch == '\\' || ch == '?') - p[i++] = '\\'; - p[i++] = ch; - } -@@ -96,7 +110,14 @@ wildcard_unescape (const char *s) - i = 0; - while ((ch = *s++)) - { -- if (ch == '\\') -+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2])) -+ { -+ p[i++] = '\\'; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ } -+ else if (ch == '\\') - p[i++] = *s++; - else - p[i++] = ch; -@@ -398,10 +419,20 @@ parse_string (const char *str, - switch (*ptr) - { - case '\\': -- escaped = !escaped; -- if (!escaped && put) -- *(put++) = '\\'; -- ptr++; -+ if (!escaped && put && *(ptr+1) == 'x' && is_hex(*(ptr+2)) && is_hex(*(ptr+3))) -+ { -+ *(put++) = *ptr++; -+ *(put++) = *ptr++; -+ *(put++) = *ptr++; -+ *(put++) = *ptr++; -+ } -+ else -+ { -+ escaped = !escaped; -+ if (!escaped && put) -+ *(put++) = '\\'; -+ ptr++; -+ } - break; - case '$': - if (escaped) diff --git a/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch b/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch deleted file mode 100644 index da65e18..0000000 --- a/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch +++ /dev/null @@ -1,1609 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 22 Jan 2013 06:31:38 +0100 -Subject: [PATCH] blscfg: add blscfg module to parse Boot Loader Specification - snippets - -The BootLoaderSpec (BLS) defines a scheme where different bootloaders can -share a format for boot items and a configuration directory that accepts -these common configurations as drop-in files. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -[wjt: some cleanups and fixes] -Signed-off-by: Will Thompson ---- - grub-core/Makefile.core.def | 11 + - grub-core/commands/blscfg.c | 1177 ++++++++++++++++++++++++++++++++++++++++ - grub-core/commands/legacycfg.c | 5 +- - grub-core/commands/loadenv.c | 77 +-- - grub-core/commands/menuentry.c | 20 +- - grub-core/normal/main.c | 6 + - grub-core/commands/loadenv.h | 93 ++++ - include/grub/compiler.h | 2 + - include/grub/menu.h | 13 + - include/grub/normal.h | 2 +- - 10 files changed, 1324 insertions(+), 82 deletions(-) - create mode 100644 grub-core/commands/blscfg.c - create mode 100644 grub-core/commands/loadenv.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index c865a08b027..c15e91943b9 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -814,6 +814,16 @@ module = { - common = commands/blocklist.c; - }; - -+module = { -+ name = blscfg; -+ common = commands/blscfg.c; -+ common = commands/loadenv.h; -+ enable = powerpc_ieee1275; -+ enable = efi; -+ enable = i386_pc; -+ enable = emu; -+}; -+ - module = { - name = boot; - common = commands/boot.c; -@@ -980,6 +990,7 @@ module = { - module = { - name = loadenv; - common = commands/loadenv.c; -+ common = commands/loadenv.h; - common = lib/envblk.c; - }; - -diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c -new file mode 100644 -index 00000000000..e907a6a5d28 ---- /dev/null -+++ b/grub-core/commands/blscfg.c -@@ -0,0 +1,1177 @@ -+/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/ -+ -+/* bls.c - implementation of the boot loader spec */ -+ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#include "loadenv.h" -+ -+#define GRUB_BLS_CONFIG_PATH "/loader/entries/" -+#ifdef GRUB_MACHINE_EMU -+#define GRUB_BOOT_DEVICE "/boot" -+#else -+#define GRUB_BOOT_DEVICE "($root)" -+#endif -+ -+struct keyval -+{ -+ const char *key; -+ char *val; -+}; -+ -+static struct bls_entry *entries = NULL; -+ -+#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries) -+ -+static int bls_add_keyval(struct bls_entry *entry, char *key, char *val) -+{ -+ char *k, *v; -+ struct keyval **kvs, *kv; -+ int new_n = entry->nkeyvals + 1; -+ -+ kvs = grub_realloc (entry->keyvals, new_n * sizeof (struct keyval *)); -+ if (!kvs) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't find space for BLS entry"); -+ entry->keyvals = kvs; -+ -+ kv = grub_malloc (sizeof (struct keyval)); -+ if (!kv) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't find space for BLS entry"); -+ -+ k = grub_strdup (key); -+ if (!k) -+ { -+ grub_free (kv); -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't find space for BLS entry"); -+ } -+ -+ v = grub_strdup (val); -+ if (!v) -+ { -+ grub_free (k); -+ grub_free (kv); -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't find space for BLS entry"); -+ } -+ -+ kv->key = k; -+ kv->val = v; -+ -+ entry->keyvals[entry->nkeyvals] = kv; -+ grub_dprintf("blscfg", "new keyval at %p:%s:%s\n", entry->keyvals[entry->nkeyvals], k, v); -+ entry->nkeyvals = new_n; -+ -+ return 0; -+} -+ -+/* Find they value of the key named by keyname. If there are allowed to be -+ * more than one, pass a pointer to an int set to -1 the first time, and pass -+ * the same pointer through each time after, and it'll return them in sorted -+ * order as defined in the BLS fragment file */ -+static char *bls_get_val(struct bls_entry *entry, const char *keyname, int *last) -+{ -+ int idx, start = 0; -+ struct keyval *kv = NULL; -+ -+ if (last) -+ start = *last + 1; -+ -+ for (idx = start; idx < entry->nkeyvals; idx++) { -+ kv = entry->keyvals[idx]; -+ -+ if (!grub_strcmp (keyname, kv->key)) -+ break; -+ } -+ -+ if (idx == entry->nkeyvals) { -+ if (last) -+ *last = -1; -+ return NULL; -+ } -+ -+ if (last) -+ *last = idx; -+ -+ return kv->val; -+} -+ -+#define goto_return(x) ({ ret = (x); goto finish; }) -+ -+/* compare alpha and numeric segments of two versions */ -+/* return 1: a is newer than b */ -+/* 0: a and b are the same version */ -+/* -1: b is newer than a */ -+static int vercmp(const char * a, const char * b) -+{ -+ char oldch1, oldch2; -+ char *abuf, *bbuf; -+ char *str1, *str2; -+ char * one, * two; -+ int rc; -+ int isnum; -+ int ret = 0; -+ -+ grub_dprintf("blscfg", "%s comparing %s and %s\n", __func__, a, b); -+ if (!grub_strcmp(a, b)) -+ return 0; -+ -+ abuf = grub_malloc(grub_strlen(a) + 1); -+ bbuf = grub_malloc(grub_strlen(b) + 1); -+ str1 = abuf; -+ str2 = bbuf; -+ grub_strcpy(str1, a); -+ grub_strcpy(str2, b); -+ -+ one = str1; -+ two = str2; -+ -+ /* loop through each version segment of str1 and str2 and compare them */ -+ while (*one || *two) { -+ while (*one && !grub_isalnum(*one) && *one != '~' && *one != '+') one++; -+ while (*two && !grub_isalnum(*two) && *two != '~' && *two != '+') two++; -+ -+ /* handle the tilde separator, it sorts before everything else */ -+ if (*one == '~' || *two == '~') { -+ if (*one != '~') goto_return (1); -+ if (*two != '~') goto_return (-1); -+ one++; -+ two++; -+ continue; -+ } -+ -+ /* -+ * Handle plus separator. Concept is the same as tilde, -+ * except that if one of the strings ends (base version), -+ * the other is considered as higher version. -+ */ -+ if (*one == '+' || *two == '+') { -+ if (!*one) return -1; -+ if (!*two) return 1; -+ if (*one != '+') goto_return (1); -+ if (*two != '+') goto_return (-1); -+ one++; -+ two++; -+ continue; -+ } -+ -+ /* If we ran to the end of either, we are finished with the loop */ -+ if (!(*one && *two)) break; -+ -+ str1 = one; -+ str2 = two; -+ -+ /* grab first completely alpha or completely numeric segment */ -+ /* leave one and two pointing to the start of the alpha or numeric */ -+ /* segment and walk str1 and str2 to end of segment */ -+ if (grub_isdigit(*str1)) { -+ while (*str1 && grub_isdigit(*str1)) str1++; -+ while (*str2 && grub_isdigit(*str2)) str2++; -+ isnum = 1; -+ } else { -+ while (*str1 && grub_isalpha(*str1)) str1++; -+ while (*str2 && grub_isalpha(*str2)) str2++; -+ isnum = 0; -+ } -+ -+ /* save character at the end of the alpha or numeric segment */ -+ /* so that they can be restored after the comparison */ -+ oldch1 = *str1; -+ *str1 = '\0'; -+ oldch2 = *str2; -+ *str2 = '\0'; -+ -+ /* this cannot happen, as we previously tested to make sure that */ -+ /* the first string has a non-null segment */ -+ if (one == str1) goto_return(-1); /* arbitrary */ -+ -+ /* take care of the case where the two version segments are */ -+ /* different types: one numeric, the other alpha (i.e. empty) */ -+ /* numeric segments are always newer than alpha segments */ -+ /* XXX See patch #60884 (and details) from bugzilla #50977. */ -+ if (two == str2) goto_return (isnum ? 1 : -1); -+ -+ if (isnum) { -+ grub_size_t onelen, twolen; -+ /* this used to be done by converting the digit segments */ -+ /* to ints using atoi() - it's changed because long */ -+ /* digit segments can overflow an int - this should fix that. */ -+ -+ /* throw away any leading zeros - it's a number, right? */ -+ while (*one == '0') one++; -+ while (*two == '0') two++; -+ -+ /* whichever number has more digits wins */ -+ onelen = grub_strlen(one); -+ twolen = grub_strlen(two); -+ if (onelen > twolen) goto_return (1); -+ if (twolen > onelen) goto_return (-1); -+ } -+ -+ /* grub_strcmp will return which one is greater - even if the two */ -+ /* segments are alpha or if they are numeric. don't return */ -+ /* if they are equal because there might be more segments to */ -+ /* compare */ -+ rc = grub_strcmp(one, two); -+ if (rc) goto_return (rc < 1 ? -1 : 1); -+ -+ /* restore character that was replaced by null above */ -+ *str1 = oldch1; -+ one = str1; -+ *str2 = oldch2; -+ two = str2; -+ } -+ -+ /* this catches the case where all numeric and alpha segments have */ -+ /* compared identically but the segment sepparating characters were */ -+ /* different */ -+ if ((!*one) && (!*two)) goto_return (0); -+ -+ /* whichever version still has characters left over wins */ -+ if (!*one) goto_return (-1); else goto_return (1); -+ -+finish: -+ grub_free (abuf); -+ grub_free (bbuf); -+ return ret; -+} -+ -+/* returns name/version/release */ -+/* NULL string pointer returned if nothing found */ -+static void -+split_package_string (char *package_string, char **name, -+ char **version, char **release) -+{ -+ char *package_version, *package_release; -+ -+ /* Release */ -+ package_release = grub_strrchr (package_string, '-'); -+ -+ if (package_release != NULL) -+ *package_release++ = '\0'; -+ -+ *release = package_release; -+ -+ if (name == NULL) -+ { -+ *version = package_string; -+ } -+ else -+ { -+ /* Version */ -+ package_version = grub_strrchr(package_string, '-'); -+ -+ if (package_version != NULL) -+ *package_version++ = '\0'; -+ -+ *version = package_version; -+ /* Name */ -+ *name = package_string; -+ } -+ -+ /* Bubble up non-null values from release to name */ -+ if (name != NULL && *name == NULL) -+ { -+ *name = (*version == NULL ? *release : *version); -+ *version = *release; -+ *release = NULL; -+ } -+ if (*version == NULL) -+ { -+ *version = *release; -+ *release = NULL; -+ } -+} -+ -+static int -+split_cmp(char *nvr0, char *nvr1, int has_name) -+{ -+ int ret = 0; -+ char *name0, *version0, *release0; -+ char *name1, *version1, *release1; -+ -+ split_package_string(nvr0, has_name ? &name0 : NULL, &version0, &release0); -+ split_package_string(nvr1, has_name ? &name1 : NULL, &version1, &release1); -+ -+ if (has_name) -+ { -+ ret = vercmp(name0 == NULL ? "" : name0, -+ name1 == NULL ? "" : name1); -+ if (ret != 0) -+ return ret; -+ } -+ -+ ret = vercmp(version0 == NULL ? "" : version0, -+ version1 == NULL ? "" : version1); -+ if (ret != 0) -+ return ret; -+ -+ ret = vercmp(release0 == NULL ? "" : release0, -+ release1 == NULL ? "" : release1); -+ return ret; -+} -+ -+/* return 1: e0 is newer than e1 */ -+/* 0: e0 and e1 are the same version */ -+/* -1: e1 is newer than e0 */ -+static int bls_cmp(const struct bls_entry *e0, const struct bls_entry *e1) -+{ -+ char *id0, *id1; -+ int r; -+ -+ id0 = grub_strdup(e0->filename); -+ id1 = grub_strdup(e1->filename); -+ -+ r = split_cmp(id0, id1, 1); -+ -+ grub_free(id0); -+ grub_free(id1); -+ -+ return r; -+} -+ -+static void list_add_tail(struct bls_entry *head, struct bls_entry *item) -+{ -+ item->next = head; -+ if (head->prev) -+ head->prev->next = item; -+ item->prev = head->prev; -+ head->prev = item; -+} -+ -+static int bls_add_entry(struct bls_entry *entry) -+{ -+ struct bls_entry *e, *last = NULL; -+ int rc; -+ -+ if (!entries) { -+ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); -+ entries = entry; -+ return 0; -+ } -+ -+ FOR_BLS_ENTRIES(e) { -+ rc = bls_cmp(entry, e); -+ -+ if (!rc) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ if (rc == 1) { -+ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); -+ list_add_tail (e, entry); -+ if (e == entries) { -+ entries = entry; -+ entry->prev = NULL; -+ } -+ return 0; -+ } -+ last = e; -+ } -+ -+ if (last) { -+ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); -+ last->next = entry; -+ entry->prev = last; -+ } -+ -+ return 0; -+} -+ -+struct read_entry_info { -+ const char *devid; -+ const char *dirname; -+ grub_file_t file; -+}; -+ -+static int read_entry ( -+ const char *filename, -+ const struct grub_dirhook_info *dirhook_info UNUSED, -+ void *data) -+{ -+ grub_size_t m = 0, n, clip = 0; -+ int rc = 0; -+ char *p = NULL; -+ grub_file_t f = NULL; -+ struct bls_entry *entry; -+ struct read_entry_info *info = (struct read_entry_info *)data; -+ -+ grub_dprintf ("blscfg", "filename: \"%s\"\n", filename); -+ -+ n = grub_strlen (filename); -+ -+ if (info->file) -+ { -+ f = info->file; -+ } -+ else -+ { -+ if (filename[0] == '.') -+ return 0; -+ -+ if (n <= 5) -+ return 0; -+ -+ if (grub_strcmp (filename + n - 5, ".conf") != 0) -+ return 0; -+ -+ p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename); -+ -+ f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG); -+ if (!f) -+ goto finish; -+ } -+ -+ entry = grub_zalloc (sizeof (*entry)); -+ if (!entry) -+ goto finish; -+ -+ if (info->file) -+ { -+ char *slash; -+ -+ if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0) -+ clip = 5; -+ -+ slash = grub_strrchr (filename, '/'); -+ if (!slash) -+ slash = grub_strrchr (filename, '\\'); -+ -+ while (*slash == '/' || *slash == '\\') -+ slash++; -+ -+ m = slash ? slash - filename : 0; -+ } -+ else -+ { -+ m = 0; -+ clip = 5; -+ } -+ n -= m; -+ -+ entry->filename = grub_strndup(filename + m, n - clip); -+ if (!entry->filename) -+ goto finish; -+ -+ entry->filename[n - 5] = '\0'; -+ -+ for (;;) -+ { -+ char *buf; -+ char *separator; -+ -+ buf = grub_file_getline (f); -+ if (!buf) -+ break; -+ -+ while (buf && buf[0] && (buf[0] == ' ' || buf[0] == '\t')) -+ buf++; -+ if (buf[0] == '#') -+ continue; -+ -+ separator = grub_strchr (buf, ' '); -+ -+ if (!separator) -+ separator = grub_strchr (buf, '\t'); -+ -+ if (!separator || separator[1] == '\0') -+ { -+ grub_free (buf); -+ break; -+ } -+ -+ separator[0] = '\0'; -+ -+ do { -+ separator++; -+ } while (*separator == ' ' || *separator == '\t'); -+ -+ rc = bls_add_keyval (entry, buf, separator); -+ grub_free (buf); -+ if (rc < 0) -+ break; -+ } -+ -+ if (!rc) -+ bls_add_entry(entry); -+ -+finish: -+ if (p) -+ grub_free (p); -+ -+ if (f) -+ grub_file_close (f); -+ -+ return 0; -+} -+ -+static grub_envblk_t saved_env = NULL; -+ -+static int UNUSED -+save_var (const char *name, const char *value, void *whitelist UNUSED) -+{ -+ const char *val = grub_env_get (name); -+ grub_dprintf("blscfg", "saving \"%s\"\n", name); -+ -+ if (val) -+ grub_envblk_set (saved_env, name, value); -+ -+ return 0; -+} -+ -+static int UNUSED -+unset_var (const char *name, const char *value UNUSED, void *whitelist) -+{ -+ grub_dprintf("blscfg", "restoring \"%s\"\n", name); -+ if (! whitelist) -+ { -+ grub_env_unset (name); -+ return 0; -+ } -+ -+ if (test_whitelist_membership (name, -+ (const grub_env_whitelist_t *) whitelist)) -+ grub_env_unset (name); -+ -+ return 0; -+} -+ -+static char **bls_make_list (struct bls_entry *entry, const char *key, int *num) -+{ -+ int last = -1; -+ char *val; -+ -+ int nlist = 0; -+ char **list = NULL; -+ -+ list = grub_malloc (sizeof (char *)); -+ if (!list) -+ return NULL; -+ list[0] = NULL; -+ -+ while (1) -+ { -+ char **new; -+ -+ val = bls_get_val (entry, key, &last); -+ if (!val) -+ break; -+ -+ new = grub_realloc (list, (nlist + 2) * sizeof (char *)); -+ if (!new) -+ break; -+ -+ list = new; -+ list[nlist++] = val; -+ list[nlist] = NULL; -+ } -+ -+ if (!nlist) -+ { -+ grub_free (list); -+ return NULL; -+ } -+ -+ if (num) -+ *num = nlist; -+ -+ return list; -+} -+ -+static char *field_append(bool is_var, char *buffer, const char *start, const char *end) -+{ -+ char *tmp = grub_strndup(start, end - start + 1); -+ const char *field = tmp; -+ int term = is_var ? 2 : 1; -+ -+ if (is_var) { -+ field = grub_env_get (tmp); -+ if (!field) -+ return buffer; -+ } -+ -+ if (!buffer) -+ buffer = grub_zalloc (grub_strlen(field) + term); -+ else -+ buffer = grub_realloc (buffer, grub_strlen(buffer) + grub_strlen(field) + term); -+ -+ if (!buffer) -+ return NULL; -+ -+ tmp = buffer + grub_strlen(buffer); -+ tmp = grub_stpcpy (tmp, field); -+ -+ if (is_var) -+ tmp = grub_stpcpy (tmp, " "); -+ -+ return buffer; -+} -+ -+static char *expand_val(const char *value) -+{ -+ char *buffer = NULL; -+ const char *start = value; -+ const char *end = value; -+ bool is_var = false; -+ -+ if (!value) -+ return NULL; -+ -+ while (*value) { -+ if (*value == '$') { -+ if (start != end) { -+ buffer = field_append(is_var, buffer, start, end); -+ if (!buffer) -+ return NULL; -+ } -+ -+ is_var = true; -+ start = value + 1; -+ } else if (is_var) { -+ if (!grub_isalnum(*value) && *value != '_') { -+ buffer = field_append(is_var, buffer, start, end); -+ is_var = false; -+ start = value; -+ if (*start == ' ') -+ start++; -+ } -+ } -+ -+ end = value; -+ value++; -+ } -+ -+ if (start != end) { -+ buffer = field_append(is_var, buffer, start, end); -+ if (!buffer) -+ return NULL; -+ } -+ -+ return buffer; -+} -+ -+static char **early_initrd_list (const char *initrd) -+{ -+ int nlist = 0; -+ char **list = NULL; -+ char *separator; -+ -+ while ((separator = grub_strchr (initrd, ' '))) -+ { -+ list = grub_realloc (list, (nlist + 2) * sizeof (char *)); -+ if (!list) -+ return NULL; -+ -+ list[nlist++] = grub_strndup(initrd, separator - initrd); -+ list[nlist] = NULL; -+ initrd = separator + 1; -+ } -+ -+ list = grub_realloc (list, (nlist + 2) * sizeof (char *)); -+ if (!list) -+ return NULL; -+ -+ list[nlist++] = grub_strndup(initrd, grub_strlen(initrd)); -+ list[nlist] = NULL; -+ -+ return list; -+} -+ -+static void create_entry (struct bls_entry *entry) -+{ -+ int argc = 0; -+ const char **argv = NULL; -+ -+ char *title = NULL; -+ char *clinux = NULL; -+ char *options = NULL; -+ char **initrds = NULL; -+ char *initrd = NULL; -+ const char *early_initrd = NULL; -+ char **early_initrds = NULL; -+ char *initrd_prefix = NULL; -+ char *devicetree = NULL; -+ char *dt = NULL; -+ char *id = entry->filename; -+ char *dotconf = id; -+ char *hotkey = NULL; -+ -+ char *users = NULL; -+ char **classes = NULL; -+ -+ char **args = NULL; -+ -+ char *src = NULL; -+ int i, index; -+ bool add_dt_prefix = false; -+ -+ grub_dprintf("blscfg", "%s got here\n", __func__); -+ clinux = bls_get_val (entry, "linux", NULL); -+ if (!clinux) -+ { -+ grub_dprintf ("blscfg", "Skipping file %s with no 'linux' key.\n", entry->filename); -+ goto finish; -+ } -+ -+ /* -+ * strip the ".conf" off the end before we make it our "id" field. -+ */ -+ do -+ { -+ dotconf = grub_strstr(dotconf, ".conf"); -+ } while (dotconf != NULL && dotconf[5] != '\0'); -+ if (dotconf) -+ dotconf[0] = '\0'; -+ -+ title = bls_get_val (entry, "title", NULL); -+ options = expand_val (bls_get_val (entry, "options", NULL)); -+ -+ if (!options) -+ options = expand_val (grub_env_get("default_kernelopts")); -+ -+ initrds = bls_make_list (entry, "initrd", NULL); -+ -+ devicetree = expand_val (bls_get_val (entry, "devicetree", NULL)); -+ -+ if (!devicetree) -+ { -+ devicetree = expand_val (grub_env_get("devicetree")); -+ add_dt_prefix = true; -+ } -+ -+ hotkey = bls_get_val (entry, "grub_hotkey", NULL); -+ users = expand_val (bls_get_val (entry, "grub_users", NULL)); -+ classes = bls_make_list (entry, "grub_class", NULL); -+ args = bls_make_list (entry, "grub_arg", &argc); -+ -+ argc += 1; -+ argv = grub_malloc ((argc + 1) * sizeof (char *)); -+ argv[0] = title ? title : clinux; -+ for (i = 1; i < argc; i++) -+ argv[i] = args[i-1]; -+ argv[argc] = NULL; -+ -+ early_initrd = grub_env_get("early_initrd"); -+ -+ grub_dprintf ("blscfg", "adding menu entry for \"%s\" with id \"%s\"\n", -+ title, id); -+ if (early_initrd) -+ { -+ early_initrds = early_initrd_list(early_initrd); -+ if (!early_initrds) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ -+ if (initrds != NULL && initrds[0] != NULL) -+ { -+ initrd_prefix = grub_strrchr (initrds[0], '/'); -+ initrd_prefix = grub_strndup(initrds[0], initrd_prefix - initrds[0] + 1); -+ } -+ else -+ { -+ initrd_prefix = grub_strrchr (clinux, '/'); -+ initrd_prefix = grub_strndup(clinux, initrd_prefix - clinux + 1); -+ } -+ -+ if (!initrd_prefix) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ } -+ -+ if (early_initrds || initrds) -+ { -+ int initrd_size = sizeof ("initrd"); -+ char *tmp; -+ -+ for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) -+ initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \ -+ + grub_strlen(initrd_prefix) \ -+ + grub_strlen (early_initrds[i]) + 1; -+ -+ for (i = 0; initrds != NULL && initrds[i] != NULL; i++) -+ initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \ -+ + grub_strlen (initrds[i]) + 1; -+ initrd_size += 1; -+ -+ initrd = grub_malloc (initrd_size); -+ if (!initrd) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ -+ tmp = grub_stpcpy(initrd, "initrd"); -+ for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) -+ { -+ grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]); -+ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); -+ tmp = grub_stpcpy (tmp, initrd_prefix); -+ tmp = grub_stpcpy (tmp, early_initrds[i]); -+ grub_free(early_initrds[i]); -+ } -+ -+ for (i = 0; initrds != NULL && initrds[i] != NULL; i++) -+ { -+ grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]); -+ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); -+ tmp = grub_stpcpy (tmp, initrds[i]); -+ } -+ tmp = grub_stpcpy (tmp, "\n"); -+ } -+ -+ if (devicetree) -+ { -+ char *prefix = NULL; -+ int dt_size; -+ -+ if (add_dt_prefix) -+ { -+ prefix = grub_strrchr (clinux, '/'); -+ prefix = grub_strndup(clinux, prefix - clinux + 1); -+ if (!prefix) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ } -+ -+ dt_size = sizeof("devicetree " GRUB_BOOT_DEVICE) + grub_strlen(devicetree) + 1; -+ -+ if (add_dt_prefix) -+ { -+ dt_size += grub_strlen(prefix); -+ } -+ -+ dt = grub_malloc (dt_size); -+ if (!dt) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ char *tmp = dt; -+ tmp = grub_stpcpy (dt, "devicetree"); -+ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); -+ if (add_dt_prefix) -+ tmp = grub_stpcpy (tmp, prefix); -+ tmp = grub_stpcpy (tmp, devicetree); -+ tmp = grub_stpcpy (tmp, "\n"); -+ -+ grub_free(prefix); -+ } -+ -+ grub_dprintf ("blscfg2", "devicetree %s for id:\"%s\"\n", dt, id); -+ -+ const char *sdval = grub_env_get("save_default"); -+ bool savedefault = ((NULL != sdval) && (grub_strcmp(sdval, "true") == 0)); -+ src = grub_xasprintf ("%sload_video\n" -+ "set gfxpayload=keep\n" -+ "insmod gzio\n" -+ "linux %s%s%s%s\n" -+ "%s%s", -+ savedefault ? "savedefault\n" : "", -+ GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "", -+ initrd ? initrd : "", dt ? dt : ""); -+ -+ grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry); -+ grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id); -+ -+finish: -+ grub_free (dt); -+ grub_free (initrd); -+ grub_free (initrd_prefix); -+ grub_free (early_initrds); -+ grub_free (devicetree); -+ grub_free (initrds); -+ grub_free (options); -+ grub_free (classes); -+ grub_free (args); -+ grub_free (argv); -+ grub_free (src); -+} -+ -+struct find_entry_info { -+ const char *dirname; -+ const char *devid; -+ grub_device_t dev; -+ grub_fs_t fs; -+}; -+ -+/* -+ * info: the filesystem object the file is on. -+ */ -+static int find_entry (struct find_entry_info *info) -+{ -+ struct read_entry_info read_entry_info; -+ grub_fs_t blsdir_fs = NULL; -+ grub_device_t blsdir_dev = NULL; -+ const char *blsdir = info->dirname; -+ int fallback = 0; -+ int r = 0; -+ -+ if (!blsdir) { -+ blsdir = grub_env_get ("blsdir"); -+ if (!blsdir) -+ blsdir = GRUB_BLS_CONFIG_PATH; -+ } -+ -+ read_entry_info.file = NULL; -+ read_entry_info.dirname = blsdir; -+ -+ grub_dprintf ("blscfg", "scanning blsdir: %s\n", blsdir); -+ -+ blsdir_dev = info->dev; -+ blsdir_fs = info->fs; -+ read_entry_info.devid = info->devid; -+ -+read_fallback: -+ r = blsdir_fs->fs_dir (blsdir_dev, read_entry_info.dirname, read_entry, -+ &read_entry_info); -+ if (r != 0) { -+ grub_dprintf ("blscfg", "read_entry returned error\n"); -+ grub_err_t e; -+ do -+ { -+ e = grub_error_pop(); -+ } while (e); -+ } -+ -+ if (r && !info->dirname && !fallback) { -+ read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH; -+ grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n", -+ blsdir, read_entry_info.dirname); -+ fallback = 1; -+ goto read_fallback; -+ } -+ -+ return 0; -+} -+ -+static grub_err_t -+bls_load_entries (const char *path) -+{ -+ grub_size_t len; -+ grub_fs_t fs; -+ grub_device_t dev; -+ static grub_err_t r; -+ const char *devid = NULL; -+ char *blsdir = NULL; -+ struct find_entry_info info = { -+ .dev = NULL, -+ .fs = NULL, -+ .dirname = NULL, -+ }; -+ struct read_entry_info rei = { -+ .devid = NULL, -+ .dirname = NULL, -+ }; -+ -+ if (path) { -+ len = grub_strlen (path); -+ if (grub_strcmp (path + len - 5, ".conf") == 0) { -+ rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG); -+ if (!rei.file) -+ return grub_errno; -+ /* -+ * read_entry() closes the file -+ */ -+ return read_entry(path, NULL, &rei); -+ } else if (path[0] == '(') { -+ devid = path + 1; -+ -+ blsdir = grub_strchr (path, ')'); -+ if (!blsdir) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Filepath isn't correct")); -+ -+ *blsdir = '\0'; -+ blsdir = blsdir + 1; -+ } -+ } -+ -+ if (!devid) { -+#ifdef GRUB_MACHINE_EMU -+ devid = "host"; -+#else -+ devid = grub_env_get ("root"); -+#endif -+ if (!devid) -+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, -+ N_("variable `%s' isn't set"), "root"); -+ } -+ -+ grub_dprintf ("blscfg", "opening %s\n", devid); -+ dev = grub_device_open (devid); -+ if (!dev) -+ return grub_errno; -+ -+ grub_dprintf ("blscfg", "probing fs\n"); -+ fs = grub_fs_probe (dev); -+ if (!fs) -+ { -+ r = grub_errno; -+ goto finish; -+ } -+ -+ info.dirname = blsdir; -+ info.devid = devid; -+ info.dev = dev; -+ info.fs = fs; -+ find_entry(&info); -+ -+finish: -+ if (dev) -+ grub_device_close (dev); -+ -+ return r; -+} -+ -+static bool -+is_default_entry(const char *def_entry, struct bls_entry *entry, int idx) -+{ -+ const char *title; -+ int def_idx; -+ -+ if (!def_entry) -+ return false; -+ -+ if (grub_strcmp(def_entry, entry->filename) == 0) -+ return true; -+ -+ title = bls_get_val(entry, "title", NULL); -+ -+ if (title && grub_strcmp(def_entry, title) == 0) -+ return true; -+ -+ def_idx = (int)grub_strtol(def_entry, NULL, 0); -+ if (grub_errno == GRUB_ERR_BAD_NUMBER) { -+ grub_errno = GRUB_ERR_NONE; -+ return false; -+ } -+ -+ if (def_idx == idx) -+ return true; -+ -+ return false; -+} -+ -+static grub_err_t -+bls_create_entries (bool show_default, bool show_non_default, char *entry_id) -+{ -+ const char *def_entry = NULL; -+ struct bls_entry *entry = NULL; -+ int idx = 0; -+ -+ def_entry = grub_env_get("default"); -+ -+ grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__); -+ FOR_BLS_ENTRIES(entry) { -+ if (entry->visible) { -+ idx++; -+ continue; -+ } -+ -+ if ((show_default && is_default_entry(def_entry, entry, idx)) || -+ (show_non_default && !is_default_entry(def_entry, entry, idx)) || -+ (entry_id && grub_strcmp(entry_id, entry->filename) == 0)) { -+ create_entry(entry); -+ entry->visible = 1; -+ } -+ idx++; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, -+ int argc, char **args) -+{ -+ grub_err_t r; -+ char *path = NULL; -+ char *entry_id = NULL; -+ bool show_default = true; -+ bool show_non_default = true; -+ -+ if (argc == 1) { -+ if (grub_strcmp (args[0], "default") == 0) { -+ show_non_default = false; -+ } else if (grub_strcmp (args[0], "non-default") == 0) { -+ show_default = false; -+ } else if (args[0][0] == '(') { -+ path = args[0]; -+ } else { -+ entry_id = args[0]; -+ show_default = false; -+ show_non_default = false; -+ } -+ } -+ -+ r = bls_load_entries(path); -+ if (r) -+ return r; -+ -+ return bls_create_entries(show_default, show_non_default, entry_id); -+} -+ -+static grub_extcmd_t cmd; -+static grub_extcmd_t oldcmd; -+ -+GRUB_MOD_INIT(blscfg) -+{ -+ grub_dprintf("blscfg", "%s got here\n", __func__); -+ cmd = grub_register_extcmd ("blscfg", -+ grub_cmd_blscfg, -+ 0, -+ NULL, -+ N_("Import Boot Loader Specification snippets."), -+ NULL); -+ oldcmd = grub_register_extcmd ("bls_import", -+ grub_cmd_blscfg, -+ 0, -+ NULL, -+ N_("Import Boot Loader Specification snippets."), -+ NULL); -+} -+ -+GRUB_MOD_FINI(blscfg) -+{ -+ grub_unregister_extcmd (cmd); -+ grub_unregister_extcmd (oldcmd); -+} -diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c -index cc5971f4dbd..782761c31aa 100644 ---- a/grub-core/commands/legacycfg.c -+++ b/grub-core/commands/legacycfg.c -@@ -143,7 +143,7 @@ legacy_file (const char *filename) - args[0] = oldname; - grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", - NULL, NULL, -- entrysrc, 0); -+ entrysrc, 0, NULL, NULL); - grub_free (args); - entrysrc[0] = 0; - grub_free (oldname); -@@ -205,7 +205,8 @@ legacy_file (const char *filename) - } - args[0] = entryname; - grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, -- NULL, NULL, entrysrc, 0); -+ NULL, NULL, entrysrc, 0, NULL, -+ NULL); - grub_free (args); - } - -diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c -index 3fd664aac33..163b9a09042 100644 ---- a/grub-core/commands/loadenv.c -+++ b/grub-core/commands/loadenv.c -@@ -28,6 +28,8 @@ - #include - #include - -+#include "loadenv.h" -+ - GRUB_MOD_LICENSE ("GPLv3+"); - - static const struct grub_arg_option options[] = -@@ -79,81 +81,6 @@ open_envblk_file (char *filename, - return file; - } - --static grub_envblk_t --read_envblk_file (grub_file_t file) --{ -- grub_off_t offset = 0; -- char *buf; -- grub_size_t size = grub_file_size (file); -- grub_envblk_t envblk; -- -- buf = grub_malloc (size); -- if (! buf) -- return 0; -- -- while (size > 0) -- { -- grub_ssize_t ret; -- -- ret = grub_file_read (file, buf + offset, size); -- if (ret <= 0) -- { -- grub_free (buf); -- return 0; -- } -- -- size -= ret; -- offset += ret; -- } -- -- envblk = grub_envblk_open (buf, offset); -- if (! envblk) -- { -- grub_free (buf); -- grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); -- return 0; -- } -- -- return envblk; --} -- --struct grub_env_whitelist --{ -- grub_size_t len; -- char **list; --}; --typedef struct grub_env_whitelist grub_env_whitelist_t; -- --static int --test_whitelist_membership (const char* name, -- const grub_env_whitelist_t* whitelist) --{ -- grub_size_t i; -- -- for (i = 0; i < whitelist->len; i++) -- if (grub_strcmp (name, whitelist->list[i]) == 0) -- return 1; /* found it */ -- -- return 0; /* not found */ --} -- --/* Helper for grub_cmd_load_env. */ --static int --set_var (const char *name, const char *value, void *whitelist) --{ -- if (! whitelist) -- { -- grub_env_set (name, value); -- return 0; -- } -- -- if (test_whitelist_membership (name, -- (const grub_env_whitelist_t *) whitelist)) -- grub_env_set (name, value); -- -- return 0; --} -- - static grub_err_t - grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) - { -diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c -index 720e6d8ea3b..b194123eb67 100644 ---- a/grub-core/commands/menuentry.c -+++ b/grub-core/commands/menuentry.c -@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args, - char **classes, const char *id, - const char *users, const char *hotkey, - const char *prefix, const char *sourcecode, -- int submenu) -+ int submenu, int *index, struct bls_entry *bls) - { - int menu_hotkey = 0; - char **menu_args = NULL; -@@ -149,9 +149,12 @@ grub_normal_add_menu_entry (int argc, const char **args, - if (! menu_title) - goto fail; - -+ grub_dprintf ("menu", "id:\"%s\"\n", id); -+ grub_dprintf ("menu", "title:\"%s\"\n", menu_title); - menu_id = grub_strdup (id ? : menu_title); - if (! menu_id) - goto fail; -+ grub_dprintf ("menu", "menu_id:\"%s\"\n", menu_id); - - /* Save argc, args to pass as parameters to block arg later. */ - menu_args = grub_calloc (argc + 1, sizeof (char *)); -@@ -170,8 +173,12 @@ grub_normal_add_menu_entry (int argc, const char **args, - } - - /* Add the menu entry at the end of the list. */ -+ int ind=0; - while (*last) -- last = &(*last)->next; -+ { -+ ind++; -+ last = &(*last)->next; -+ } - - *last = grub_zalloc (sizeof (**last)); - if (! *last) -@@ -188,8 +195,11 @@ grub_normal_add_menu_entry (int argc, const char **args, - (*last)->args = menu_args; - (*last)->sourcecode = menu_sourcecode; - (*last)->submenu = submenu; -+ (*last)->bls = bls; - - menu->size++; -+ if (index) -+ *index = ind; - return GRUB_ERR_NONE; - - fail: -@@ -286,7 +296,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) - users, - ctxt->state[2].arg, 0, - ctxt->state[3].arg, -- ctxt->extcmd->cmd->name[0] == 's'); -+ ctxt->extcmd->cmd->name[0] == 's', -+ NULL, NULL); - - src = args[argc - 1]; - args[argc - 1] = NULL; -@@ -303,7 +314,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) - ctxt->state[0].args, ctxt->state[4].arg, - users, - ctxt->state[2].arg, prefix, src + 1, -- ctxt->extcmd->cmd->name[0] == 's'); -+ ctxt->extcmd->cmd->name[0] == 's', NULL, -+ NULL); - - src[len - 1] = ch; - args[argc - 1] = src; -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 62571e6dfcc..7ca2e5400b1 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -70,6 +71,11 @@ grub_normal_free_menu (grub_menu_t menu) - grub_free (entry->args); - } - -+ if (entry->bls) -+ { -+ entry->bls->visible = 0; -+ } -+ - grub_free ((void *) entry->id); - grub_free ((void *) entry->users); - grub_free ((void *) entry->title); -diff --git a/grub-core/commands/loadenv.h b/grub-core/commands/loadenv.h -new file mode 100644 -index 00000000000..952f46121bd ---- /dev/null -+++ b/grub-core/commands/loadenv.h -@@ -0,0 +1,93 @@ -+/* loadenv.c - command to load/save environment variable. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+static grub_envblk_t UNUSED -+read_envblk_file (grub_file_t file) -+{ -+ grub_off_t offset = 0; -+ char *buf; -+ grub_size_t size = grub_file_size (file); -+ grub_envblk_t envblk; -+ -+ buf = grub_malloc (size); -+ if (! buf) -+ return 0; -+ -+ while (size > 0) -+ { -+ grub_ssize_t ret; -+ -+ ret = grub_file_read (file, buf + offset, size); -+ if (ret <= 0) -+ { -+ grub_free (buf); -+ return 0; -+ } -+ -+ size -= ret; -+ offset += ret; -+ } -+ -+ envblk = grub_envblk_open (buf, offset); -+ if (! envblk) -+ { -+ grub_free (buf); -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); -+ return 0; -+ } -+ -+ return envblk; -+} -+ -+struct grub_env_whitelist -+{ -+ grub_size_t len; -+ char **list; -+}; -+typedef struct grub_env_whitelist grub_env_whitelist_t; -+ -+static int UNUSED -+test_whitelist_membership (const char* name, -+ const grub_env_whitelist_t* whitelist) -+{ -+ grub_size_t i; -+ -+ for (i = 0; i < whitelist->len; i++) -+ if (grub_strcmp (name, whitelist->list[i]) == 0) -+ return 1; /* found it */ -+ -+ return 0; /* not found */ -+} -+ -+/* Helper for grub_cmd_load_env. */ -+static int UNUSED -+set_var (const char *name, const char *value, void *whitelist) -+{ -+ if (! whitelist) -+ { -+ grub_env_set (name, value); -+ return 0; -+ } -+ -+ if (test_whitelist_membership (name, -+ (const grub_env_whitelist_t *) whitelist)) -+ grub_env_set (name, value); -+ -+ return 0; -+} -diff --git a/include/grub/compiler.h b/include/grub/compiler.h -index 8f3be3ae706..ebafec68957 100644 ---- a/include/grub/compiler.h -+++ b/include/grub/compiler.h -@@ -56,4 +56,6 @@ - # define CLANG_PREREQ(maj,min) 0 - #endif - -+#define UNUSED __attribute__((__unused__)) -+ - #endif /* ! GRUB_COMPILER_HEADER */ -diff --git a/include/grub/menu.h b/include/grub/menu.h -index ee2b5e91045..0acdc2aa6bf 100644 ---- a/include/grub/menu.h -+++ b/include/grub/menu.h -@@ -20,6 +20,16 @@ - #ifndef GRUB_MENU_HEADER - #define GRUB_MENU_HEADER 1 - -+struct bls_entry -+{ -+ struct bls_entry *next; -+ struct bls_entry *prev; -+ struct keyval **keyvals; -+ int nkeyvals; -+ char *filename; -+ int visible; -+}; -+ - struct grub_menu_entry_class - { - char *name; -@@ -60,6 +70,9 @@ struct grub_menu_entry - - /* The next element. */ - struct grub_menu_entry *next; -+ -+ /* BLS used to populate the entry */ -+ struct bls_entry *bls; - }; - typedef struct grub_menu_entry *grub_menu_entry_t; - -diff --git a/include/grub/normal.h b/include/grub/normal.h -index 218cbabccaf..8839ad85a19 100644 ---- a/include/grub/normal.h -+++ b/include/grub/normal.h -@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, - const char *id, - const char *users, const char *hotkey, - const char *prefix, const char *sourcecode, -- int submenu); -+ int submenu, int *index, struct bls_entry *bls); - - grub_err_t - grub_normal_set_password (const char *user, const char *password); diff --git a/0022-Add-devicetree-loading.patch b/0022-Add-devicetree-loading.patch deleted file mode 100644 index c0728a9..0000000 --- a/0022-Add-devicetree-loading.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 14 Jan 2014 13:12:23 -0500 -Subject: [PATCH] Add devicetree loading - -Signed-off-by: Peter Jones - -Switch to use APM Mustang device tree, for hardware testing. - -Signed-off-by: David A. Marlin - -Use the default device tree from the grub default file - -instead of hardcoding a value. - -Signed-off-by: David A. Marlin ---- - util/grub-mkconfig.in | 3 ++- - util/grub.d/10_linux.in | 15 +++++++++++++++ - 2 files changed, 17 insertions(+), 1 deletion(-) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index d3e879b8e5c..8ea2315ebc2 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -248,7 +248,8 @@ export GRUB_DEFAULT \ - GRUB_ENABLE_CRYPTODISK \ - GRUB_BADRAM \ - GRUB_OS_PROBER_SKIP_LIST \ -- GRUB_DISABLE_SUBMENU -+ GRUB_DISABLE_SUBMENU \ -+ GRUB_DEFAULT_DTB - - if test "x${grub_cfg}" != "x"; then - rm -f "${grub_cfg}.new" -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index e8b01c0d0c7..dc75a1c30bf 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -153,6 +153,13 @@ EOF - sed "s/^/$submenu_indentation/" << EOF - echo '$(echo "$message" | grub_quote)' - initrd $(echo $initrd_path) -+EOF -+ fi -+ if test -n "${fdt}" ; then -+ message="$(gettext_printf "Loading fdt ...")" -+ sed "s/^/$submenu_indentation/" << EOF -+ echo '$(echo "$message" | grub_quote)' -+ devicetree ${rel_dirname}/${fdt} - EOF - fi - sed "s/^/$submenu_indentation/" << EOF -@@ -236,6 +243,14 @@ while [ "x$list" != "x" ] ; do - gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 - fi - -+ fdt= -+ for i in "dtb-${version}" "dtb-${alt_version}"; do -+ if test -f "${dirname}/${i}/${GRUB_DEFAULT_DTB}" ; then -+ fdt="${i}/${GRUB_DEFAULT_DTB}" -+ break -+ fi -+ done -+ - config= - for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do - if test -e "${i}" ; then diff --git a/0023-Enable-pager-by-default.-985860.patch b/0023-Enable-pager-by-default.-985860.patch deleted file mode 100644 index d92fbcc..0000000 --- a/0023-Enable-pager-by-default.-985860.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 28 Oct 2013 10:09:27 -0400 -Subject: [PATCH] Enable pager by default. (#985860) - -Signed-off-by: Peter Jones ---- - util/grub.d/00_header.in | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in -index 93a90233ead..858b526c925 100644 ---- a/util/grub.d/00_header.in -+++ b/util/grub.d/00_header.in -@@ -43,6 +43,8 @@ if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_ - if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi - - cat << EOF -+set pager=1 -+ - if [ -s \$prefix/grubenv ]; then - load_env - fi diff --git a/0024-Don-t-say-GNU-Linux-in-generated-menus.patch b/0024-Don-t-say-GNU-Linux-in-generated-menus.patch deleted file mode 100644 index f288095..0000000 --- a/0024-Don-t-say-GNU-Linux-in-generated-menus.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 14 Mar 2011 14:27:42 -0400 -Subject: [PATCH] Don't say "GNU/Linux" in generated menus. - ---- - util/grub.d/10_linux.in | 4 ++-- - util/grub.d/20_linux_xen.in | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index dc75a1c30bf..4a499c53a61 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" - CLASS="--class gnu-linux --class gnu --class os" - - if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then -- OS=GNU/Linux -+ OS="$(sed 's, release .*$,,g' /etc/system-release)" - else -- OS="${GRUB_DISTRIBUTOR} GNU/Linux" -+ OS="${GRUB_DISTRIBUTOR}" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" - fi - -diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in -index 3b1f4704921..ada20775a14 100644 ---- a/util/grub.d/20_linux_xen.in -+++ b/util/grub.d/20_linux_xen.in -@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" - CLASS="--class gnu-linux --class gnu --class os --class xen" - - if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then -- OS=GNU/Linux -+ OS="$(sed 's, release .*$,,g' /etc/system-release)" - else -- OS="${GRUB_DISTRIBUTOR} GNU/Linux" -+ OS="${GRUB_DISTRIBUTOR}" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" - fi - diff --git a/0025-Add-.eh_frame-to-list-of-relocations-stripped.patch b/0025-Add-.eh_frame-to-list-of-relocations-stripped.patch deleted file mode 100644 index ed48c5c..0000000 --- a/0025-Add-.eh_frame-to-list-of-relocations-stripped.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Mon, 13 Jan 2014 21:50:59 -0500 -Subject: [PATCH] Add .eh_frame to list of relocations stripped - ---- - conf/Makefile.common | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 2a1a886f6d5..191b1a70c6b 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -38,7 +38,7 @@ CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding - LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) - CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 - CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) --STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -+STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx - - CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding - LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d diff --git a/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch b/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch deleted file mode 100644 index ac9475e..0000000 --- a/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 11 Feb 2014 11:14:50 -0500 -Subject: [PATCH] Don't require a password to boot entries generated by - grub-mkconfig. - -When we set a password, we just want that to mean you can't /edit/ an entry. - -Resolves: rhbz#1030176 - -Signed-off-by: Peter Jones ---- - util/grub.d/10_linux.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 4a499c53a61..cf8d1186981 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -26,7 +26,7 @@ datarootdir="@datarootdir@" - export TEXTDOMAIN=@PACKAGE@ - export TEXTDOMAINDIR="@localedir@" - --CLASS="--class gnu-linux --class gnu --class os" -+CLASS="--class gnu-linux --class gnu --class os --unrestricted" - - if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then - OS="$(sed 's, release .*$,,g' /etc/system-release)" diff --git a/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch b/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch deleted file mode 100644 index daa6fae..0000000 --- a/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch +++ /dev/null @@ -1,1959 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 4 Mar 2014 11:00:23 -0500 -Subject: [PATCH] Replace a lot of man pages with slightly nicer ones. - -Replace a bunch of machine generated ones with ones that look nicer. ---- - configure.ac | 23 ++++++ - conf/Makefile.extra-dist | 1 - - docs/Makefile.am | 2 - - docs/man/grub-bios-setup.h2m | 6 -- - docs/man/grub-editenv.h2m | 5 -- - docs/man/grub-emu.h2m | 6 -- - docs/man/grub-file.h2m | 2 - - docs/man/grub-fstest.h2m | 4 - - docs/man/grub-glue-efi.h2m | 4 - - docs/man/grub-install.h2m | 6 -- - docs/man/grub-kbdcomp.h2m | 10 --- - docs/man/grub-macbless.h2m | 4 - - docs/man/grub-macho2img.h2m | 4 - - docs/man/grub-menulst2cfg.h2m | 4 - - docs/man/grub-mkconfig.h2m | 4 - - docs/man/grub-mkfont.h2m | 4 - - docs/man/grub-mkimage.h2m | 6 -- - docs/man/grub-mklayout.h2m | 10 --- - docs/man/grub-mknetdir.h2m | 4 - - docs/man/grub-mkpasswd-pbkdf2.h2m | 4 - - docs/man/grub-mkrelpath.h2m | 4 - - docs/man/grub-mkrescue.h2m | 4 - - docs/man/grub-mkstandalone.h2m | 4 - - docs/man/grub-mount.h2m | 2 - - docs/man/grub-ofpathname.h2m | 4 - - docs/man/grub-pe2elf.h2m | 4 - - docs/man/grub-probe.h2m | 4 - - docs/man/grub-reboot.h2m | 5 -- - docs/man/grub-render-label.h2m | 3 - - docs/man/grub-script-check.h2m | 4 - - docs/man/grub-set-default.h2m | 5 -- - docs/man/grub-sparc64-setup.h2m | 6 -- - docs/man/grub-syslinux2cfg.h2m | 4 - - gentpl.py | 5 +- - util/grub-bios-setup.8 | 54 +++++++++++++ - util/grub-editenv.1 | 46 +++++++++++ - util/grub-file.1 | 165 ++++++++++++++++++++++++++++++++++++++ - util/grub-fstest.1 | 99 +++++++++++++++++++++++ - util/grub-glue-efi.1 | 31 +++++++ - util/grub-install.8 | 128 +++++++++++++++++++++++++++++ - util/grub-kbdcomp.1 | 19 +++++ - util/grub-macbless.1 | 22 +++++ - util/grub-menulst2cfg.1 | 12 +++ - util/grub-mkconfig.8 | 17 ++++ - util/grub-mkfont.1 | 87 ++++++++++++++++++++ - util/grub-mkimage.1 | 95 ++++++++++++++++++++++ - util/grub-mklayout.1 | 27 +++++++ - util/grub-mknetdir.1 | 12 +++ - util/grub-mkpasswd-pbkdf2.1 | 27 +++++++ - util/grub-mkrelpath.1 | 12 +++ - util/grub-mkrescue.1 | 123 ++++++++++++++++++++++++++++ - util/grub-mkstandalone.1 | 100 +++++++++++++++++++++++ - util/grub-ofpathname.8 | 12 +++ - util/grub-probe.8 | 80 ++++++++++++++++++ - util/grub-reboot.8 | 21 +++++ - util/grub-render-label.1 | 51 ++++++++++++ - util/grub-script-check.1 | 21 +++++ - util/grub-set-default.8 | 21 +++++ - util/grub-sparc64-setup.8 | 12 +++ - 59 files changed, 1318 insertions(+), 147 deletions(-) - delete mode 100644 docs/man/grub-bios-setup.h2m - delete mode 100644 docs/man/grub-editenv.h2m - delete mode 100644 docs/man/grub-emu.h2m - delete mode 100644 docs/man/grub-file.h2m - delete mode 100644 docs/man/grub-fstest.h2m - delete mode 100644 docs/man/grub-glue-efi.h2m - delete mode 100644 docs/man/grub-install.h2m - delete mode 100644 docs/man/grub-kbdcomp.h2m - delete mode 100644 docs/man/grub-macbless.h2m - delete mode 100644 docs/man/grub-macho2img.h2m - delete mode 100644 docs/man/grub-menulst2cfg.h2m - delete mode 100644 docs/man/grub-mkconfig.h2m - delete mode 100644 docs/man/grub-mkfont.h2m - delete mode 100644 docs/man/grub-mkimage.h2m - delete mode 100644 docs/man/grub-mklayout.h2m - delete mode 100644 docs/man/grub-mknetdir.h2m - delete mode 100644 docs/man/grub-mkpasswd-pbkdf2.h2m - delete mode 100644 docs/man/grub-mkrelpath.h2m - delete mode 100644 docs/man/grub-mkrescue.h2m - delete mode 100644 docs/man/grub-mkstandalone.h2m - delete mode 100644 docs/man/grub-mount.h2m - delete mode 100644 docs/man/grub-ofpathname.h2m - delete mode 100644 docs/man/grub-pe2elf.h2m - delete mode 100644 docs/man/grub-probe.h2m - delete mode 100644 docs/man/grub-reboot.h2m - delete mode 100644 docs/man/grub-render-label.h2m - delete mode 100644 docs/man/grub-script-check.h2m - delete mode 100644 docs/man/grub-set-default.h2m - delete mode 100644 docs/man/grub-sparc64-setup.h2m - delete mode 100644 docs/man/grub-syslinux2cfg.h2m - create mode 100644 util/grub-bios-setup.8 - create mode 100644 util/grub-editenv.1 - create mode 100644 util/grub-file.1 - create mode 100644 util/grub-fstest.1 - create mode 100644 util/grub-glue-efi.1 - create mode 100644 util/grub-install.8 - create mode 100644 util/grub-kbdcomp.1 - create mode 100644 util/grub-macbless.1 - create mode 100644 util/grub-menulst2cfg.1 - create mode 100644 util/grub-mkconfig.8 - create mode 100644 util/grub-mkfont.1 - create mode 100644 util/grub-mkimage.1 - create mode 100644 util/grub-mklayout.1 - create mode 100644 util/grub-mknetdir.1 - create mode 100644 util/grub-mkpasswd-pbkdf2.1 - create mode 100644 util/grub-mkrelpath.1 - create mode 100644 util/grub-mkrescue.1 - create mode 100644 util/grub-mkstandalone.1 - create mode 100644 util/grub-ofpathname.8 - create mode 100644 util/grub-probe.8 - create mode 100644 util/grub-reboot.8 - create mode 100644 util/grub-render-label.1 - create mode 100644 util/grub-script-check.1 - create mode 100644 util/grub-set-default.8 - create mode 100644 util/grub-sparc64-setup.8 - -diff --git a/configure.ac b/configure.ac -index 8331f95b645..bec8535af70 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -77,6 +77,29 @@ grub_TRANSFORM([grub-set-default]) - grub_TRANSFORM([grub-sparc64-setup]) - grub_TRANSFORM([grub-render-label]) - grub_TRANSFORM([grub-file]) -+grub_TRANSFORM([grub-bios-setup.3]) -+grub_TRANSFORM([grub-editenv.1]) -+grub_TRANSFORM([grub-fstest.3]) -+grub_TRANSFORM([grub-glue-efi.3]) -+grub_TRANSFORM([grub-install.1]) -+grub_TRANSFORM([grub-kbdcomp.3]) -+grub_TRANSFORM([grub-menulst2cfg.1]) -+grub_TRANSFORM([grub-mkconfig.1]) -+grub_TRANSFORM([grub-mkfont.3]) -+grub_TRANSFORM([grub-mkimage.1]) -+grub_TRANSFORM([grub-mklayout.3]) -+grub_TRANSFORM([grub-mknetdir.3]) -+grub_TRANSFORM([grub-mkpasswd-pbkdf2.3]) -+grub_TRANSFORM([grub-mkrelpath.3]) -+grub_TRANSFORM([grub-mkrescue.1]) -+grub_TRANSFORM([grub-mkstandalone.3]) -+grub_TRANSFORM([grub-ofpathname.3]) -+grub_TRANSFORM([grub-probe.3]) -+grub_TRANSFORM([grub-reboot.3]) -+grub_TRANSFORM([grub-render-label.3]) -+grub_TRANSFORM([grub-script-check.3]) -+grub_TRANSFORM([grub-set-default.1]) -+grub_TRANSFORM([grub-sparc64-setup.3]) - - # Optimization flag. Allow user to override. - if test "x$TARGET_CFLAGS" = x; then -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index 8f1485d52a5..b909f2c073a 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -11,7 +11,6 @@ EXTRA_DIST += unicode - EXTRA_DIST += util/import_gcry.py - EXTRA_DIST += util/import_unicode.py - --EXTRA_DIST += docs/man - EXTRA_DIST += docs/autoiso.cfg - EXTRA_DIST += docs/grub.cfg - EXTRA_DIST += docs/osdetect.cfg -diff --git a/docs/Makefile.am b/docs/Makefile.am -index 93eb3962765..ab28f199694 100644 ---- a/docs/Makefile.am -+++ b/docs/Makefile.am -@@ -5,5 +5,3 @@ info_TEXINFOS = grub.texi grub-dev.texi - grub_TEXINFOS = fdl.texi - - EXTRA_DIST = font_char_metrics.png font_char_metrics.txt -- -- -diff --git a/docs/man/grub-bios-setup.h2m b/docs/man/grub-bios-setup.h2m -deleted file mode 100644 -index ac6ede36296..00000000000 ---- a/docs/man/grub-bios-setup.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-bios-setup \- set up a device to boot using GRUB --[SEE ALSO] --.BR grub-install (8), --.BR grub-mkimage (1), --.BR grub-mkrescue (1) -diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m -deleted file mode 100644 -index 3859d3d4c4f..00000000000 ---- a/docs/man/grub-editenv.h2m -+++ /dev/null -@@ -1,5 +0,0 @@ --[NAME] --grub-editenv \- edit GRUB environment block --[SEE ALSO] --.BR grub-reboot (8), --.BR grub-set-default (8) -diff --git a/docs/man/grub-emu.h2m b/docs/man/grub-emu.h2m -deleted file mode 100644 -index ef1c000656a..00000000000 ---- a/docs/man/grub-emu.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-emu \- GRUB emulator --[SEE ALSO] --If you are trying to install GRUB, then you should use --.BR grub-install (8) --rather than this program. -diff --git a/docs/man/grub-file.h2m b/docs/man/grub-file.h2m -deleted file mode 100644 -index e09bb4d3101..00000000000 ---- a/docs/man/grub-file.h2m -+++ /dev/null -@@ -1,2 +0,0 @@ --[NAME] --grub-file \- check file type -diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m -deleted file mode 100644 -index 9676b159afd..00000000000 ---- a/docs/man/grub-fstest.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-fstest \- debug tool for GRUB filesystem drivers --[SEE ALSO] --.BR grub-probe (8) -diff --git a/docs/man/grub-glue-efi.h2m b/docs/man/grub-glue-efi.h2m -deleted file mode 100644 -index c1c6ded49ff..00000000000 ---- a/docs/man/grub-glue-efi.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-glue-efi \- generate a fat binary for EFI --[DESCRIPTION] --grub-glue-efi processes ia32 and amd64 EFI images and glues them according to Apple format. -diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m -deleted file mode 100644 -index 8cbbc87a0f2..00000000000 ---- a/docs/man/grub-install.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-install \- install GRUB to a device --[SEE ALSO] --.BR grub-mkconfig (8), --.BR grub-mkimage (1), --.BR grub-mkrescue (1) -diff --git a/docs/man/grub-kbdcomp.h2m b/docs/man/grub-kbdcomp.h2m -deleted file mode 100644 -index d81f9157e01..00000000000 ---- a/docs/man/grub-kbdcomp.h2m -+++ /dev/null -@@ -1,10 +0,0 @@ --[NAME] --grub-kbdcomp \- generate a GRUB keyboard layout file --[DESCRIPTION] --grub-kbdcomp processes a X keyboard layout description in --.BR keymaps (5) --format into a format that can be used by GRUB's --.B keymap --command. --[SEE ALSO] --.BR grub-mklayout (8) -diff --git a/docs/man/grub-macbless.h2m b/docs/man/grub-macbless.h2m -deleted file mode 100644 -index 0197c0087d7..00000000000 ---- a/docs/man/grub-macbless.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-macbless \- bless a mac file/directory --[SEE ALSO] --.BR grub-install (1) -diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m -deleted file mode 100644 -index d79aaeed8f9..00000000000 ---- a/docs/man/grub-macho2img.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-macho2img \- convert Mach-O to raw image --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-menulst2cfg.h2m b/docs/man/grub-menulst2cfg.h2m -deleted file mode 100644 -index c2e0055ed7e..00000000000 ---- a/docs/man/grub-menulst2cfg.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-menulst2cfg \- transform legacy menu.lst into grub.cfg --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m -deleted file mode 100644 -index 9b42f813010..00000000000 ---- a/docs/man/grub-mkconfig.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkconfig \- generate a GRUB configuration file --[SEE ALSO] --.BR grub-install (8) -diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m -deleted file mode 100644 -index d46fe600eca..00000000000 ---- a/docs/man/grub-mkfont.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkfont \- make GRUB font files --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m -deleted file mode 100644 -index f0fbc2bb197..00000000000 ---- a/docs/man/grub-mkimage.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-mkimage \- make a bootable image of GRUB --[SEE ALSO] --.BR grub-install (8), --.BR grub-mkrescue (1), --.BR grub-mknetdir (8) -diff --git a/docs/man/grub-mklayout.h2m b/docs/man/grub-mklayout.h2m -deleted file mode 100644 -index 1e43409c0ab..00000000000 ---- a/docs/man/grub-mklayout.h2m -+++ /dev/null -@@ -1,10 +0,0 @@ --[NAME] --grub-mklayout \- generate a GRUB keyboard layout file --[DESCRIPTION] --grub-mklayout processes a keyboard layout description in --.BR keymaps (5) --format into a format that can be used by GRUB's --.B keymap --command. --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-mknetdir.h2m b/docs/man/grub-mknetdir.h2m -deleted file mode 100644 -index a2ef13ec111..00000000000 ---- a/docs/man/grub-mknetdir.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mknetdir \- prepare a GRUB netboot directory. --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m -deleted file mode 100644 -index 4d202f3da7e..00000000000 ---- a/docs/man/grub-mkpasswd-pbkdf2.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m -deleted file mode 100644 -index d01f3961e3f..00000000000 ---- a/docs/man/grub-mkrelpath.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkrelpath \- make a system path relative to its root --[SEE ALSO] --.BR grub-probe (8) -diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m -deleted file mode 100644 -index a427f02e3c6..00000000000 ---- a/docs/man/grub-mkrescue.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkrescue \- make a GRUB rescue image --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-mkstandalone.h2m b/docs/man/grub-mkstandalone.h2m -deleted file mode 100644 -index c77313978ad..00000000000 ---- a/docs/man/grub-mkstandalone.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkstandalone \- make a memdisk-based GRUB image --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-mount.h2m b/docs/man/grub-mount.h2m -deleted file mode 100644 -index 8d168982d72..00000000000 ---- a/docs/man/grub-mount.h2m -+++ /dev/null -@@ -1,2 +0,0 @@ --[NAME] --grub-mount \- export GRUB filesystem with FUSE -diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m -deleted file mode 100644 -index 74b43eea039..00000000000 ---- a/docs/man/grub-ofpathname.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-ofpathname \- find OpenBOOT path for a device --[SEE ALSO] --.BR grub-probe (8) -diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m -deleted file mode 100644 -index 7ca29bd703c..00000000000 ---- a/docs/man/grub-pe2elf.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-pe2elf \- convert PE image to ELF --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m -deleted file mode 100644 -index 6e1ffdcf937..00000000000 ---- a/docs/man/grub-probe.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-probe \- probe device information for GRUB --[SEE ALSO] --.BR grub-fstest (1) -diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m -deleted file mode 100644 -index e4acace65ce..00000000000 ---- a/docs/man/grub-reboot.h2m -+++ /dev/null -@@ -1,5 +0,0 @@ --[NAME] --grub-reboot \- set the default boot entry for GRUB, for the next boot only --[SEE ALSO] --.BR grub-set-default (8), --.BR grub-editenv (1) -diff --git a/docs/man/grub-render-label.h2m b/docs/man/grub-render-label.h2m -deleted file mode 100644 -index 50ae5247c05..00000000000 ---- a/docs/man/grub-render-label.h2m -+++ /dev/null -@@ -1,3 +0,0 @@ --[NAME] --grub-render-label \- generate a .disk_label for Apple Macs. -- -diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m -deleted file mode 100644 -index 3653682671a..00000000000 ---- a/docs/man/grub-script-check.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-script-check \- check grub.cfg for syntax errors --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m -deleted file mode 100644 -index 7945001c154..00000000000 ---- a/docs/man/grub-set-default.h2m -+++ /dev/null -@@ -1,5 +0,0 @@ --[NAME] --grub-set-default \- set the saved default boot entry for GRUB --[SEE ALSO] --.BR grub-reboot (8), --.BR grub-editenv (1) -diff --git a/docs/man/grub-sparc64-setup.h2m b/docs/man/grub-sparc64-setup.h2m -deleted file mode 100644 -index 18f803a50db..00000000000 ---- a/docs/man/grub-sparc64-setup.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-sparc64-setup \- set up a device to boot using GRUB --[SEE ALSO] --.BR grub-install (8), --.BR grub-mkimage (1), --.BR grub-mkrescue (1) -diff --git a/docs/man/grub-syslinux2cfg.h2m b/docs/man/grub-syslinux2cfg.h2m -deleted file mode 100644 -index ad25c8ab753..00000000000 ---- a/docs/man/grub-syslinux2cfg.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-syslinux2cfg \- transform syslinux config into grub.cfg --[SEE ALSO] --.BR grub-menulst2cfg (8) -diff --git a/gentpl.py b/gentpl.py -index c86550d4f9e..2cba0bbbd6f 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -805,10 +805,7 @@ def manpage(defn, adddeps): - - output("if COND_MAN_PAGES\n") - gvar_add("man_MANS", name + "." + mansection) -- rule(name + "." + mansection, name + " " + adddeps, """ --chmod a+x """ + name + """ --PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """ --""") -+ rule(name + "." + mansection, name + " " + adddeps, "cat $(top_srcdir)/util/" + name + "." + mansection + " | $(top_builddir)/config.status --file=$@:-") - gvar_add("CLEANFILES", name + "." + mansection) - output("endif\n") - -diff --git a/util/grub-bios-setup.8 b/util/grub-bios-setup.8 -new file mode 100644 -index 00000000000..56f582b3d75 ---- /dev/null -+++ b/util/grub-bios-setup.8 -@@ -0,0 +1,54 @@ -+.TH GRUB-BIOS-SETUP 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-bios-setup\fR \(em Set up images to boot from a device. -+ -+.SH SYNOPSIS -+\fBgrub-bios-setup\fR [-a | --allow-floppy] [-b | --boot-image=\fIFILE\fR] -+.RS 17 -+[-c | --core-image=\fIFILE\fR] [-d | --directory=\fIDIR\fR] -+.RE -+.RS 17 -+[-f | --force] [-m | --device-map=\fIFILE\fR] -+.RE -+.RS 17 -+[-s | --skip-fs-probe] [-v | --verbose] \fIDEVICE\fR -+ -+.SH DESCRIPTION -+You should not normally run this program directly. Use grub-install instead. -+ -+.SH OPTIONS -+.TP -+\fB--allow-floppy\fR -+Make the device also bootable as a floppy. This option is the default for -+/dev/fdX devices. Some BIOSes will not boot images created with this option. -+ -+.TP -+\fB--boot-image\fR=\fIFILE\fR -+Use FILE as the boot image. The default value is \fBboot.img\fR. -+ -+.TP -+\fB--core-image\fR=\fIFILE\fR -+Use FILE as ther core image. The default value is \fBcore.img\fR. -+ -+.TP -+\fB--directory\fR=\fIDIR\fR -+Use GRUB files in the directory DIR. The default value is \fB/boot/grub\fR. -+ -+.TP -+\fB--force\fR -+Install even if problems are detected. -+ -+.TP -+\fB--device-map\fR=\fIFILE\fR -+Use FILE as the device map. The default value is /boot/grub/device.map . -+ -+.TP -+\fB--skip-fs-probe\fR -+Do not probe DEVICE for filesystems. -+ -+.TP -+\fB--verbose\fR -+Print verbose messages. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-editenv.1 b/util/grub-editenv.1 -new file mode 100644 -index 00000000000..d28ba03ba42 ---- /dev/null -+++ b/util/grub-editenv.1 -@@ -0,0 +1,46 @@ -+.TH GRUB-EDITENV 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-editenv\fR \(em Manage the GRUB environment block. -+ -+.SH SYNOPSIS -+\fBgrub-editenv\fR [-v | --verbose] [\fIFILE\fR] -+.RS 14 -+ -+ -+.SH DESCRIPTION -+\fBgrub-editenv\fR is a command line tool to manage GRUB's stored environment. -+ -+.SH OPTIONS -+.TP -+\fB--verbose\fR -+Print verbose messages. -+ -+.TP -+\fBFILE\fR -+.RS 7 -+File name to use for grub environment. Default is /boot/grub/grubenv . -+.RE -+ -+.SH COMMANDS -+.TP -+\fBcreate\fR -+.RS 7 -+Create a blank environment block file. -+.RE -+ -+.TP -+\fBlist\fR -+.RS 7 -+List the current variables. -+.RE -+ -+.TP -+\fBset\fR [\fINAME\fR=\fIVALUE\fR ...] -+Set variables. -+ -+.TP -+\fBunset [\fINAME\fR ...] -+Delete variables. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-file.1 b/util/grub-file.1 -new file mode 100644 -index 00000000000..b29cb327889 ---- /dev/null -+++ b/util/grub-file.1 -@@ -0,0 +1,165 @@ -+.TH GRUB-FILE 1 "Web Feb 26 2014" -+.SH NAME -+\fBgrub-file\fR \(em Check if FILE is of specified type. -+ -+.SH SYNOPSIS -+\fBgrub-file\fR (--is-i386-xen-pae-domu | --is-x86_64-xen-domu | -+.RS 11 -+--is-x86-xen-dom0 | --is-x86-multiboot | -+.RE -+.RS 11 -+--is-x86-multiboot2 | --is-arm-linux | --is-arm64-linux | -+.RE -+.RS 11 -+--is-ia64-linux | --is-mips-linux | --is-mipsel-linux | -+.RE -+.RS 11 -+--is-sparc64-linux | --is-powerpc-linux | --is-x86-linux | -+.RE -+.RS 11 -+--is-x86-linux32 | --is-x86-kfreebsd | --is-i386-kfreebsd | -+.RE -+.RS 11 -+--is-x86_64-kfreebsd | --is-x86-knetbsd | -+.RE -+.RS 11 -+--is-i386-knetbsd | --is-x86_64-knetbsd | --is-i386-efi | -+.RE -+.RS 11 -+--is-x86_64-efi | --is-ia64-efi | --is-arm64-efi | -+.RE -+.RS 11 -+--is-arm-efi | --is-hibernated-hiberfil | --is-x86_64-xnu | -+.RE -+.RS 11 -+--is-i386-xnu | --is-xnu-hibr | --is-x86-bios-bootsector) -+.RE -+.RS 11 -+\fIFILE\fR -+ -+.SH DESCRIPTION -+\fBgrub-file\fR is used to check if \fIFILE\fR is of a specified type. -+ -+.SH OPTIONS -+.TP -+--is-i386-xen-pae-domu -+Check if FILE can be booted as i386 PAE Xen unprivileged guest kernel -+ -+.TP -+--is-x86_64-xen-domu -+Check if FILE can be booted as x86_64 Xen unprivileged guest kernel -+ -+.TP -+--is-x86-xen-dom0 -+Check if FILE can be used as Xen x86 privileged guest kernel -+ -+.TP -+--is-x86-multiboot -+Check if FILE can be used as x86 multiboot kernel -+ -+.TP -+--is-x86-multiboot2 -+Check if FILE can be used as x86 multiboot2 kernel -+ -+.TP -+--is-arm-linux -+Check if FILE is ARM Linux -+ -+.TP -+--is-arm64-linux -+Check if FILE is ARM64 Linux -+ -+.TP -+--is-ia64-linux -+Check if FILE is IA64 Linux -+ -+.TP -+--is-mips-linux -+Check if FILE is MIPS Linux -+ -+.TP -+--is-mipsel-linux -+Check if FILE is MIPSEL Linux -+ -+.TP -+--is-sparc64-linux -+Check if FILE is SPARC64 Linux -+ -+.TP -+--is-powerpc-linux -+Check if FILE is POWERPC Linux -+ -+.TP -+--is-x86-linux -+Check if FILE is x86 Linux -+ -+.TP -+--is-x86-linux32 -+Check if FILE is x86 Linux supporting 32-bit protocol -+ -+.TP -+--is-x86-kfreebsd -+Check if FILE is x86 kFreeBSD -+ -+.TP -+--is-i386-kfreebsd -+Check if FILE is i386 kFreeBSD -+ -+.TP -+--is-x86_64-kfreebsd -+Check if FILE is x86_64 kFreeBSD -+ -+.TP -+--is-x86-knetbsd -+Check if FILE is x86 kNetBSD -+ -+.TP -+--is-i386-knetbsd -+Check if FILE is i386 kNetBSD -+ -+.TP -+--is-x86_64-knetbsd -+Check if FILE is x86_64 kNetBSD -+ -+.TP -+--is-i386-efi -+Check if FILE is i386 EFI file -+ -+.TP -+--is-x86_64-efi -+Check if FILE is x86_64 EFI file -+ -+.TP -+--is-ia64-efi -+Check if FILE is IA64 EFI file -+ -+.TP -+--is-arm64-efi -+Check if FILE is ARM64 EFI file -+ -+.TP -+--is-arm-efi -+Check if FILE is ARM EFI file -+ -+.TP -+--is-hibernated-hiberfil -+Check if FILE is hiberfil.sys in hibernated state -+ -+.TP -+--is-x86_64-xnu -+Check if FILE is x86_64 XNU (Mac OS X kernel) -+ -+.TP -+--is-i386-xnu -+Check if FILE is i386 XNU (Mac OS X kernel) -+ -+.TP -+--is-xnu-hibr -+Check if FILE is XNU (Mac OS X kernel) hibernated image -+ -+.TP -+--is-x86-bios-bootsector -+Check if FILE is BIOS bootsector -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-fstest.1 b/util/grub-fstest.1 -new file mode 100644 -index 00000000000..792fa78634c ---- /dev/null -+++ b/util/grub-fstest.1 -@@ -0,0 +1,99 @@ -+.TH GRUB-FSTEST 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-fstest\fR — Debug tool for GRUB's filesystem driver. -+ -+.SH SYNOPSIS -+\fBgrub-fstest\fR [-c | --diskcount=\fINUM\fR] [-C | --crypto] -+.RS 13 -+[-d | --debug=\fISTRING\fR] [-K | --zfs-key=\fIFILE\fR|\fIprompt\fR] -+.RE -+.RS 13 -+[-n | --length=\fINUM\fR] [-r | --root=\fIDEVICE_NAME\fR] -+.RE -+.RS 13 -+[-s | --skip=\fINUM\fR] [-u | --uncompress] [-v | --verbose] -+.RE -+.RS 13 -+\fIIMAGE_PATH\fR -+ -+.SH DESCRIPTION -+\fBgrub-fstest\fR is a tool for testing GRUB's filesystem drivers. You should not normally need to run this program. -+ -+.SH OPTIONS -+.TP -+\fB--diskcount\fR=\fINUM\fR -+Specify the number of input files. -+ -+.TP -+\fB--crypto\fR -+Mount cryptographic devices. -+ -+.TP -+\fB--debug\fR=\fISTRING\fR -+Set debug environment variable. -+ -+.TP -+\fB--zfs-key\fR=\fIFILE\fR|\fIprompt\fR -+Load ZFS cryptographic key. -+ -+.TP -+\fB--length\fR=\fINUM\fR -+Handle NUM bytes in output file. -+ -+.TP -+\fB--root\fR=\fIDEVICE_NAME\fR -+Set root device. -+ -+.TP -+\fB--skip\fR=\fINUM\fR -+Skip NUM bytes from output file. -+ -+.TP -+\fB--uncompress\fR -+Uncompress data. -+ -+.TP -+\fB--verbose\fR -+Print verbose messages. -+ -+.SH COMMANDS -+.TP -+\fBblocklist\fR \fIFILE\fR -+Display block list of \fIFILE\fR. -+ -+.TP -+\fBcat\fR \fIFILE\fR -+Display \fIFILE\fR on standard output. -+ -+.TP -+\fBcmp\fR \fIFILE\fR \fILOCAL\fR -+Compare \fIFILE\fR with local file \fILOCAL\fR. -+ -+.TP -+\fBcp\fR \fIFILE\fR \fILOCAL\fR -+Copy \fIFILE\fR to local file \fILOCAL\fR. -+ -+.TP -+\fBcrc\fR \fIFILE\fR -+Display the CRC-32 checksum of \fIFILE\fR. -+ -+.TP -+\fBhex\fR \fIFILE\fR -+Display contents of \fIFILE\fR in hexidecimal. -+ -+.TP -+\fBls\fR \fIPATH\fR -+List files at \fIPATH\fR. -+ -+.TP -+\fBxnu_uuid\fR \fIDEVICE\fR -+Display the XNU UUID of \fIDEVICE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-glue-efi.1 b/util/grub-glue-efi.1 -new file mode 100644 -index 00000000000..72bd555d577 ---- /dev/null -+++ b/util/grub-glue-efi.1 -@@ -0,0 +1,31 @@ -+.TH GRUB-GLUE-EFI 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-glue-efi\fR \(em Create an Apple fat EFI binary. -+ -+.SH SYNOPSIS -+\fBgrub-glue-efi\fR <-3 | --input32=\fIFILE\fR> <-6 | --input64=\fIFILE\fR> -+.RS 15 -+<-o | --output=\fIFILE\fR> [-v | --verbose] -+ -+.SH DESCRIPTION -+\fBgrub-glue-efi\fR creates an Apple fat EFI binary from two EFI binaries. -+ -+.SH OPTIONS -+.TP -+\fB--input32\fR=\fIFILE\fR -+Read 32-bit binary from \fIFILE\fR. -+ -+.TP -+\fB--input64\fR=\fIFILE\fR -+Read 64-bit binary from \fIFILE\fR. -+ -+.TP -+\fB--output\fR=\fIFILE\fR -+Write resulting fat binary to \fIFILE\fR. -+ -+.TP -+\fB--verbose\fR -+Print verbose messages. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-install.8 b/util/grub-install.8 -new file mode 100644 -index 00000000000..1db89e94b3b ---- /dev/null -+++ b/util/grub-install.8 -@@ -0,0 +1,128 @@ -+.TH GRUB-INSTALL 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-install\fR \(em Install GRUB on a device. -+ -+.SH SYNOPSIS -+\fBgrub-install\fR [--modules=\fIMODULES\fR] [--install-modules=\fIMODULES\fR] -+.RS 14 -+[--themes=\fITHEMES\fR] [--fonts=\fIFONTS\fR] [--locales=\fILOCALES\fR] -+.RE -+.RS 14 -+[--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] [-d | --directory=\fIDIR\fR] -+.RE -+.RS 14 -+[--grub-mkimage=\fIFILE\fR] [--boot-directory=\fIDIR\fR] -+.RE -+.RS 14 -+[--target=\fITARGET\fR] [--grub-setup=\fIFILE\fR] -+.RE -+.RS 14 -+[--grub-mkrelpath=\fIFILE\fR] [--grub-probe=\fIFILE\fR] -+.RE -+.RS 14 -+[--allow-floppy] [--recheck] [--force] [--force-file-id] -+.RE -+.RS 14 -+[--disk-module=\fIMODULE\fR] [--no-nvram] [--removable] -+.RE -+.RS 14 -+[--bootloader-id=\fIID\fR] [--efi-directory=\fIDIR\fR] \fIINSTALL_DEVICE\fR -+ -+.SH DESCRIPTION -+\fBgrub-install\fR installs GRUB onto a device. This includes copying GRUB images into the target directory (generally \fI/boot/grub\fR), and on some platforms may also include installing GRUB onto a boot sector. -+ -+.SH OPTIONS -+.TP -+\fB--modules\fR=\fIMODULES\fR\! -+Pre-load modules specified by \fIMODULES\fR. -+ -+.TP -+\fB--install-modules\fR=\fIMODULES\fR -+Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. -+ -+.TP -+\fB--themes\fR=\fITHEMES\fR -+Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. -+ -+.TP -+\fB--fonts\fR=\fIFONTS\fR -+Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. -+ -+.TP -+\fB--locales\fR=\fILOCALES\fR -+Install only locales listed in \fILOCALES\fR. The default is to install all available locales. -+ -+.TP -+\fB--compress\fR=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR -+Compress GRUB files using the specified compression algorithm. -+ -+.TP -+\fB--directory\fR=\fIDIR\fR -+Use images and modules in \fIDIR\fR. -+ -+.TP -+\fB--grub-mkimage\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-mkimage\fR. The default is \fI/usr/bin/grub-mkimage\fR. -+ -+.TP -+\fB--boot-directory\fR=\fIDIR\fR -+Use \fIDIR\fR as the boot directory. The default is \fI/boot\fR. GRUB will put its files in a subdirectory of this directory named \fIgrub\fR. -+ -+.TP -+\fB--target\fR=\fITARGET\fR -+Install GRUB for \fITARGET\fR platform. The default is the platform \fBgrub-install\fR is running on. -+ -+.TP -+\fB--grub-setup\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-setup\fR. The default is \fI/usr/bin/grub-setup\fR. -+ -+.TP -+\fB--grub-mkrelpath\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-mkrelpath\fR. The default is \fI/usr/bin/grub-mkrelpath\fR. -+ -+.TP -+\fB--grub-probe\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-probe\fR. The default is \fI/usr/bin/grub-mkrelpath\fR. -+ -+.TP -+\fB--allow-floppy -+Make the device also bootable as a floppy. This option is the default for /dev/fdX devices. Some BIOSes will not boot images created with this option. -+ -+.TP -+\fB--recheck -+Delete any existing device map and create a new one if necessary. -+ -+.TP -+\fB--force -+Install even if problems are detected. -+ -+.TP -+\fB--force-file-id -+Use identifier file even if UUID is available. -+ -+.TP -+\fB--disk-module\fR=\fIMODULE\fR -+Use \fIMODULE\fR for disk access. This allows you to manually specify either \fIbiosdisk\fR or \fInative\fR disk access. This option is only available on the BIOS target platform. -+ -+.TP -+\fB--no-nvram -+Do not update the \fIboot-device\fR NVRAM variable. This option is only available on IEEE1275 target platforms. -+ -+.TP -+\fB--removable -+Treat the target device as if it is removeable. This option is only available on the EFI target platform. -+ -+.TP -+\fB--bootloader-id\fR=\fIID\fR -+Use \fIID\fR as the bootloader ID. This option is only available on the EFI target platform. -+ -+.TP -+\fB--efi-directory\fR=\fIDIR\fR -+Use \fIDIR\fR as the EFI System Partition root. This option is only available on the EFI target platform. -+ -+.TP -+\fIINSTALL_DEVICE\fR -+Install GRUB to the block device \fIINSTALL_DEVICE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-kbdcomp.1 b/util/grub-kbdcomp.1 -new file mode 100644 -index 00000000000..0bb969a5b43 ---- /dev/null -+++ b/util/grub-kbdcomp.1 -@@ -0,0 +1,19 @@ -+.TH GRUB-KBDCOMP 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-kbdcomp\fR \(em Generate a GRUB keyboard layout file. -+ -+.SH SYNOPSIS -+\fBgrub-kbdcomp\fR <-o | --output=\fIFILE\fR> \fICKBMAP_ARGUMENTS\fR -+ -+.SH DESCRIPTION -+\fBgrub-kbdcomp\fR processes an X keyboard layout description in -+\fBkeymaps\fR(5) format into a format that can be used by GRUB's \fBkeymap\fR -+command. -+ -+.SH OPTIONS -+.TP -+\fB--output\fR=\fIFILE\fR -+Write output to \fIFILE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-macbless.1 b/util/grub-macbless.1 -new file mode 100644 -index 00000000000..41a96186f70 ---- /dev/null -+++ b/util/grub-macbless.1 -@@ -0,0 +1,22 @@ -+.TH GRUB-MACBLESS 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-macbless\fR \(em Mac-style bless on HFS or HFS+ -+ -+.SH SYNOPSIS -+\fBgrub-macbless\fR [-v | --verbose] [-p | --ppc] \fIFILE\fR | [-x | --x86] \fIFILE\fR -+ -+.SH OPTIONS -+.TP -+--x86 -+Bless for x86 based Macs. -+ -+.TP -+--ppc -+Bless for PPC based Macs. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-menulst2cfg.1 b/util/grub-menulst2cfg.1 -new file mode 100644 -index 00000000000..91e2ef87113 ---- /dev/null -+++ b/util/grub-menulst2cfg.1 -@@ -0,0 +1,12 @@ -+.TH GRUB-MENULST2CFG 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-menulst2cfg\fR \(em Convert a configuration file from GRUB 0.xx to GRUB 2.xx format. -+ -+.SH SYNOPSIS -+\fBgrub-menulst2cfg\fR [\fIINFILE\fR [\fIOUTFILE\fR]] -+ -+.SH DESCRIPTION -+\fBgrub-menulst2cfg\fR converts a configuration file from GRUB 0.xx to the current format. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkconfig.8 b/util/grub-mkconfig.8 -new file mode 100644 -index 00000000000..a2d1f577b9b ---- /dev/null -+++ b/util/grub-mkconfig.8 -@@ -0,0 +1,17 @@ -+.TH GRUB-MKCONFIG 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkconfig\fR \(em Generate a GRUB configuration file. -+ -+.SH SYNOPSIS -+\fBgrub-mkconfig\fR [-o | --output=\fIFILE\fR] -+ -+.SH DESCRIPTION -+\fBgrub-mkconfig\fR generates a configuration file for GRUB. -+ -+.SH OPTIONS -+.TP -+\fB--output\fR=\fIFILE\fR -+Write generated output to \fIFILE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkfont.1 b/util/grub-mkfont.1 -new file mode 100644 -index 00000000000..3494857987d ---- /dev/null -+++ b/util/grub-mkfont.1 -@@ -0,0 +1,87 @@ -+.TH GRUB-MKFONT 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkfont\fR \(em Convert common font file formats into the PF2 format. -+ -+.SH SYNOPSIS -+\fBgrub-mkfont\fR [--ascii-bitmaps] [-a | --force-autohint] -+.RS 13 -+[-b | --bold] [-c | --asce=\fINUM\fR] [-d | --desc=\fINUM\fR] -+.RE -+.RS 13 -+[-i | --index=\fINUM\fR] [-n | --name=\fINAME\fR] [--no-bitmap] -+.RE -+.RS 13 -+[--no-hinting] <-o | --output=\fIFILE\fR> -+.RE -+.RS 13 -+[-r | --range=\fIFROM-TO\fR[\fI,FROM-TO\fR]] [-s | --size=\fISIZE\fR] -+.RE -+.RS 13 -+[-v | --verbose] [--width-spec] \fIFONT_FILES\fR -+ -+.SH DESCRIPTION -+\fBgrub-mkfont\fR converts font files from common formats into the PF2 format used by GRUB. -+ -+.SH OPTIONS -+.TP -+--ascii-bitmaps -+Save only bitmaps for ASCII characters. -+ -+.TP -+--force-autohint -+Force generation of automatic hinting. -+ -+.TP -+--bold -+Convert font to bold. -+ -+.TP -+--asce=\fINUM\fR -+Set font ascent to \fINUM\fR. -+ -+.TP -+--desc=\fINUM\fR -+Set font descent to \fINUM\fR. -+ -+.TP -+--index=\fINUM\fR -+Select face index \fINUM\fR. -+ -+.TP -+--name=\fINAME\fR -+Set font family to \fINAME\fR. -+ -+.TP -+--no-bitmap -+Ignore bitmap strikes when loading. -+ -+.TP -+--no-hinting -+Disable hinting. -+ -+.TP -+--output=\fIFILE\fR -+Save ouptut to \fIFILE\fR. This argument is required. -+ -+.TP -+--range=\fIFROM-TO\fR\fI,FROM-TO\fR -+Set the font ranges to each pair of \fIFROM\fR,\fITO\fR. -+ -+.TP -+--size=\fISIZE\fR -+Set font size to \fISIZE\fR. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.TP -+--width-spec -+Create a width summary file. -+ -+.TP -+\fIFONT_FILES\fR -+The input files to be converted. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkimage.1 b/util/grub-mkimage.1 -new file mode 100644 -index 00000000000..4dea4f54597 ---- /dev/null -+++ b/util/grub-mkimage.1 -@@ -0,0 +1,95 @@ -+.TH GRUB-MKIMAGE 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkimage\fR \(em Make a bootable GRUB image. -+ -+.SH SYNOPSIS -+\fBgrub-mkimage\fR [-c | --config=\fRFILE\fI] [-C | --compression=(\fIxz\fR,\fInone\fR,\fIauto\fR)] -+.RS 14 -+[-d | --directory=\fRDIR\fR] [-k | --pubkey=\fIFILE\fR] -+.RE -+.RS 14 -+[-m | --memdisk=\fIFILE\fR] [-n | --note] [-o | --output=\fIFILE\fR] -+.RE -+.RS 14 -+[-O | --format=\fIFORMAT\fR] [-p | --prefix=\fIDIR\fR] -+.RE -+.RS 14 -+[-v | --verbose] \fIMODULES\fR -+ -+.SH DESCRIPTION -+\fBgrub-mkimage\fI builds a bootable image of GRUB. -+ -+.SH OPTIONS -+.TP -+--config=\fIFILE\fR -+Embed \fIFILE\fR as the image's initial configuration file. -+ -+.TP -+--compression=(\fIxz\fR,\fInone\fR,\fIauto\fR) -+Use one of \fIxz\fR, \fInone\fR, or \fIauto\fR as the compression method for the core image. -+ -+.TP -+--directory=\fIDIR\fR -+Use images and modules from \fIDIR\fR. The default value is \fB/usr/lib/grub/\fR. -+ -+.TP -+--pubkey=\fIFILE\fR -+Embed the public key \fIFILE\fR for signature checking. -+ -+.TP -+--memdisk=\fIFILE\fR -+Embed the memdisk image \fIFILE\fR. If no \fB-p\fR option is also specified, this implies \fI-p (memdisk)/boot/grub\fR. -+ -+.TP -+--note -+Add a CHRP \fINOTE\fR section. This option is only valid on IEEE1275 platforms. -+ -+.TP -+--output=\fIFILE\fR -+Write the generated file to \fIFILE\fR. The default is to write to standard output. -+ -+.TP -+--format=\fIFORMAT\fR -+Generate an image in the specified \fIFORMAT\fR. Valid values are: -+.RS -+.RS 4 -+.P -+i386-coreboot, -+i386-multiboot, -+i386-pc, -+i386-pc-pxe, -+i386-efi, -+i386-ieee1275, -+i386-qemu, -+x86_64-efi, -+mipsel-yeeloong-flash, -+mipsel-fuloong2f-flash, -+mipself-loongson-elf, -+powerpc-ieee1275, -+sparc64-ieee1275-raw, -+sparc64-ieee1275-cdcore, -+sparc64-ieee1275-aout, -+ia64-efi, -+mips-arc, -+mipsel-arc, -+mipsel-qemu_mips-elf, -+mips-qemu_mips-flash, -+mipsel-qemu_mips-flash, -+mips-qemu_mips-elf -+.RE -+.RE -+ -+.TP -+--prefix=\fIDIR\fR -+Set prefix directory. The default value is \fI/boot/grub\fR. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.TP -+\fIMODULES\fR -+Include \fIMODULES\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mklayout.1 b/util/grub-mklayout.1 -new file mode 100644 -index 00000000000..d1bbc2ec515 ---- /dev/null -+++ b/util/grub-mklayout.1 -@@ -0,0 +1,27 @@ -+.TH GRUB-MKLAYOUT 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mklayout\fR \(em Generate a GRUB keyboard layout file. -+ -+.SH SYNOPSIS -+\fBgrub-mklayout\fR [-i | --input=\fIFILE\fR] [-o | --output=\fIFILE\fR] -+.RS 15 -+[-v | --verbose] -+ -+.SH DESCRIPTION -+\fBgrub-mklayout\fR generates a GRUB keyboard layout description which corresponds with the Linux console layout description given as input. -+ -+.SH OPTIONS -+.TP -+--input=\fIFILE\fR -+Use \fIFILE\fR as the input. The default value is the standard input device. -+ -+.TP -+--output=\fIFILE\fR -+Use \fIFILE\fR as the output. The default value is the standard output device. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mknetdir.1 b/util/grub-mknetdir.1 -new file mode 100644 -index 00000000000..fa7e8d4ef0d ---- /dev/null -+++ b/util/grub-mknetdir.1 -@@ -0,0 +1,12 @@ -+.TH GRUB-MKNETDIR 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mknetdir\fR \(em Prepare a GRUB netboot directory. -+ -+.SH SYNOPSIS -+\fBgrub-mknetdir\fR -+ -+.SH DESCRIPTION -+\fBgrub-mknetdir\fR prepares a directory for GRUB to be netbooted from. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkpasswd-pbkdf2.1 b/util/grub-mkpasswd-pbkdf2.1 -new file mode 100644 -index 00000000000..73c437c15d8 ---- /dev/null -+++ b/util/grub-mkpasswd-pbkdf2.1 -@@ -0,0 +1,27 @@ -+.TH GRUB-MKPASSWD-PBKDF2 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkpasswd-pbkdf2\fR \(em Generate a PBKDF2 password hash. -+ -+.SH SYNOPSIS -+\fBgrub-mkpasswd-pbkdf2\fR [-c | --iteration-count=\fINUM\fR] [-l | --buflen=\fINUM\fR] -+.RS 22 -+[-s | --salt=\fINUM\fR] -+ -+.SH DESCRIPTION -+\fBgrub-mkpasswd-pbkdf2\fR generates a PBKDF2 password string suitable for use in a GRUB configuration file. -+ -+.SH OPTIONS -+.TP -+--iteration-count=\fINUM\fR -+Number of PBKDF2 iterations. -+ -+.TP -+--buflen=\fINUM\fR -+Length of generated hash. -+ -+.TP -+--salt=\fINUM\fR -+Length of salt to use. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkrelpath.1 b/util/grub-mkrelpath.1 -new file mode 100644 -index 00000000000..85f1113621d ---- /dev/null -+++ b/util/grub-mkrelpath.1 -@@ -0,0 +1,12 @@ -+.TH GRUB-MKRELPATH 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkrelpath\fR \(em Generate a relative GRUB path given an OS path. -+ -+.SH SYNOPSIS -+\fBgrub-mkrelpath\fR \fIFILE\fR -+ -+.SH DESCRIPTION -+\fBgrub-mkrelpath\fR takes an OS filesystem path for \fIFILE\fR and returns a relative path suitable for use in a GRUB configuration file. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkrescue.1 b/util/grub-mkrescue.1 -new file mode 100644 -index 00000000000..4ed9fc723fd ---- /dev/null -+++ b/util/grub-mkrescue.1 -@@ -0,0 +1,123 @@ -+.TH GRUB-MKRESCUE 3 "Wed Feb 26 2014" -+.SH NAME -+grub-mkrescue \(em Generate a GRUB rescue image using GNU Xorriso. -+ -+.SH SYNOPSIS -+\fBgrub-mkrescue\fR [-o | --output=\fIFILE\fR] [--modules=\fIMODULES\fR] -+.RS 15 -+[--install-modules=\fIMODULES\fR] [--themes=\fITHEMES\fR] -+.RE -+.RS 15 -+[--fonts=\fIFONTS\fR] [--locales=\fILOCALES\fR] -+.RE -+.RS 15 -+[--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] [-d | --directory=\fIDIR\fR] -+.RE -+.RS 15 -+[--grub-mkimage=\fIFILE\fR] [--rom-directory=\fIDIR\fR] -+.RE -+.RS 15 -+[--xorriso=\fIFILE\fR] [--grub-glue-efi=\fIFILE\fR] -+.RE -+.RS 15 -+[--grub-render-label=\fIFILE\fR] [--label-font=\fIFILE\fR] -+.RE -+.RS 15 -+[--label-color=\fICOLOR\fR] [--label-bgcolor=\fIFILE\fR] -+.RE -+.RS 15 -+[--product-name=\fISTRING\fR] [--product-version=\fISTRING\fR] -+.RE -+.RS 15 -+[--sparc-boot] [--arcs-boot] -+ -+.SH DESCRIPTION -+\fBgrub-mkrescue\fR can be used to generate a rescue image with the GRUB bootloader. -+ -+.SH OPTIONS -+.TP -+\fB--output\fR=\fIFILE\fR -+Write the generated file to \fIFILE\fR. The default is to write to standard output. -+ -+.TP -+\fB--modules\fR=\fIMODULES\fR -+Pre-load modules specified by \fIMODULES\fR. -+ -+.TP -+\fB--install-modules\fR=\fIMODULES\fR -+Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. -+ -+.TP -+\fB--themes\fR=\fITHEMES\fR -+Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. -+ -+.TP -+\fB--fonts\fR=\fIFONTS\fR -+Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. -+ -+.TP -+\fB--locales\fR=\fILOCALES\fR -+Install only locales listed in \fILOCALES\fR. The default is to install all available locales. -+ -+.TP -+\fB--compress\fR[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR] -+Compress GRUB files using the specified compression algorithm. -+ -+.TP -+\fB--directory\fR=\fIDIR\fR -+Use images and modules in \fIDIR\fR. -+ -+.TP -+\fB--grub-mkimage\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-mkimage\fR(1). The default is \fI/usr/bin/grub-mkimage\fR. -+ -+.TP -+\fB--rom-directory\fR=\fIDIR\fR -+Save ROM images in \fIDIR\fR. -+ -+.TP -+\fB--xorriso\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBxorriso\fI. -+ -+.TP -+\fB--grub-glue-efi\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-glue-efi\fR(3). -+ -+.TP -+\fB--grub-render-label\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-render-label\fR(3). -+ -+.TP -+\fB--label-font\fR=\fIFILE\fR -+Use \fIFILE\fR as the font file for generated labels. -+ -+.TP -+\fB--label-color\fR=\fICOLOR\fR -+Use \fICOLOR\fI as the color for generated labels. -+ -+.TP -+\fB--label-bgcolor\fR=\fICOLOR\fR -+Use \fICOLOR\fR as the background color for generated labels. -+ -+.TP -+\fB--product-name\fR=\fISTRING\fR -+Use \fISTRING\fR as the product name in generated labels. -+ -+.TP -+\fB--product-version\fR=\fISTRING\fR -+Use \fISTRING\fR as the product version in generated labels. -+ -+.TP -+\fB--sparc-boot\fR -+Enable booting the SPARC platform. This disables HFS+, APM, ARCS, and "boot as disk image" on the \fIi386-pc\fR target platform. -+ -+.TP -+\fB--arcs-boot\fR -+Enable ARCS booting. This is typically for big-endian MIPS machines, and disables HFS+, APM, sparc64, and "boot as disk image" on the \fIi386-pc\fR target platform. -+ -+.TP -+\fB--\fR -+All options after a \fB--\fR will be passed directly to xorriso's command line when generating the image. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkstandalone.1 b/util/grub-mkstandalone.1 -new file mode 100644 -index 00000000000..ba2d2bdf279 ---- /dev/null -+++ b/util/grub-mkstandalone.1 -@@ -0,0 +1,100 @@ -+.TH GRUB-MKSTANDALONE 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkstandalone\fR \(em Generate a standalone image in the selected format. -+ -+.SH SYNOPSIS -+\fBgrub-mkstandalone\fR [-o | --output=\fIFILE\fR] [-O | --format=\fIFORMAT\fR] -+.RS 19 -+[-C | --compression=(\fIxz\fR|\fInone\fR|\fIauto\fR)] -+.RE -+.RS 19 -+[--modules=\fIMODULES\fR] [--install-modules=\fIMODULES\fR] -+.RE -+.RS 19 -+[--themes=\fITHEMES\fR] [--fonts=\fIFONTS\fR] -+.RE -+.RS 19 -+[--locales=\fILOCALES\fR] [--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] -+.RE -+.RS 19 -+[-d | --directory=\fIDIR\fR] [--grub-mkimage=\fIFILE\fR] -+.RE -+.RS 19 -+\fISOURCE...\fR -+ -+.SH DESCRIPTION -+ -+.SH OPTIONS -+.TP -+--output=\fIFILE\fR -+Write the generated file to \fIFILE\fR. The default is to write to standard output. -+ -+.TP -+--format=\fIFORMAT\fR -+Generate an image in the specified \fIFORMAT\fR. Valid values are: -+.RS -+.RS 4 -+.P -+i386-coreboot, -+i386-multiboot, -+i386-pc, -+i386-pc-pxe, -+i386-efi, -+i386-ieee1275, -+i386-qemu, -+x86_64-efi, -+mipsel-yeeloong-flash, -+mipsel-fuloong2f-flash, -+mipself-loongson-elf, -+powerpc-ieee1275, -+sparc64-ieee1275-raw, -+sparc64-ieee1275-cdcore, -+sparc64-ieee1275-aout, -+ia64-efi, -+mips-arc, -+mipsel-arc, -+mipsel-qemu_mips-elf, -+mips-qemu_mips-flash, -+mipsel-qemu_mips-flash, -+mips-qemu_mips-elf -+.RE -+.RE -+ -+.TP -+--compression=(\fIxz\fR|\fInone\fR|\fIauto\fR) -+Use one of \fIxz\fR, \fInone\fR, or \fIauto\fR as the compression method for the core image. -+ -+.TP -+--modules=\fIMODULES\fR -+Pre-load modules specified by \fIMODULES\fR. -+ -+.TP -+--install-modules=\fIMODULES\fR -+Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. -+ -+.TP -+--themes=\fITHEMES\fR -+Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. -+ -+.TP -+--fonts=\fIFONTS\fR -+Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. -+ -+.TP -+--locales=\fILOCALES\fR -+Install only locales listed in \fILOCALES\fR. The default is to install all available locales. -+ -+.TP -+--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR] -+Compress GRUB files using the specified compression algorithm. -+ -+.TP -+--directory=\fIDIR\fR -+Use images and modules in \fIDIR\fR. -+ -+.TP -+--grub-mkimage=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-mkimage\fR. The default is \fI/usr/bin/grub-mkimage\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-ofpathname.8 b/util/grub-ofpathname.8 -new file mode 100644 -index 00000000000..bf3743aeba1 ---- /dev/null -+++ b/util/grub-ofpathname.8 -@@ -0,0 +1,12 @@ -+.TH GRUB-OFPATHNAME 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-ofpathname\fR \(em Generate an IEEE-1275 device path for a specified device. -+ -+.SH SYNOPSIS -+\fBgrub-ofpathname\fR \fIDEVICE\fR -+ -+.SH DESCRIPTION -+\fBgrub-ofpathname\fR generates an IEEE-1275 device path for the specified \fIDEVICE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-probe.8 b/util/grub-probe.8 -new file mode 100644 -index 00000000000..04e26c832bb ---- /dev/null -+++ b/util/grub-probe.8 -@@ -0,0 +1,80 @@ -+.TH GRUB-PROBE 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-probe\fR \(em Probe device information for a given path. -+ -+.SH SYNOPSIS -+\fBgrub-probe\fR \[-d | --device] [-m | --device-map=\fIFILE\fR] -+.RS 12 -+[-t | --target=(fs|fs_uuid|fs_label|drive|device|partmap| -+.RE -+.RS 28 -+abstraction|cryptodisk_uuid| -+.RE -+.RS 28 -+msdos_parttype)] -+.RE -+.RS 12 -+[-v | --verbose] (PATH|DEVICE) -+ -+.SH DESCRIPTION -+\fBgrub-probe\fR probes a path or device for filesystem and related information. -+ -+.SH OPTIONS -+.TP -+--device -+Final option represents a \fIDEVICE\fR, rather than a filesystem \fIPATH\fR. -+.TP -+--device-map=\fIFILE\fR -+Use \fIFILE\fR as the device map. The default value is \fI/boot/grub/device.map\fR. -+ -+.TP -+--target=(fs|fs_uuid|fs_label|drive|device|partmap|msdos_parttype) -+Select among various output definitions. The default is \fIfs\fR. -+.RS -+.TP -+\fIfs\fR -+filesystem module -+ -+.TP -+\fIfs_uuid\fR -+filesystem UUID -+ -+.TP -+\fIfs_label\fR -+filesystem label -+ -+.TP -+\fIdrive\fR -+GRUB drive name -+ -+.TP -+\fIdevice\fR -+System device -+ -+.TP -+\fIpartmap\fR -+partition map module -+ -+.TP -+\fIabstraction\fR -+abstraction module -+ -+.TP -+\fIcryptodisk_uuid\fR -+cryptographic container -+ -+.TP -+\fImsdos_partmap\fR -+MS-DOS partition map -+.RE -+ -+.TP -+--verbose -+Print verbose output. -+ -+.TP -+(\fIPATH\fR|\fIDEVICE\fR) -+If --device is passed, a block \fIDEVICE\fR. Otherwise, the \fIPATH\fR of a file on the filesystem. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-reboot.8 b/util/grub-reboot.8 -new file mode 100644 -index 00000000000..faa5e4eece2 ---- /dev/null -+++ b/util/grub-reboot.8 -@@ -0,0 +1,21 @@ -+.TH GRUB-REBOOT 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-reboot\fR \(em Set the default boot menu entry for the next boot only. -+ -+.SH SYNOPSIS -+\fBgrub-reboot\fR [--boot-directory=\fIDIR\fR] \fIMENU_ENTRY\fR -+ -+.SH DESCRIPTION -+\fBgrub-reboot\fR sets the default boot menu entry for the next boot, but not further boots after that. This command only works for GRUB configuration files created with \fIGRUB_DEFAULT=saved\fR in \fI/etc/default/grub\fR. -+ -+.SH OPTIONS -+.TP -+--boot-directory=\fIDIR\fR -+Find GRUB images under \fIDIR/grub\fR. The default value is \fI/boot\fR, resulting in grub images being search for at \fI/boot/grub\fR. -+ -+.TP -+\fIMENU_ENTRY\fR -+A number, a menu item title or a menu item identifier. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-render-label.1 b/util/grub-render-label.1 -new file mode 100644 -index 00000000000..4d51c8abf01 ---- /dev/null -+++ b/util/grub-render-label.1 -@@ -0,0 +1,51 @@ -+.TH GRUB-RENDER-LABEL 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-render-label\fR \(em Render an Apple disk label. -+ -+.SH SYNOPSIS -+\fBgrub-render-label\fR [-b | --bgcolor=\fICOLOR\fR] [-c | --color=\fICOLOR\fR] -+.RS 19 -+[-f | --font=\fIFILE\fR] [-i | --input=\fIFILE\fR] -+.RE -+.RS 19 -+[-o | --output=\fIFILE\fR] [-t | --text=\fISTRING\fR] -+.RE -+.RS 19 -+[-v | --verbose] -+ -+.SH DESCRIPTION -+\fBgrub-render-label\fR renders an Apple disk label (.disk_label) file. -+ -+ -+.SH OPTIONS -+.TP -+\fB--color\fR=\fICOLOR\fR -+Use \fICOLOR\fI as the color for generated labels. -+ -+.TP -+\fB--bgcolor\fR=\fICOLOR\fR -+Use \fICOLOR\fR as the background color for generated labels. -+ -+.TP -+\fB--font\fR=\fIFILE\fR -+Use \fIFILE\fR as the font file for generated labels. -+ -+.TP -+--input=\fIFILE\fR -+Read input text from \fIFILE\fR. -+ -+.TP -+--output=\fIFILE\fR -+Render output to \fIFILE\fR. -+ -+.TP -+--text=\fISTRING\fR -+Use \fISTRING\fR as input text. -+ -+.TP -+--verbose -+Print verbose output. -+ -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-script-check.1 b/util/grub-script-check.1 -new file mode 100644 -index 00000000000..0f1f625b05d ---- /dev/null -+++ b/util/grub-script-check.1 -@@ -0,0 +1,21 @@ -+.TH GRUB-SCRIPT-CHECK 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-script-check\fR \(em Check GRUB configuration file for syntax errors. -+ -+.SH SYNOPSIS -+\fBgrub-script-check\fR [-v | --verbose] \fIPATH\fR -+ -+.SH DESCRIPTION -+\fBgrub-script-check\fR verifies that a specified GRUB configuration file does not contain syntax errors. -+ -+.SH OPTIONS -+.TP -+--verbose -+Print verbose output. -+ -+.TP -+\fIPATH\fR -+Path of the file to use as input. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-set-default.8 b/util/grub-set-default.8 -new file mode 100644 -index 00000000000..a96265a1509 ---- /dev/null -+++ b/util/grub-set-default.8 -@@ -0,0 +1,21 @@ -+.TH GRUB-SET-DEFAULT 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-set-default\fR \(em Set the default boot menu entry for GRUB. -+ -+.SH SYNOPSIS -+\fBgrub-set-default\fR [--boot-directory=\fIDIR\fR] \fIMENU_ENTRY\fR -+ -+.SH DESCRIPTION -+\fBgrub-set-default\fR sets the default boot menu entry for all subsequent boots. This command only works for GRUB configuration files created with \fIGRUB_DEFAULT=saved\fR in \fI/etc/default/grub\fR. -+ -+.SH OPTIONS -+.TP -+--boot-directory=\fIDIR\fR -+Find GRUB images under \fIDIR/grub\fR. The default value is \fI/boot\fR, resulting in grub images being search for at \fI/boot/grub\fR. -+ -+.TP -+\fIMENU_ENTRY\fR -+A number, a menu item title or a menu item identifier. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-sparc64-setup.8 b/util/grub-sparc64-setup.8 -new file mode 100644 -index 00000000000..37ea2dd5eaa ---- /dev/null -+++ b/util/grub-sparc64-setup.8 -@@ -0,0 +1,12 @@ -+.TH GRUB-SPARC64-SETUP 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-sparc64-setup\fR \(em Set up a device to boot a sparc64 GRUB image. -+ -+.SH SYNOPSIS -+\fBgrub-sparc64-setup\fR [OPTIONS]. -+ -+.SH DESCRIPTION -+You should not normally run this program directly. Use grub-install instead. -+ -+.SH SEE ALSO -+.BR "info grub" diff --git a/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch b/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch deleted file mode 100644 index 6b1580b..0000000 --- a/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Wed, 19 Feb 2014 15:58:43 -0500 -Subject: [PATCH] use fw_path prefix when fallback searching for grub config - -When PXE booting via UEFI firmware, grub was searching for grub.cfg -in the fw_path directory where the grub application was found. If -that didn't exist, a fallback search would look for config file names -based on MAC and IP address. However, the search would look in the -prefix directory which may not be the same fw_path. This patch -changes that behavior to use the fw_path directory for the fallback -search. Only if fw_path is NULL will the prefix directory be searched. - -Signed-off-by: Mark Salter ---- - grub-core/normal/main.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 7ca2e5400b1..02577502116 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -347,7 +347,7 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - char *config; - const char *prefix, *fw_path; - -- fw_path = grub_env_get ("fw_path"); -+ prefix = fw_path = grub_env_get ("fw_path"); - if (fw_path) - { - config = grub_xasprintf ("%s/grub.cfg", fw_path); -@@ -370,7 +370,8 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - } - } - -- prefix = grub_env_get ("prefix"); -+ if (! prefix) -+ prefix = grub_env_get ("prefix"); - if (prefix) - { - grub_size_t config_len; diff --git a/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch b/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch deleted file mode 100644 index ab49bb1..0000000 --- a/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 8 Jul 2019 17:33:22 +0200 -Subject: [PATCH] Try mac/guid/etc before grub.cfg on tftp config files. - -Signed-off-by: Peter Jones ---- - grub-core/normal/main.c | 97 ++++++++++++++++++++++++++----------------------- - 1 file changed, 51 insertions(+), 46 deletions(-) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 02577502116..880d0ebd454 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -345,61 +345,66 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - /* Guess the config filename. It is necessary to make CONFIG static, - so that it won't get broken by longjmp. */ - char *config; -- const char *prefix, *fw_path; -- -- prefix = fw_path = grub_env_get ("fw_path"); -- if (fw_path) -- { -- config = grub_xasprintf ("%s/grub.cfg", fw_path); -- if (config) -- { -- grub_file_t file; -- -- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -- if (file) -- { -- grub_file_close (file); -- grub_enter_normal_mode (config); -- } -- else -- { -- /* Ignore all errors. */ -- grub_errno = 0; -- } -- grub_free (config); -- } -- } -+ const char *prefix; -+ const char *net_search_cfg; -+ int disable_net_search = 0; - -+ prefix = grub_env_get ("fw_path"); - if (! prefix) - prefix = grub_env_get ("prefix"); -+ -+ net_search_cfg = grub_env_get ("feature_net_search_cfg"); -+ if (net_search_cfg && net_search_cfg[0] == 'n') -+ disable_net_search = 1; -+ - if (prefix) - { -- grub_size_t config_len; -- int disable_net_search = 0; -- const char *net_search_cfg; -- -- config_len = grub_strlen (prefix) + -- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -- config = grub_malloc (config_len); -- -- if (!config) -- goto quit; -- -- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -- -- net_search_cfg = grub_env_get ("feature_net_search_cfg"); -- if (net_search_cfg && net_search_cfg[0] == 'n') -- disable_net_search = 1; -- - if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && - !disable_net_search) -- grub_net_search_config_file (config); -+ { -+ grub_size_t config_len; -+ config_len = grub_strlen (prefix) + -+ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -+ config = grub_malloc (config_len); - -- grub_enter_normal_mode (config); -- grub_free (config); -- } -+ if (! config) -+ goto quit; -+ -+ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -+ -+ grub_net_search_configfile (config); -+ -+ grub_enter_normal_mode (config); -+ grub_free (config); -+ config = NULL; -+ } -+ -+ if (!config) -+ { -+ config = grub_xasprintf ("%s/grub.cfg", prefix); -+ if (config) -+ { -+ grub_file_t file; -+ -+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -+ if (file) -+ { -+ grub_file_close (file); -+ grub_enter_normal_mode (config); -+ } -+ else -+ { -+ /* Ignore all errors. */ -+ grub_errno = 0; -+ } -+ grub_free (config); -+ } -+ } -+ } - else -- grub_enter_normal_mode (0); -+ { -+ grub_enter_normal_mode (0); -+ } - } - else - grub_enter_normal_mode (argv[0]); diff --git a/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch b/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch deleted file mode 100644 index 245faf7..0000000 --- a/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 4 Sep 2014 14:23:23 -0400 -Subject: [PATCH] Generate OS and CLASS in 10_linux from /etc/os-release - -This makes us use pretty names in the titles we generate in -grub2-mkconfig when GRUB_DISTRIBUTOR isn't set. - -Resolves: rhbz#996794 - -Signed-off-by: Peter Jones ---- - util/grub.d/10_linux.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index cf8d1186981..5f6d3c8d52d 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -29,7 +29,8 @@ export TEXTDOMAINDIR="@localedir@" - CLASS="--class gnu-linux --class gnu --class os --unrestricted" - - if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then -- OS="$(sed 's, release .*$,,g' /etc/system-release)" -+ OS="$(eval $(grep PRETTY_NAME /etc/os-release) ; echo ${PRETTY_NAME})" -+ CLASS="--class $(eval $(grep '^ID_LIKE=\|^ID=' /etc/os-release) ; [ -n "${ID_LIKE}" ] && echo ${ID_LIKE} || echo ${ID}) ${CLASS}" - else - OS="${GRUB_DISTRIBUTOR}" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" diff --git a/0031-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch b/0031-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch deleted file mode 100644 index 3e2d3ae..0000000 --- a/0031-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 4 Sep 2014 15:52:08 -0400 -Subject: [PATCH] Minimize the sort ordering for .debug and -rescue- kernels. - -Resolves: rhbz#1065360 -Signed-off-by: Peter Jones ---- - util/grub-mkconfig_lib.in | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index 301d1ac229a..0f6505bf3b6 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -253,6 +253,14 @@ version_test_gt () - *.old:*.old) ;; - *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;; - *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;; -+ *-rescue*:*-rescue*) ;; -+ *?debug:*?debug) ;; -+ *-rescue*:*?debug) return 1 ;; -+ *?debug:*-rescue*) return 0 ;; -+ *-rescue*:*) return 1 ;; -+ *:*-rescue*) return 0 ;; -+ *?debug:*) return 1 ;; -+ *:*?debug) return 0 ;; - esac - version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" - return "$?" diff --git a/0032-Try-prefix-if-fw_path-doesn-t-work.patch b/0032-Try-prefix-if-fw_path-doesn-t-work.patch deleted file mode 100644 index 54a876b..0000000 --- a/0032-Try-prefix-if-fw_path-doesn-t-work.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 10:35:16 +0200 -Subject: [PATCH] Try $prefix if $fw_path doesn't work. - -Related: rhbz#1148652 - -Signed-off-by: Peter Jones ---- - grub-core/kern/ieee1275/init.c | 28 +++++---- - grub-core/net/net.c | 2 +- - grub-core/normal/main.c | 134 ++++++++++++++++++++--------------------- - 3 files changed, 82 insertions(+), 82 deletions(-) - -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index e71d1584164..0cd2a627231 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -127,23 +127,25 @@ grub_machine_get_bootlocation (char **device, char **path) - grub_free (canon); - } - else -- *device = grub_ieee1275_encode_devname (bootpath); -- grub_free (type); -- -- filename = grub_ieee1275_get_filename (bootpath); -- if (filename) - { -- char *lastslash = grub_strrchr (filename, '\\'); -- -- /* Truncate at last directory. */ -- if (lastslash) -+ filename = grub_ieee1275_get_filename (bootpath); -+ if (filename) - { -- *lastslash = '\0'; -- grub_translate_ieee1275_path (filename); -+ char *lastslash = grub_strrchr (filename, '\\'); - -- *path = filename; -- } -+ /* Truncate at last directory. */ -+ if (lastslash) -+ { -+ *lastslash = '\0'; -+ grub_translate_ieee1275_path (filename); -+ -+ *path = filename; -+ } -+ } -+ *device = grub_ieee1275_encode_devname (bootpath); - } -+ -+ grub_free (type); - grub_free (bootpath); - } - -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 4d3eb5c1a52..0ef148f4adc 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -1869,7 +1869,7 @@ grub_net_search_config_file (char *config) - /* Remove the remaining minus sign at the end. */ - config[config_len] = '\0'; - -- return GRUB_ERR_NONE; -+ return GRUB_ERR_FILE_NOT_FOUND; - } - - static struct grub_preboot *fini_hnd; -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 880d0ebd454..d5df4f815b0 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -335,81 +335,79 @@ grub_enter_normal_mode (const char *config) - grub_boot_time ("Exiting normal mode"); - } - -+static grub_err_t -+grub_try_normal (const char *variable) -+{ -+ char *config; -+ const char *prefix; -+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; -+ const char *net_search_cfg; -+ int disable_net_search = 0; -+ -+ prefix = grub_env_get (variable); -+ if (!prefix) -+ return GRUB_ERR_FILE_NOT_FOUND; -+ -+ net_search_cfg = grub_env_get ("feature_net_search_cfg"); -+ if (net_search_cfg && net_search_cfg[0] == 'n') -+ disable_net_search = 1; -+ -+ if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && -+ !disable_net_search) -+ { -+ grub_size_t config_len; -+ config_len = grub_strlen (prefix) + -+ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -+ config = grub_malloc (config_len); -+ -+ if (! config) -+ return GRUB_ERR_FILE_NOT_FOUND; -+ -+ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -+ err = grub_net_search_config_file (config); -+ } -+ -+ if (err != GRUB_ERR_NONE) -+ { -+ config = grub_xasprintf ("%s/grub.cfg", prefix); -+ if (config) -+ { -+ grub_file_t file; -+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -+ if (file) -+ { -+ grub_file_close (file); -+ err = GRUB_ERR_NONE; -+ } -+ } -+ } -+ -+ if (err == GRUB_ERR_NONE) -+ grub_enter_normal_mode (config); -+ -+ grub_errno = 0; -+ grub_free (config); -+ return err; -+} -+ - /* Enter normal mode from rescue mode. */ - static grub_err_t - grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - int argc, char *argv[]) - { -- if (argc == 0) -- { -- /* Guess the config filename. It is necessary to make CONFIG static, -- so that it won't get broken by longjmp. */ -- char *config; -- const char *prefix; -- const char *net_search_cfg; -- int disable_net_search = 0; -- -- prefix = grub_env_get ("fw_path"); -- if (! prefix) -- prefix = grub_env_get ("prefix"); -- -- net_search_cfg = grub_env_get ("feature_net_search_cfg"); -- if (net_search_cfg && net_search_cfg[0] == 'n') -- disable_net_search = 1; -- -- if (prefix) -- { -- if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && -- !disable_net_search) -- { -- grub_size_t config_len; -- config_len = grub_strlen (prefix) + -- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -- config = grub_malloc (config_len); -- -- if (! config) -- goto quit; -- -- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -- -- grub_net_search_configfile (config); -- -- grub_enter_normal_mode (config); -- grub_free (config); -- config = NULL; -- } -- -- if (!config) -- { -- config = grub_xasprintf ("%s/grub.cfg", prefix); -- if (config) -- { -- grub_file_t file; -- -- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -- if (file) -- { -- grub_file_close (file); -- grub_enter_normal_mode (config); -- } -- else -- { -- /* Ignore all errors. */ -- grub_errno = 0; -- } -- grub_free (config); -- } -- } -- } -- else -- { -- grub_enter_normal_mode (0); -- } -- } -- else -+ if (argc) - grub_enter_normal_mode (argv[0]); -+ else -+ { -+ /* Guess the config filename. */ -+ grub_err_t err; -+ err = grub_try_normal ("fw_path"); -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ err = grub_try_normal ("prefix"); -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ grub_enter_normal_mode (0); -+ } - --quit: - return 0; - } - diff --git a/0033-Use-rpm-s-sort-for-grub2-mkconfig.patch b/0033-Use-rpm-s-sort-for-grub2-mkconfig.patch deleted file mode 100644 index ff1c13e..0000000 --- a/0033-Use-rpm-s-sort-for-grub2-mkconfig.patch +++ /dev/null @@ -1,475 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robert Marshall -Date: Mon, 16 Mar 2015 14:14:19 -0400 -Subject: [PATCH] Use rpm's sort for grub2-mkconfig - -Add an option for rpm-based systems to use the rpm-sort library to sort -kernels. This avoids problems due to discrepancies between `sort -V` -and rpm. - -Signed-off-by: Robert Marshall -[pjones: fix --enable-rpm-sort configure option] -Signed-off-by: Peter Jones -[thierry.vignaud: fix build with rpm-4.16] -Signed-off-by: Thierry Vignaud -[tim: fix disabling grub-rpm-sort by ./configure] -Signed-off-by: Tim Landscheidt -[javierm: don't check for rpmvercmp in librpm] -Signed-off-by: Javier Martinez Canillas -[rharwood: commit message] -Signed-off-by: Robbie Harwood ---- - configure.ac | 37 ++++++ - Makefile.util.def | 17 +++ - util/grub-rpm-sort.c | 281 ++++++++++++++++++++++++++++++++++++++++++++++ - util/grub-mkconfig_lib.in | 11 +- - util/grub-rpm-sort.8 | 12 ++ - 5 files changed, 357 insertions(+), 1 deletion(-) - create mode 100644 util/grub-rpm-sort.c - create mode 100644 util/grub-rpm-sort.8 - -diff --git a/configure.ac b/configure.ac -index bec8535af70..643a13f9147 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -72,6 +72,7 @@ grub_TRANSFORM([grub-mkrelpath]) - grub_TRANSFORM([grub-mkrescue]) - grub_TRANSFORM([grub-probe]) - grub_TRANSFORM([grub-reboot]) -+grub_TRANSFORM([grub-rpm-sort]) - grub_TRANSFORM([grub-script-check]) - grub_TRANSFORM([grub-set-default]) - grub_TRANSFORM([grub-sparc64-setup]) -@@ -95,6 +96,7 @@ grub_TRANSFORM([grub-mkrescue.1]) - grub_TRANSFORM([grub-mkstandalone.3]) - grub_TRANSFORM([grub-ofpathname.3]) - grub_TRANSFORM([grub-probe.3]) -+grub_TRANSFORM([grub-rpm-sort.8]) - grub_TRANSFORM([grub-reboot.3]) - grub_TRANSFORM([grub-render-label.3]) - grub_TRANSFORM([grub-script-check.3]) -@@ -1860,6 +1862,35 @@ fi - - AC_SUBST([LIBDEVMAPPER]) - -+AC_ARG_ENABLE([rpm-sort], -+ [AS_HELP_STRING([--enable-rpm-sort], -+ [enable native rpm sorting of kernels in grub (default=guessed)])]) -+if test x"$enable_rpm_sort" = xno ; then -+ rpm_sort_excuse="explicitly disabled" -+else -+ enable_rpm_sort=yes -+fi -+ -+if test x"$rpm_sort_excuse" = x ; then -+ # Check for rpmlib header. -+ AC_CHECK_HEADER([rpm/rpmlib.h], [], -+ [rpm_sort_excuse="need rpm/rpmlib header"]) -+fi -+ -+if test x"$rpm_sort_excuse" = x ; then -+ # Check for rpmio library. -+ AC_CHECK_LIB([rpmio], [rpmvercmp], [], -+ [rpm_sort_excuse="rpmio missing rpmvercmp"]) -+fi -+ -+if test x"$rpm_sort_excuse" = x ; then -+ LIBRPM="-lrpmio"; -+ AC_DEFINE([HAVE_RPMIO], [1], -+ [Define to 1 if you have the rpmio library.]) -+fi -+ -+AC_SUBST([LIBRPM]) -+ - LIBGEOM= - if test x$host_kernel = xkfreebsd; then - AC_CHECK_LIB([geom], [geom_gettree], [], -@@ -2047,6 +2078,7 @@ AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) - AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) - AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) - AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) -+AM_CONDITIONAL([COND_GRUB_RPM_SORT], [test x$enable_rpm_sort = xyes]) - AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) - if test x$FONT_SOURCE != x ; then - HAVE_FONT_SOURCE=1 -@@ -2168,6 +2200,11 @@ echo grub-mount: Yes - else - echo grub-mount: No "($grub_mount_excuse)" - fi -+if [ x"$rpm_sort_excuse" = x ]; then -+echo grub-rpm-sort: Yes -+else -+echo grub-rpm-sort: No "($rpm_sort_excuse)" -+fi - if [ x"$starfield_excuse" = x ]; then - echo starfield theme: Yes - echo With DejaVuSans font from $DJVU_FONT_SOURCE -diff --git a/Makefile.util.def b/Makefile.util.def -index 2c9b283a230..bc10cc79722 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -703,6 +703,23 @@ program = { - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - }; - -+program = { -+ name = grub-rpm-sort; -+ mansection = 8; -+ installdir = sbin; -+ -+ common = grub-core/kern/emu/misc.c; -+ common = grub-core/kern/emu/argp_common.c; -+ common = grub-core/osdep/init.c; -+ common = util/misc.c; -+ common = util/grub-rpm-sort.c; -+ -+ ldadd = libgrubkern.a; -+ ldadd = grub-core/lib/gnulib/libgnu.a; -+ ldadd = '$(LIBDEVMAPPER) $(LIBRPM)'; -+ condition = COND_GRUB_RPM_SORT; -+}; -+ - script = { - name = grub-mkconfig; - common = util/grub-mkconfig.in; -diff --git a/util/grub-rpm-sort.c b/util/grub-rpm-sort.c -new file mode 100644 -index 00000000000..f33bd1ed568 ---- /dev/null -+++ b/util/grub-rpm-sort.c -@@ -0,0 +1,281 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static size_t -+read_file (const char *input, char **ret) -+{ -+ FILE *in; -+ size_t s; -+ size_t sz = 2048; -+ size_t offset = 0; -+ char *text; -+ -+ if (!strcmp(input, "-")) -+ in = stdin; -+ else -+ in = grub_util_fopen(input, "r"); -+ -+ text = xmalloc (sz); -+ -+ if (!in) -+ grub_util_error (_("cannot open `%s': %s"), input, strerror (errno)); -+ -+ while ((s = fread (text + offset, 1, sz - offset, in)) != 0) -+ { -+ offset += s; -+ if (sz - offset == 0) -+ { -+ sz += 2048; -+ text = xrealloc (text, sz); -+ } -+ } -+ -+ text[offset] = '\0'; -+ *ret = text; -+ -+ if (in != stdin) -+ fclose(in); -+ -+ return offset + 1; -+} -+ -+/* returns name/version/release */ -+/* NULL string pointer returned if nothing found */ -+static void -+split_package_string (char *package_string, char **name, -+ char **version, char **release) -+{ -+ char *package_version, *package_release; -+ -+ /* Release */ -+ package_release = strrchr (package_string, '-'); -+ -+ if (package_release != NULL) -+ *package_release++ = '\0'; -+ -+ *release = package_release; -+ -+ /* Version */ -+ package_version = strrchr(package_string, '-'); -+ -+ if (package_version != NULL) -+ *package_version++ = '\0'; -+ -+ *version = package_version; -+ /* Name */ -+ *name = package_string; -+ -+ /* Bubble up non-null values from release to name */ -+ if (*name == NULL) -+ { -+ *name = (*version == NULL ? *release : *version); -+ *version = *release; -+ *release = NULL; -+ } -+ if (*version == NULL) -+ { -+ *version = *release; -+ *release = NULL; -+ } -+} -+ -+/* -+ * package name-version-release comparator for qsort -+ * expects p, q which are pointers to character strings (char *) -+ * which will not be altered in this function -+ */ -+static int -+package_version_compare (const void *p, const void *q) -+{ -+ char *local_p, *local_q; -+ char *lhs_name, *lhs_version, *lhs_release; -+ char *rhs_name, *rhs_version, *rhs_release; -+ int vercmpflag = 0; -+ -+ local_p = alloca (strlen (*(char * const *)p) + 1); -+ local_q = alloca (strlen (*(char * const *)q) + 1); -+ -+ /* make sure these allocated */ -+ assert (local_p); -+ assert (local_q); -+ -+ strcpy (local_p, *(char * const *)p); -+ strcpy (local_q, *(char * const *)q); -+ -+ split_package_string (local_p, &lhs_name, &lhs_version, &lhs_release); -+ split_package_string (local_q, &rhs_name, &rhs_version, &rhs_release); -+ -+ /* Check Name and return if unequal */ -+ vercmpflag = rpmvercmp ((lhs_name == NULL ? "" : lhs_name), -+ (rhs_name == NULL ? "" : rhs_name)); -+ if (vercmpflag != 0) -+ return vercmpflag; -+ -+ /* Check version and return if unequal */ -+ vercmpflag = rpmvercmp ((lhs_version == NULL ? "" : lhs_version), -+ (rhs_version == NULL ? "" : rhs_version)); -+ if (vercmpflag != 0) -+ return vercmpflag; -+ -+ /* Check release and return the version compare value */ -+ vercmpflag = rpmvercmp ((lhs_release == NULL ? "" : lhs_release), -+ (rhs_release == NULL ? "" : rhs_release)); -+ -+ return vercmpflag; -+} -+ -+static void -+add_input (const char *filename, char ***package_names, size_t *n_package_names) -+{ -+ char *orig_input_buffer = NULL; -+ char *input_buffer; -+ char *position_of_newline; -+ char **names = *package_names; -+ char **new_names = NULL; -+ size_t n_names = *n_package_names; -+ -+ if (!*package_names) -+ new_names = names = xmalloc (sizeof (char *) * 2); -+ -+ if (read_file (filename, &orig_input_buffer) < 2) -+ { -+ if (new_names) -+ free (new_names); -+ if (orig_input_buffer) -+ free (orig_input_buffer); -+ return; -+ } -+ -+ input_buffer = orig_input_buffer; -+ while (input_buffer && *input_buffer && -+ (position_of_newline = strchrnul (input_buffer, '\n'))) -+ { -+ size_t sz = position_of_newline - input_buffer; -+ char *new; -+ -+ if (sz == 0) -+ { -+ input_buffer = position_of_newline + 1; -+ continue; -+ } -+ -+ new = xmalloc (sz+1); -+ strncpy (new, input_buffer, sz); -+ new[sz] = '\0'; -+ -+ names = xrealloc (names, sizeof (char *) * (n_names + 1)); -+ names[n_names] = new; -+ n_names++; -+ -+ /* move buffer ahead to next line */ -+ input_buffer = position_of_newline + 1; -+ if (*position_of_newline == '\0') -+ input_buffer = NULL; -+ } -+ -+ free (orig_input_buffer); -+ -+ *package_names = names; -+ *n_package_names = n_names; -+} -+ -+static char * -+help_filter (int key, const char *text, void *input __attribute__ ((unused))) -+{ -+ return (char *)text; -+} -+ -+static struct argp_option options[] = { -+ { 0, } -+}; -+ -+struct arguments -+{ -+ size_t ninputs; -+ size_t input_max; -+ char **inputs; -+}; -+ -+static error_t -+argp_parser (int key, char *arg, struct argp_state *state) -+{ -+ struct arguments *arguments = state->input; -+ switch (key) -+ { -+ case ARGP_KEY_ARG: -+ assert (arguments->ninputs < arguments->input_max); -+ arguments->inputs[arguments->ninputs++] = xstrdup (arg); -+ break; -+ default: -+ return ARGP_ERR_UNKNOWN; -+ } -+ return 0; -+} -+ -+static struct argp argp = { -+ options, argp_parser, N_("[INPUT_FILES]"), -+ N_("Sort a list of strings in RPM version sort order."), -+ NULL, help_filter, NULL -+}; -+ -+int -+main (int argc, char *argv[]) -+{ -+ struct arguments arguments; -+ char **package_names = NULL; -+ size_t n_package_names = 0; -+ int i; -+ -+ grub_util_host_init (&argc, &argv); -+ -+ memset (&arguments, 0, sizeof (struct arguments)); -+ arguments.input_max = argc+1; -+ arguments.inputs = xmalloc ((arguments.input_max + 1) -+ * sizeof (arguments.inputs[0])); -+ memset (arguments.inputs, 0, (arguments.input_max + 1) -+ * sizeof (arguments.inputs[0])); -+ -+ /* Parse our arguments */ -+ if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) -+ grub_util_error ("%s", _("Error in parsing command line arguments\n")); -+ -+ /* If there's no inputs in argv, add one for stdin */ -+ if (!arguments.ninputs) -+ { -+ arguments.ninputs = 1; -+ arguments.inputs[0] = xmalloc (2); -+ strcpy(arguments.inputs[0], "-"); -+ } -+ -+ for (i = 0; i < arguments.ninputs; i++) -+ add_input(arguments.inputs[i], &package_names, &n_package_names); -+ -+ if (package_names == NULL || n_package_names < 1) -+ grub_util_error ("%s", _("Invalid input\n")); -+ -+ qsort (package_names, n_package_names, sizeof (char *), -+ package_version_compare); -+ -+ /* send sorted list to stdout */ -+ for (i = 0; i < n_package_names; i++) -+ { -+ fprintf (stdout, "%s\n", package_names[i]); -+ free (package_names[i]); -+ } -+ -+ free (package_names); -+ for (i = 0; i < arguments.ninputs; i++) -+ free (arguments.inputs[i]); -+ -+ free (arguments.inputs); -+ -+ return 0; -+} -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index 0f6505bf3b6..42c2ea9ba50 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -33,6 +33,9 @@ fi - if test "x$grub_mkrelpath" = x; then - grub_mkrelpath="${bindir}/@grub_mkrelpath@" - fi -+if test "x$grub_rpm_sort" = x; then -+ grub_rpm_sort="${sbindir}/@grub_rpm_sort@" -+fi - - if command -v gettext >/dev/null; then - : -@@ -218,6 +221,12 @@ version_sort () - esac - } - -+if [ "x$grub_rpm_sort" != x -a -x "$grub_rpm_sort" ]; then -+ kernel_sort="$grub_rpm_sort" -+else -+ kernel_sort=version_sort -+fi -+ - version_test_numeric () - { - version_test_numeric_a="$1" -@@ -234,7 +243,7 @@ version_test_numeric () - version_test_numeric_a="$version_test_numeric_b" - version_test_numeric_b="$version_test_numeric_c" - fi -- if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then -+ if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | "$kernel_sort" | head -n 1 | grep -qx "$version_test_numeric_b" ; then - return 0 - else - return 1 -diff --git a/util/grub-rpm-sort.8 b/util/grub-rpm-sort.8 -new file mode 100644 -index 00000000000..8ce21488448 ---- /dev/null -+++ b/util/grub-rpm-sort.8 -@@ -0,0 +1,12 @@ -+.TH GRUB-RPM-SORT 8 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-rpm-sort\fR \(em Sort input according to RPM version compare. -+ -+.SH SYNOPSIS -+\fBgrub-rpm-sort\fR [OPTIONS]. -+ -+.SH DESCRIPTION -+You should not normally run this program directly. Use grub-mkconfig instead. -+ -+.SH SEE ALSO -+.BR "info grub" diff --git a/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch b/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch deleted file mode 100644 index 4eb37e1..0000000 --- a/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 28 Apr 2015 11:15:03 -0400 -Subject: [PATCH] Make grub2-mkconfig construct titles that look like the ones - we want elsewhere. - -Resolves: rhbz#1215839 - -Signed-off-by: Peter Jones ---- - util/grub.d/10_linux.in | 34 +++++++++++++++++++++++++++------- - 1 file changed, 27 insertions(+), 7 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 5f6d3c8d52d..786dbabb4a8 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -78,6 +78,32 @@ case x"$GRUB_FS" in - ;; - esac - -+mktitle () -+{ -+ local title_type -+ local version -+ local OS_NAME -+ local OS_VERS -+ -+ title_type=$1 && shift -+ version=$1 && shift -+ -+ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})" -+ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})" -+ -+ case $title_type in -+ recovery) -+ title=$(printf '%s (%s) %s (recovery mode)' \ -+ "${OS_NAME}" "${version}" "${OS_VERS}") -+ ;; -+ *) -+ title=$(printf '%s (%s) %s' \ -+ "${OS_NAME}" "${version}" "${OS_VERS}") -+ ;; -+ esac -+ echo -n ${title} -+} -+ - title_correction_code= - - linux_entry () -@@ -91,17 +117,11 @@ linux_entry () - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" - fi - if [ x$type != xsimple ] ; then -- case $type in -- recovery) -- title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;; -- *) -- title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;; -- esac -+ title=$(mktitle "$type" "$version") - if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then - replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" - quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" - title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" -- grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" - fi - echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" - else diff --git a/0035-Add-friendly-grub2-password-config-tool-985962.patch b/0035-Add-friendly-grub2-password-config-tool-985962.patch deleted file mode 100644 index 2d6f18a..0000000 --- a/0035-Add-friendly-grub2-password-config-tool-985962.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robert Marshall -Date: Thu, 25 Jun 2015 11:13:11 -0400 -Subject: [PATCH] Add friendly grub2 password config tool (#985962) - -Provided a tool for users to reset the grub2 root user password -without having to alter the grub.cfg. The hashed password now -lives in a root-only-readable configuration file. - -Resolves: rhbz#985962 - -Signed-off-by: Robert Marshall -[pjones: fix the efidir in grub-setpassword and rename tool] -Signed-off-by: Peter Jones -[luto: fix grub-setpassword -o's output path] -Andy Lutomirski ---- - configure.ac | 1 + - Makefile.util.def | 13 +++++ - util/grub-mkconfig.in | 2 + - util/grub-set-password.8 | 28 ++++++++++ - util/grub-set-password.in | 128 ++++++++++++++++++++++++++++++++++++++++++++++ - util/grub.d/01_users.in | 11 ++++ - 6 files changed, 183 insertions(+) - create mode 100644 util/grub-set-password.8 - create mode 100644 util/grub-set-password.in - create mode 100644 util/grub.d/01_users.in - -diff --git a/configure.ac b/configure.ac -index 643a13f9147..25e1abb59b9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -72,6 +72,7 @@ grub_TRANSFORM([grub-mkrelpath]) - grub_TRANSFORM([grub-mkrescue]) - grub_TRANSFORM([grub-probe]) - grub_TRANSFORM([grub-reboot]) -+grub_TRANSFORM([grub-set-password]) - grub_TRANSFORM([grub-rpm-sort]) - grub_TRANSFORM([grub-script-check]) - grub_TRANSFORM([grub-set-default]) -diff --git a/Makefile.util.def b/Makefile.util.def -index bc10cc79722..8ca4c14f0b9 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -452,6 +452,12 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = '01_users'; -+ common = util/grub.d/01_users.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '10_windows'; - common = util/grub.d/10_windows.in; -@@ -741,6 +747,13 @@ script = { - installdir = sbin; - }; - -+script = { -+ name = grub-set-password; -+ common = util/grub-set-password.in; -+ mansection = 8; -+ installdir = sbin; -+}; -+ - script = { - name = grub-mkconfig_lib; - common = util/grub-mkconfig_lib.in; -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index 8ea2315ebc2..ba14cf6261c 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -276,6 +276,8 @@ for i in "${grub_mkconfig_dir}"/* ; do - *~) ;; - # emacsen autosave files. FIXME: support other editors - */\#*\#) ;; -+ # rpm config files of yore. -+ *.rpmsave|*.rpmnew|*.rpmorig) ;; - *) - if grub_file_is_not_garbage "$i" && test -x "$i" ; then - echo -diff --git a/util/grub-set-password.8 b/util/grub-set-password.8 -new file mode 100644 -index 00000000000..9646546e43d ---- /dev/null -+++ b/util/grub-set-password.8 -@@ -0,0 +1,28 @@ -+.TH GRUB-SET-PASSWORD 3 "Thu Jun 25 2015" -+.SH NAME -+\fBgrub-set-password\fR \(em Generate the user.cfg file containing the hashed grub bootloader password. -+ -+.SH SYNOPSIS -+\fBgrub-set-password\fR [OPTION] -+ -+.SH DESCRIPTION -+\fBgrub-set-password\fR outputs the user.cfg file which contains the hashed GRUB bootloader password. This utility only supports configurations where there is a single root user. -+ -+The file has the format: -+GRUB2_PASSWORD=<\fIhashed password\fR>. -+ -+.SH OPTIONS -+.TP -+-h, --help -+Display program usage and exit. -+.TP -+-v, --version -+Display the current version. -+.TP -+-o, --output=<\fIDIRECTORY\fR> -+Choose the file path to which user.cfg will be written. -+ -+.SH SEE ALSO -+.BR "info grub" -+ -+.BR "info grub2-mkpasswd-pbkdf2" -diff --git a/util/grub-set-password.in b/util/grub-set-password.in -new file mode 100644 -index 00000000000..5ebf50576d6 ---- /dev/null -+++ b/util/grub-set-password.in -@@ -0,0 +1,128 @@ -+#!/bin/sh -e -+ -+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/') -+if [ -d /sys/firmware/efi/efivars/ ]; then -+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` -+else -+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` -+fi -+ -+PACKAGE_VERSION="@PACKAGE_VERSION@" -+PACKAGE_NAME="@PACKAGE_NAME@" -+self=`basename $0` -+bindir="@bindir@" -+grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@" -+ -+# Usage: usage -+# Print the usage. -+usage () { -+ cat < put user.cfg in a user-selected directory -+ -+Report bugs at https://bugzilla.redhat.com. -+EOF -+} -+ -+argument () { -+ opt=$1 -+ shift -+ -+ if test $# -eq 0; then -+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 -+ exit 1 -+ fi -+ echo $1 -+} -+ -+# Ensure that it's the root user running this script -+if [ "${EUID}" -ne 0 ]; then -+ echo "The grub bootloader password may only be set by root." -+ usage -+ exit 2 -+fi -+ -+# Check the arguments. -+while test $# -gt 0 -+do -+ option=$1 -+ shift -+ -+ case "$option" in -+ -h | --help) -+ usage -+ exit 0 ;; -+ -v | --version) -+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" -+ exit 0 ;; -+ -o | --output) -+ OUTPUT_PATH=`argument $option "$@"`; shift ;; -+ --output=*) -+ OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;; -+ -o=*) -+ OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;; -+ esac -+done -+ -+# set user input or default path for user.cfg file -+if [ -z "${OUTPUT_PATH}" ]; then -+ OUTPUT_PATH="${grubdir}" -+fi -+ -+if [ ! -d "${OUTPUT_PATH}" ]; then -+ echo "${OUTPUT_PATH} does not exist." -+ usage -+ exit 2; -+fi -+ -+ttyopt=$(stty -g) -+fixtty() { -+ stty ${ttyopt} -+} -+ -+trap fixtty EXIT -+stty -echo -+ -+# prompt & confirm new grub2 root user password -+echo -n "Enter password: " -+read PASSWORD -+echo -+echo -n "Confirm password: " -+read PASSWORD_CONFIRM -+echo -+stty ${ttyopt} -+ -+getpass() { -+ local P0 -+ local P1 -+ P0="$1" && shift -+ P1="$1" && shift -+ -+ ( echo ${P0} ; echo ${P1} ) | \ -+ LC_ALL=C ${grub_mkpasswd} | \ -+ grep -v '[eE]nter password:' | \ -+ sed -e "s/PBKDF2 hash of your password is //" -+} -+ -+MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")" -+if [ -z "${MYPASS}" ]; then -+ echo "${self}: error: empty password" 1>&2 -+ exit 1 -+fi -+ -+# on the ESP, these will fail to set the permissions, but it's okay because -+# the directory is protected. -+install -m 0600 /dev/null "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : -+chmod 0600 "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : -+echo "GRUB2_PASSWORD=${MYPASS}" > "${OUTPUT_PATH}/user.cfg" -+ -+if ! grep -q "^### BEGIN /etc/grub.d/01_users ###$" "${OUTPUT_PATH}/grub.cfg"; then -+ echo "WARNING: The current configuration lacks password support!" -+ echo "Update your configuration with @grub_mkconfig@ to support this feature." -+fi -diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in -new file mode 100644 -index 00000000000..db2f44bfb78 ---- /dev/null -+++ b/util/grub.d/01_users.in -@@ -0,0 +1,11 @@ -+#!/bin/sh -e -+cat << EOF -+if [ -f \${prefix}/user.cfg ]; then -+ source \${prefix}/user.cfg -+ if [ -n "\${GRUB2_PASSWORD}" ]; then -+ set superusers="root" -+ export superusers -+ password_pbkdf2 root \${GRUB2_PASSWORD} -+ fi -+fi -+EOF diff --git a/0036-tcp-add-window-scaling-support.patch b/0036-tcp-add-window-scaling-support.patch deleted file mode 100644 index 7d1996c..0000000 --- a/0036-tcp-add-window-scaling-support.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josef Bacik -Date: Wed, 12 Aug 2015 08:57:55 -0700 -Subject: [PATCH] tcp: add window scaling support - -Sometimes we have to provision boxes across regions, such as California to -Sweden. The http server has a 10 minute timeout, so if we can't get our 250mb -image transferred fast enough our provisioning fails, which is not ideal. So -add tcp window scaling on open connections and set the window size to 1mb. With -this change we're able to get higher sustained transfers between regions and can -transfer our image in well below 10 minutes. Without this patch we'd time out -every time halfway through the transfer. Thanks, - -Signed-off-by: Josef Bacik ---- - grub-core/net/tcp.c | 42 +++++++++++++++++++++++++++++------------- - 1 file changed, 29 insertions(+), 13 deletions(-) - -diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c -index e8ad34b84d4..7d4b822626d 100644 ---- a/grub-core/net/tcp.c -+++ b/grub-core/net/tcp.c -@@ -106,6 +106,18 @@ struct tcphdr - grub_uint16_t urgent; - } GRUB_PACKED; - -+struct tcp_scale_opt { -+ grub_uint8_t kind; -+ grub_uint8_t length; -+ grub_uint8_t scale; -+} GRUB_PACKED; -+ -+struct tcp_synhdr { -+ struct tcphdr tcphdr; -+ struct tcp_scale_opt scale_opt; -+ grub_uint8_t padding; -+}; -+ - struct tcp_pseudohdr - { - grub_uint32_t src; -@@ -566,7 +578,7 @@ grub_net_tcp_open (char *server, - grub_net_tcp_socket_t socket; - static grub_uint16_t in_port = 21550; - struct grub_net_buff *nb; -- struct tcphdr *tcph; -+ struct tcp_synhdr *tcph; - int i; - grub_uint8_t *nbd; - grub_net_link_level_address_t ll_target_addr; -@@ -635,20 +647,24 @@ grub_net_tcp_open (char *server, - } - - tcph = (void *) nb->data; -+ grub_memset(tcph, 0, sizeof (*tcph)); - socket->my_start_seq = grub_get_time_ms (); - socket->my_cur_seq = socket->my_start_seq + 1; -- socket->my_window = 8192; -- tcph->seqnr = grub_cpu_to_be32 (socket->my_start_seq); -- tcph->ack = grub_cpu_to_be32_compile_time (0); -- tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_SYN); -- tcph->window = grub_cpu_to_be16 (socket->my_window); -- tcph->urgent = 0; -- tcph->src = grub_cpu_to_be16 (socket->in_port); -- tcph->dst = grub_cpu_to_be16 (socket->out_port); -- tcph->checksum = 0; -- tcph->checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, -- &socket->inf->address, -- &socket->out_nla); -+ socket->my_window = 32768; -+ tcph->tcphdr.seqnr = grub_cpu_to_be32 (socket->my_start_seq); -+ tcph->tcphdr.ack = grub_cpu_to_be32_compile_time (0); -+ tcph->tcphdr.flags = grub_cpu_to_be16_compile_time ((6 << 12) | TCP_SYN); -+ tcph->tcphdr.window = grub_cpu_to_be16 (socket->my_window); -+ tcph->tcphdr.urgent = 0; -+ tcph->tcphdr.src = grub_cpu_to_be16 (socket->in_port); -+ tcph->tcphdr.dst = grub_cpu_to_be16 (socket->out_port); -+ tcph->tcphdr.checksum = 0; -+ tcph->scale_opt.kind = 3; -+ tcph->scale_opt.length = 3; -+ tcph->scale_opt.scale = 5; -+ tcph->tcphdr.checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, -+ &socket->inf->address, -+ &socket->out_nla); - - tcp_socket_register (socket); - diff --git a/0037-efinet-and-bootp-add-support-for-dhcpv6.patch b/0037-efinet-and-bootp-add-support-for-dhcpv6.patch deleted file mode 100644 index a9844b8..0000000 --- a/0037-efinet-and-bootp-add-support-for-dhcpv6.patch +++ /dev/null @@ -1,651 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 11:47:37 +0200 -Subject: [PATCH] efinet and bootp: add support for dhcpv6 - -Signed-off-by: Peter Jones ---- - grub-core/net/bootp.c | 173 +++++++++++++++++++++++++++++++++++++ - grub-core/net/drivers/efi/efinet.c | 53 ++++++++++-- - grub-core/net/net.c | 72 +++++++++++++++ - grub-core/net/tftp.c | 4 + - include/grub/efi/api.h | 129 +++++++++++++++++++++++++-- - include/grub/net.h | 60 +++++++++++++ - 6 files changed, 477 insertions(+), 14 deletions(-) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index 6fb5627025d..e28fb6a09f9 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -902,6 +902,179 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), - - static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp; - -+struct grub_net_network_level_interface * -+grub_net_configure_by_dhcpv6_ack (const char *name, -+ struct grub_net_card *card, -+ grub_net_interface_flags_t flags -+ __attribute__((__unused__)), -+ const grub_net_link_level_address_t *hwaddr, -+ const struct grub_net_dhcpv6_packet *packet, -+ int is_def, char **device, char **path) -+{ -+ struct grub_net_network_level_interface *inter = NULL; -+ struct grub_net_network_level_address addr; -+ int mask = -1; -+ -+ if (!device || !path) -+ return NULL; -+ -+ *device = 0; -+ *path = 0; -+ -+ grub_dprintf ("net", "mac address is %02x:%02x:%02x:%02x:%02x:%02x\n", -+ hwaddr->mac[0], hwaddr->mac[1], hwaddr->mac[2], -+ hwaddr->mac[3], hwaddr->mac[4], hwaddr->mac[5]); -+ -+ if (is_def) -+ grub_net_default_server = 0; -+ -+ if (is_def && !grub_net_default_server && packet) -+ { -+ const grub_uint8_t *options = packet->dhcp_options; -+ unsigned int option_max = 1024 - OFFSET_OF (dhcp_options, packet); -+ unsigned int i; -+ -+ for (i = 0; i < option_max - sizeof (grub_net_dhcpv6_option_t); ) -+ { -+ grub_uint16_t num, len; -+ grub_net_dhcpv6_option_t *opt = -+ (grub_net_dhcpv6_option_t *)(options + i); -+ -+ num = grub_be_to_cpu16(opt->option_num); -+ len = grub_be_to_cpu16(opt->option_len); -+ -+ grub_dprintf ("net", "got dhcpv6 option %d len %d\n", num, len); -+ -+ if (len == 0) -+ break; -+ -+ if (len + i > 1024) -+ break; -+ -+ if (num == GRUB_NET_DHCP6_BOOTFILE_URL) -+ { -+ char *scheme, *userinfo, *host, *file; -+ char *tmp; -+ int hostlen; -+ int port; -+ int rc = extract_url_info ((const char *)opt->option_data, -+ (grub_size_t)len, -+ &scheme, &userinfo, &host, &port, -+ &file); -+ if (rc < 0) -+ continue; -+ -+ /* right now this only handles tftp. */ -+ if (grub_strcmp("tftp", scheme)) -+ { -+ grub_free (scheme); -+ grub_free (userinfo); -+ grub_free (host); -+ grub_free (file); -+ continue; -+ } -+ grub_free (userinfo); -+ -+ hostlen = grub_strlen (host); -+ if (hostlen > 2 && host[0] == '[' && host[hostlen-1] == ']') -+ { -+ tmp = host+1; -+ host[hostlen-1] = '\0'; -+ } -+ else -+ tmp = host; -+ -+ *device = grub_xasprintf ("%s,%s", scheme, tmp); -+ grub_free (scheme); -+ grub_free (host); -+ -+ if (file && *file) -+ { -+ tmp = grub_strrchr (file, '/'); -+ if (tmp) -+ *(tmp+1) = '\0'; -+ else -+ file[0] = '\0'; -+ } -+ else if (!file) -+ file = grub_strdup (""); -+ -+ if (file[0] == '/') -+ { -+ *path = grub_strdup (file+1); -+ grub_free (file); -+ } -+ else -+ *path = file; -+ } -+ else if (num == GRUB_NET_DHCP6_IA_NA) -+ { -+ const grub_net_dhcpv6_option_t *ia_na_opt; -+ const grub_net_dhcpv6_opt_ia_na_t *ia_na = -+ (const grub_net_dhcpv6_opt_ia_na_t *)opt; -+ unsigned int left = len - OFFSET_OF (options, ia_na); -+ unsigned int j; -+ -+ if ((grub_uint8_t *)ia_na + left > -+ (grub_uint8_t *)options + option_max) -+ left -= ((grub_uint8_t *)ia_na + left) -+ - ((grub_uint8_t *)options + option_max); -+ -+ if (len < OFFSET_OF (option_data, opt) -+ + sizeof (grub_net_dhcpv6_option_t)) -+ { -+ grub_dprintf ("net", -+ "found dhcpv6 ia_na option with no address\n"); -+ continue; -+ } -+ -+ for (j = 0; left > sizeof (grub_net_dhcpv6_option_t); ) -+ { -+ ia_na_opt = (const grub_net_dhcpv6_option_t *) -+ (ia_na->options + j); -+ grub_uint16_t ia_na_opt_num, ia_na_opt_len; -+ -+ ia_na_opt_num = grub_be_to_cpu16 (ia_na_opt->option_num); -+ ia_na_opt_len = grub_be_to_cpu16 (ia_na_opt->option_len); -+ if (ia_na_opt_len == 0) -+ break; -+ if (j + ia_na_opt_len > left) -+ break; -+ if (ia_na_opt_num == GRUB_NET_DHCP6_IA_ADDRESS) -+ { -+ const grub_net_dhcpv6_opt_ia_address_t *ia_addr; -+ -+ ia_addr = (const grub_net_dhcpv6_opt_ia_address_t *) -+ ia_na_opt; -+ addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ grub_memcpy(addr.ipv6, ia_addr->ipv6_address, -+ sizeof (ia_addr->ipv6_address)); -+ inter = grub_net_add_addr (name, card, &addr, hwaddr, 0); -+ } -+ -+ j += ia_na_opt_len; -+ left -= ia_na_opt_len; -+ } -+ } -+ -+ i += len + 4; -+ } -+ -+ grub_print_error (); -+ } -+ -+ if (is_def) -+ { -+ grub_env_set ("net_default_interface", name); -+ grub_env_export ("net_default_interface"); -+ } -+ -+ if (inter) -+ grub_net_add_ipv6_local (inter, mask); -+ return inter; -+} -+ -+ - void - grub_bootp_init (void) - { -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 5388f952ba9..173fb63153c 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -18,11 +18,14 @@ - - #include - #include -+#include - #include - #include - #include - #include - #include -+#include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -329,7 +332,7 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - char **path) - { - struct grub_net_card *card; -- grub_efi_device_path_t *dp; -+ grub_efi_device_path_t *dp, *ldp = NULL; - - dp = grub_efi_get_device_path (hnd); - if (! dp) -@@ -340,14 +343,19 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - grub_efi_device_path_t *cdp; - struct grub_efi_pxe *pxe; - struct grub_efi_pxe_mode *pxe_mode; -+ - if (card->driver != &efidriver) - continue; -+ - cdp = grub_efi_get_device_path (card->efi_handle); - if (! cdp) - continue; -+ -+ ldp = grub_efi_find_last_device_path (dp); -+ - if (grub_efi_compare_device_paths (dp, cdp) != 0) - { -- grub_efi_device_path_t *ldp, *dup_dp, *dup_ldp; -+ grub_efi_device_path_t *dup_dp, *dup_ldp; - int match; - - /* EDK2 UEFI PXE driver creates pseudo devices with type IPv4/IPv6 -@@ -356,7 +364,6 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - devices. We skip them when enumerating cards, so here we need to - find matching MAC device. - */ -- ldp = grub_efi_find_last_device_path (dp); - if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE - || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) -@@ -373,16 +380,46 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - if (!match) - continue; - } -+ - pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (! pxe) - continue; -+ - pxe_mode = pxe->mode; -- grub_net_configure_by_dhcp_ack (card->name, card, 0, -- (struct grub_net_bootp_packet *) -- &pxe_mode->dhcp_ack, -- sizeof (pxe_mode->dhcp_ack), -- 1, device, path); -+ if (pxe_mode->using_ipv6) -+ { -+ grub_net_link_level_address_t hwaddr; -+ struct grub_net_network_level_interface *intf; -+ -+ grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); -+ grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", -+ pxe_mode->dhcp_ack_received ? "yes" : "no", -+ pxe_mode->dhcp_ack_received ? "" : " cannot continue"); -+ if (!pxe_mode->dhcp_ack_received) -+ continue; -+ -+ hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ grub_memcpy (hwaddr.mac, -+ card->efi_net->mode->current_address, -+ sizeof (hwaddr.mac)); -+ -+ intf = grub_net_configure_by_dhcpv6_ack (card->name, card, 0, &hwaddr, -+ (const struct grub_net_dhcpv6_packet *)&pxe_mode->dhcp_ack.dhcpv6, -+ 1, device, path); -+ if (intf && device && path) -+ grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); -+ } -+ else -+ { -+ grub_dprintf ("efinet", "using ipv4 and dhcp\n"); -+ grub_net_configure_by_dhcp_ack (card->name, card, 0, -+ (struct grub_net_bootp_packet *) -+ &pxe_mode->dhcp_ack, -+ sizeof (pxe_mode->dhcp_ack), -+ 1, device, path); -+ grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); -+ } - return; - } - } -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 0ef148f4adc..22f2689aaeb 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -960,6 +960,78 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa - grub_net_network_level_interfaces = inter; - } - -+int -+grub_ipv6_get_masksize (grub_uint16_t be_mask[8]) -+{ -+ grub_uint8_t *mask; -+ grub_uint16_t mask16[8]; -+ int x, y; -+ int ret = 128; -+ -+ grub_memcpy (mask16, be_mask, sizeof (mask16)); -+ for (x = 0; x < 8; x++) -+ mask16[x] = grub_be_to_cpu16 (mask16[x]); -+ -+ mask = (grub_uint8_t *)mask16; -+ -+ for (x = 15; x >= 0; x--) -+ { -+ grub_uint8_t octet = mask[x]; -+ if (!octet) -+ { -+ ret -= 8; -+ continue; -+ } -+ for (y = 0; y < 8; y++) -+ { -+ if (octet & (1 << y)) -+ break; -+ else -+ ret--; -+ } -+ break; -+ } -+ -+ return ret; -+} -+ -+grub_err_t -+grub_net_add_ipv6_local (struct grub_net_network_level_interface *inter, -+ int mask) -+{ -+ struct grub_net_route *route; -+ -+ if (inter->address.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6) -+ return 0; -+ -+ if (mask == -1) -+ mask = grub_ipv6_get_masksize ((grub_uint16_t *)inter->address.ipv6); -+ -+ if (mask == -1) -+ return 0; -+ -+ route = grub_zalloc (sizeof (*route)); -+ if (!route) -+ return grub_errno; -+ -+ route->name = grub_xasprintf ("%s:local", inter->name); -+ if (!route->name) -+ { -+ grub_free (route); -+ return grub_errno; -+ } -+ -+ route->target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ grub_memcpy (route->target.ipv6.base, inter->address.ipv6, -+ sizeof (inter->address.ipv6)); -+ route->target.ipv6.masksize = mask; -+ route->is_gateway = 0; -+ route->interface = inter; -+ -+ grub_net_route_register (route); -+ -+ return 0; -+} - - grub_err_t - grub_net_add_ipv4_local (struct grub_net_network_level_interface *inter, -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index 7f44b30f521..4ab2f5c7357 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -358,18 +358,22 @@ tftp_open (struct grub_file *file, const char *filename) - file->not_easily_seekable = 1; - file->data = data; - -+ grub_dprintf("tftp", "resolving address for %s\n", file->device->net->server); - err = grub_net_resolve_address (file->device->net->server, &addr); - if (err) - { -+ grub_dprintf("tftp", "Address resolution failed: %d\n", err); - grub_free (data); - return err; - } - -+ grub_dprintf("tftp", "opening connection\n"); - data->sock = grub_net_udp_open (addr, - TFTP_SERVER_PORT, tftp_receive, - file); - if (!data->sock) - { -+ grub_dprintf("tftp", "connection failed\n"); - grub_free (data); - return grub_errno; - } -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index f1a52210c0c..117469450d3 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -592,10 +592,16 @@ typedef void *grub_efi_handle_t; - typedef void *grub_efi_event_t; - typedef grub_efi_uint64_t grub_efi_lba_t; - typedef grub_efi_uintn_t grub_efi_tpl_t; --typedef grub_uint8_t grub_efi_mac_address_t[32]; --typedef grub_uint8_t grub_efi_ipv4_address_t[4]; --typedef grub_uint16_t grub_efi_ipv6_address_t[8]; --typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); -+typedef grub_efi_uint8_t grub_efi_mac_address_t[32]; -+typedef grub_efi_uint8_t grub_efi_ipv4_address_t[4]; -+typedef grub_efi_uint8_t grub_efi_ipv6_address_t[16]; -+typedef union -+{ -+ grub_efi_uint32_t addr[4]; -+ grub_efi_ipv4_address_t v4; -+ grub_efi_ipv6_address_t v6; -+} grub_efi_ip_address_t __attribute__ ((aligned(4))); -+ - typedef grub_efi_uint64_t grub_efi_physical_address_t; - typedef grub_efi_uint64_t grub_efi_virtual_address_t; - -@@ -1474,16 +1480,127 @@ struct grub_efi_simple_text_output_interface - }; - typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t; - --typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; -+typedef struct grub_efi_pxe_dhcpv4_packet -+{ -+ grub_efi_uint8_t bootp_opcode; -+ grub_efi_uint8_t bootp_hwtype; -+ grub_efi_uint8_t bootp_hwaddr_len; -+ grub_efi_uint8_t bootp_gate_hops; -+ grub_efi_uint32_t bootp_ident; -+ grub_efi_uint16_t bootp_seconds; -+ grub_efi_uint16_t bootp_flags; -+ grub_efi_uint8_t bootp_ci_addr[4]; -+ grub_efi_uint8_t bootp_yi_addr[4]; -+ grub_efi_uint8_t bootp_si_addr[4]; -+ grub_efi_uint8_t bootp_gi_addr[4]; -+ grub_efi_uint8_t bootp_hw_addr[16]; -+ grub_efi_uint8_t bootp_srv_name[64]; -+ grub_efi_uint8_t bootp_boot_file[128]; -+ grub_efi_uint32_t dhcp_magik; -+ grub_efi_uint8_t dhcp_options[56]; -+} grub_efi_pxe_dhcpv4_packet_t; -+ -+struct grub_efi_pxe_dhcpv6_packet -+{ -+ grub_efi_uint32_t message_type:8; -+ grub_efi_uint32_t transaction_id:24; -+ grub_efi_uint8_t dhcp_options[1024]; -+} GRUB_PACKED; -+typedef struct grub_efi_pxe_dhcpv6_packet grub_efi_pxe_dhcpv6_packet_t; -+ -+typedef union -+{ -+ grub_efi_uint8_t raw[1472]; -+ grub_efi_pxe_dhcpv4_packet_t dhcpv4; -+ grub_efi_pxe_dhcpv6_packet_t dhcpv6; -+} grub_efi_pxe_packet_t; -+ -+#define GRUB_EFI_PXE_MAX_IPCNT 8 -+#define GRUB_EFI_PXE_MAX_ARP_ENTRIES 8 -+#define GRUB_EFI_PXE_MAX_ROUTE_ENTRIES 8 -+ -+typedef struct grub_efi_pxe_ip_filter -+{ -+ grub_efi_uint8_t filters; -+ grub_efi_uint8_t ip_count; -+ grub_efi_uint8_t reserved; -+ grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; -+} grub_efi_pxe_ip_filter_t; -+ -+typedef struct grub_efi_pxe_arp_entry -+{ -+ grub_efi_ip_address_t ip_addr; -+ grub_efi_mac_address_t mac_addr; -+} grub_efi_pxe_arp_entry_t; -+ -+typedef struct grub_efi_pxe_route_entry -+{ -+ grub_efi_ip_address_t ip_addr; -+ grub_efi_ip_address_t subnet_mask; -+ grub_efi_ip_address_t gateway_addr; -+} grub_efi_pxe_route_entry_t; -+ -+typedef struct grub_efi_pxe_icmp_error -+{ -+ grub_efi_uint8_t type; -+ grub_efi_uint8_t code; -+ grub_efi_uint16_t checksum; -+ union -+ { -+ grub_efi_uint32_t reserved; -+ grub_efi_uint32_t mtu; -+ grub_efi_uint32_t pointer; -+ struct -+ { -+ grub_efi_uint16_t identifier; -+ grub_efi_uint16_t sequence; -+ } echo; -+ } u; -+ grub_efi_uint8_t data[494]; -+} grub_efi_pxe_icmp_error_t; -+ -+typedef struct grub_efi_pxe_tftp_error -+{ -+ grub_efi_uint8_t error_code; -+ grub_efi_char8_t error_string[127]; -+} grub_efi_pxe_tftp_error_t; - - typedef struct grub_efi_pxe_mode - { -- grub_uint8_t unused[52]; -+ grub_efi_boolean_t started; -+ grub_efi_boolean_t ipv6_available; -+ grub_efi_boolean_t ipv6_supported; -+ grub_efi_boolean_t using_ipv6; -+ grub_efi_boolean_t bis_supported; -+ grub_efi_boolean_t bis_detected; -+ grub_efi_boolean_t auto_arp; -+ grub_efi_boolean_t send_guid; -+ grub_efi_boolean_t dhcp_discover_valid; -+ grub_efi_boolean_t dhcp_ack_received; -+ grub_efi_boolean_t proxy_offer_received; -+ grub_efi_boolean_t pxe_discover_valid; -+ grub_efi_boolean_t pxe_reply_received; -+ grub_efi_boolean_t pxe_bis_reply_received; -+ grub_efi_boolean_t icmp_error_received; -+ grub_efi_boolean_t tftp_error_received; -+ grub_efi_boolean_t make_callbacks; -+ grub_efi_uint8_t ttl; -+ grub_efi_uint8_t tos; -+ grub_efi_ip_address_t station_ip; -+ grub_efi_ip_address_t subnet_mask; - grub_efi_pxe_packet_t dhcp_discover; - grub_efi_pxe_packet_t dhcp_ack; - grub_efi_pxe_packet_t proxy_offer; - grub_efi_pxe_packet_t pxe_discover; - grub_efi_pxe_packet_t pxe_reply; -+ grub_efi_pxe_packet_t pxe_bis_reply; -+ grub_efi_pxe_ip_filter_t ip_filter; -+ grub_efi_uint32_t arp_cache_entries; -+ grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_MAX_ARP_ENTRIES]; -+ grub_efi_uint32_t route_table_entries; -+ grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_MAX_ROUTE_ENTRIES]; -+ grub_efi_pxe_icmp_error_t icmp_error; -+ grub_efi_pxe_tftp_error_t tftp_error; - } grub_efi_pxe_mode_t; - - typedef struct grub_efi_pxe -diff --git a/include/grub/net.h b/include/grub/net.h -index 7ae4b6bd805..8a05ec4fe7a 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -447,6 +447,51 @@ struct grub_net_bootp_packet - grub_uint8_t vendor[0]; - } GRUB_PACKED; - -+enum -+ { -+ GRUB_NET_DHCP6_IA_NA = 3, -+ GRUB_NET_DHCP6_IA_ADDRESS = 5, -+ GRUB_NET_DHCP6_BOOTFILE_URL = 59, -+ }; -+ -+struct grub_net_dhcpv6_option -+{ -+ grub_uint16_t option_num; -+ grub_uint16_t option_len; -+ grub_uint8_t option_data[]; -+} GRUB_PACKED; -+typedef struct grub_net_dhcpv6_option grub_net_dhcpv6_option_t; -+ -+struct grub_net_dhcpv6_opt_ia_na -+{ -+ grub_uint16_t option_num; -+ grub_uint16_t option_len; -+ grub_uint32_t iaid; -+ grub_uint32_t t1; -+ grub_uint32_t t2; -+ grub_uint8_t options[]; -+} GRUB_PACKED; -+typedef struct grub_net_dhcpv6_opt_ia_na grub_net_dhcpv6_opt_ia_na_t; -+ -+struct grub_net_dhcpv6_opt_ia_address -+{ -+ grub_uint16_t option_num; -+ grub_uint16_t option_len; -+ grub_uint64_t ipv6_address[2]; -+ grub_uint32_t preferred_lifetime; -+ grub_uint32_t valid_lifetime; -+ grub_uint8_t options[]; -+} GRUB_PACKED; -+typedef struct grub_net_dhcpv6_opt_ia_address grub_net_dhcpv6_opt_ia_address_t; -+ -+struct grub_net_dhcpv6_packet -+{ -+ grub_uint32_t message_type:8; -+ grub_uint32_t transaction_id:24; -+ grub_uint8_t dhcp_options[1024]; -+} GRUB_PACKED; -+typedef struct grub_net_dhcpv6_packet grub_net_dhcpv6_packet_t; -+ - #define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 - #define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 - #define GRUB_NET_BOOTP_RFC1048_MAGIC_2 0x53 -@@ -482,6 +527,21 @@ grub_net_configure_by_dhcp_ack (const char *name, - grub_size_t size, - int is_def, char **device, char **path); - -+struct grub_net_network_level_interface * -+grub_net_configure_by_dhcpv6_ack (const char *name, -+ struct grub_net_card *card, -+ grub_net_interface_flags_t flags, -+ const grub_net_link_level_address_t *hwaddr, -+ const struct grub_net_dhcpv6_packet *packet, -+ int is_def, char **device, char **path); -+ -+int -+grub_ipv6_get_masksize(grub_uint16_t *mask); -+ -+grub_err_t -+grub_net_add_ipv6_local (struct grub_net_network_level_interface *inf, -+ int mask); -+ - grub_err_t - grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf, - int mask); diff --git a/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch b/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch deleted file mode 100644 index bf78c81..0000000 --- a/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch +++ /dev/null @@ -1,296 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 23 Jun 2016 11:01:39 -0400 -Subject: [PATCH] Add grub-get-kernel-settings and use it in 10_linux - -This patch adds grub-get-kernel-settings, which reads the system kernel -installation configuration from /etc/sysconfig/kernel, and outputs -${GRUB_...} variables suitable for evaluation by grub-mkconfig. Those -variables are then used by 10_linux to choose whether or not to create -debug stanzas. - -Resolves: rhbz#1226325 ---- - configure.ac | 2 + - Makefile.util.def | 7 ++ - util/bash-completion.d/grub-completion.bash.in | 22 +++++++ - util/grub-get-kernel-settings.3 | 20 ++++++ - util/grub-get-kernel-settings.in | 88 ++++++++++++++++++++++++++ - util/grub-mkconfig.in | 3 + - util/grub.d/10_linux.in | 23 +++++-- - 7 files changed, 160 insertions(+), 5 deletions(-) - create mode 100644 util/grub-get-kernel-settings.3 - create mode 100644 util/grub-get-kernel-settings.in - -diff --git a/configure.ac b/configure.ac -index 25e1abb59b9..58e57a745fa 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -65,6 +65,7 @@ grub_TRANSFORM([grub-install]) - grub_TRANSFORM([grub-mkconfig]) - grub_TRANSFORM([grub-mkfont]) - grub_TRANSFORM([grub-mkimage]) -+grub_TRANSFORM([grub-get-kernel-settings]) - grub_TRANSFORM([grub-glue-efi]) - grub_TRANSFORM([grub-mklayout]) - grub_TRANSFORM([grub-mkpasswd-pbkdf2]) -@@ -82,6 +83,7 @@ grub_TRANSFORM([grub-file]) - grub_TRANSFORM([grub-bios-setup.3]) - grub_TRANSFORM([grub-editenv.1]) - grub_TRANSFORM([grub-fstest.3]) -+grub_TRANSFORM([grub-get-kernel-settings.3]) - grub_TRANSFORM([grub-glue-efi.3]) - grub_TRANSFORM([grub-install.1]) - grub_TRANSFORM([grub-kbdcomp.3]) -diff --git a/Makefile.util.def b/Makefile.util.def -index 8ca4c14f0b9..43a1c7453b1 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -733,6 +733,13 @@ script = { - installdir = sbin; - }; - -+script = { -+ name = grub-get-kernel-settings; -+ common = util/grub-get-kernel-settings.in; -+ mansection = 3; -+ installdir = sbin; -+}; -+ - script = { - name = grub-set-default; - common = util/grub-set-default.in; -diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in -index 44bf135b9f8..5c4acd496d4 100644 ---- a/util/bash-completion.d/grub-completion.bash.in -+++ b/util/bash-completion.d/grub-completion.bash.in -@@ -264,6 +264,28 @@ have ${__grub_sparc64_setup_program} && \ - unset __grub_sparc64_setup_program - - -+# -+# grub-get-kernel-settings -+# -+_grub_get_kernel_settings () { -+ local cur -+ -+ COMPREPLY=() -+ cur=`_get_cword` -+ -+ if [[ "$cur" == -* ]]; then -+ __grubcomp "$(__grub_get_options_from_help)" -+ else -+ # Default complete with a filename -+ _filedir -+ fi -+} -+__grub_get_kernel_settings_program="@grub_get_kernel_settings@" -+have ${__grub_get_kernel_settings_program} && \ -+ complete -F _grub_get_kernel_settings -o filenames ${__grub_get_kernel_settings_program} -+unset __grub_get_kernel_settings_program -+ -+ - # - # grub-install - # -diff --git a/util/grub-get-kernel-settings.3 b/util/grub-get-kernel-settings.3 -new file mode 100644 -index 00000000000..ba33330e28d ---- /dev/null -+++ b/util/grub-get-kernel-settings.3 -@@ -0,0 +1,20 @@ -+.TH GRUB-GET-KERNEL-SETTINGS 3 "Thu Jun 25 2015" -+.SH NAME -+\fBgrub-get-kernel-settings\fR \(em Evaluate the system's kernel installation settings for use while making a grub configuration file. -+ -+.SH SYNOPSIS -+\fBgrub-get-kernel-settings\fR [OPTION] -+ -+.SH DESCRIPTION -+\fBgrub-get-kernel-settings\fR reads the kernel installation settings on the host system, and emits a set of grub settings suitable for use when creating a grub configuration file. -+ -+.SH OPTIONS -+.TP -+-h, --help -+Display program usage and exit. -+.TP -+-v, --version -+Display the current version. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-get-kernel-settings.in b/util/grub-get-kernel-settings.in -new file mode 100644 -index 00000000000..7e87dfccc0e ---- /dev/null -+++ b/util/grub-get-kernel-settings.in -@@ -0,0 +1,88 @@ -+#!/bin/sh -+set -e -+ -+# Evaluate new-kernel-pkg's configuration file. -+# Copyright (C) 2016 Free Software Foundation, Inc. -+# -+# GRUB is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+# -+# GRUB is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with GRUB. If not, see . -+ -+PACKAGE_NAME=@PACKAGE_NAME@ -+PACKAGE_VERSION=@PACKAGE_VERSION@ -+datadir="@datadir@" -+if [ "x$pkgdatadir" = x ]; then -+ pkgdatadir="${datadir}/@PACKAGE@" -+fi -+ -+self=`basename $0` -+ -+export TEXTDOMAIN=@PACKAGE@ -+export TEXTDOMAINDIR="@localedir@" -+ -+. "${pkgdatadir}/grub-mkconfig_lib" -+ -+# Usage: usage -+# Print the usage. -+usage () { -+ gettext_printf "Usage: %s [OPTION]\n" "$self" -+ gettext "Evaluate new-kernel-pkg configuration"; echo -+ echo -+ print_option_help "-h, --help" "$(gettext "print this message and exit")" -+ print_option_help "-v, --version" "$(gettext "print the version information and exit")" -+ echo -+} -+ -+# Check the arguments. -+while test $# -gt 0 -+do -+ option=$1 -+ shift -+ -+ case "$option" in -+ -h | --help) -+ usage -+ exit 0 ;; -+ -v | --version) -+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" -+ exit 0 ;; -+ -*) -+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 -+ usage -+ exit 1 -+ ;; -+ # Explicitly ignore non-option arguments, for compatibility. -+ esac -+done -+ -+if test -f /etc/sysconfig/kernel ; then -+ . /etc/sysconfig/kernel -+fi -+ -+if [ "$MAKEDEBUG" = "yes" ]; then -+ echo GRUB_LINUX_MAKE_DEBUG=true -+ echo export GRUB_LINUX_MAKE_DEBUG -+ echo GRUB_CMDLINE_LINUX_DEBUG=\"systemd.log_level=debug systemd.log_target=kmsg\" -+ echo export GRUB_CMDLINE_LINUX_DEBUG -+ echo GRUB_LINUX_DEBUG_TITLE_POSTFIX=\" with debugging\" -+ echo export GRUB_LINUX_DEBUG_TITLE_POSTFIX -+fi -+if [ "$DEFAULTDEBUG" = "yes" ]; then -+ echo GRUB_DEFAULT_TO_DEBUG=true -+else -+ echo GRUB_DEFAULT_TO_DEBUG=false -+fi -+echo export GRUB_DEFAULT_TO_DEBUG -+if [ "$UPDATEDEFAULT" = "yes" ]; then -+ echo GRUB_UPDATE_DEFAULT_KERNEL=true -+ echo export GRUB_UPDATE_DEFAULT_KERNEL -+fi -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index ba14cf6261c..005f093809b 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -45,6 +45,7 @@ grub_probe="${sbindir}/@grub_probe@" - grub_file="${bindir}/@grub_file@" - grub_editenv="${bindir}/@grub_editenv@" - grub_script_check="${bindir}/@grub_script_check@" -+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" - - export TEXTDOMAIN=@PACKAGE@ - export TEXTDOMAINDIR="@localedir@" -@@ -158,6 +159,8 @@ if test -f ${sysconfdir}/default/grub ; then - . ${sysconfdir}/default/grub - fi - -+eval "$("${grub_get_kernel_settings}")" || true -+ - if [ "x${GRUB_DISABLE_UUID}" = "xtrue" ]; then - if [ -z "${GRUB_DISABLE_LINUX_UUID}" ]; then - GRUB_DISABLE_LINUX_UUID="true" -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 786dbabb4a8..292e333324b 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -111,7 +111,8 @@ linux_entry () - os="$1" - version="$2" - type="$3" -- args="$4" -+ isdebug="$4" -+ args="$5" - - if [ -z "$boot_device_id" ]; then - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" -@@ -123,6 +124,9 @@ linux_entry () - quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" - title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" - fi -+ if [ x$isdebug = xdebug ]; then -+ title="$title${GRUB_LINUX_DEBUG_TITLE_POSTFIX}" -+ fi - echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" - else - echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" -@@ -306,11 +310,15 @@ while [ "x$list" != "x" ] ; do - fi - - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then -- linux_entry "${OS}" "${version}" simple \ -+ linux_entry "${OS}" "${version}" simple standard \ - "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then -+ linux_entry "${OS}" "${version}" simple debug \ -+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}" -+ fi - - submenu_indentation="$grub_tab" -- -+ - if [ -z "$boot_device_id" ]; then - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" - fi -@@ -319,10 +327,15 @@ while [ "x$list" != "x" ] ; do - is_top_level=false - fi - -- linux_entry "${OS}" "${version}" advanced \ -+ linux_entry "${OS}" "${version}" advanced standard \ - "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then -+ linux_entry "${OS}" "${version}" advanced debug \ -+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}" -+ fi -+ - if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then -- linux_entry "${OS}" "${version}" recovery \ -+ linux_entry "${OS}" "${version}" recovery standard \ - "single ${GRUB_CMDLINE_LINUX}" - fi - diff --git a/0039-bz1374141-fix-incorrect-mask-for-ppc64.patch b/0039-bz1374141-fix-incorrect-mask-for-ppc64.patch deleted file mode 100644 index ef992f5..0000000 --- a/0039-bz1374141-fix-incorrect-mask-for-ppc64.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Masahiro Matsuya -Date: Sat, 29 Oct 2016 08:35:26 +0900 -Subject: [PATCH] bz1374141 fix incorrect mask for ppc64 - -The netmask configured in firmware is not respected on ppc64 (big endian). -When 255.255.252.0 is set as netmask in firmware, the following is the value of bootpath string in grub_ieee1275_parse_bootpath(). - - /vdevice/l-lan@30000002:speed=auto,duplex=auto,192.168.88.10,,192.168.89.113,192.168.88.1,5,5,255.255.252.0,512 - -The netmask in this bootpath is no problem, since it's a value specified in firmware. But, -The value of 'subnet_mask.ipv4' was set with 0xfffffc00, and __builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4)) returned 16 (not 22). -As a result, 16 was used for netmask wrongly. - -1111 1111 1111 1111 1111 1100 0000 0000 # subnet_mask.ipv4 (=0xfffffc00) -0000 0000 1111 1100 1111 1111 1111 1111 # grub_le_to_cpu32 (subnet_mask.ipv4) -1111 1111 0000 0011 0000 0000 0000 0000 # ~grub_le_to_cpu32 (subnet_mask.ipv4) - -And, the count of zero with __builtin_ctz can be 16. -This patch changes it as below. - -1111 1111 1111 1111 1111 1100 0000 0000 # subnet_mask.ipv4 (=0xfffffc00) -0000 0000 1111 1100 1111 1111 1111 1111 # grub_le_to_cpu32 (subnet_mask.ipv4) -1111 1111 1111 1111 1111 1100 0000 0000 # grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)) -0000 0000 0000 0000 0000 0011 1111 1111 # ~grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)) - -The count of zero with __builtin_clz can be 22. (clz counts the number of one bits preceding the most significant zero bit) - -Signed-off-by: Masahiro Matsuya -Signed-off-by: Robbie Harwood ---- - grub-core/net/drivers/ieee1275/ofnet.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c -index ac4e62a95c9..3860b6f78d8 100644 ---- a/grub-core/net/drivers/ieee1275/ofnet.c -+++ b/grub-core/net/drivers/ieee1275/ofnet.c -@@ -220,8 +220,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, - flags); - inter->vlantag = vlantag; - grub_net_add_ipv4_local (inter, -- __builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4))); -- -+ __builtin_clz (~grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)))); - } - - if (gateway_addr.ipv4 != 0) diff --git a/0040-Make-grub_fatal-also-backtrace.patch b/0040-Make-grub_fatal-also-backtrace.patch deleted file mode 100644 index 3534b05..0000000 --- a/0040-Make-grub_fatal-also-backtrace.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 27 Jan 2016 09:22:42 -0500 -Subject: [PATCH] Make grub_fatal() also backtrace. - ---- - grub-core/Makefile.core.def | 3 ++ - grub-core/kern/misc.c | 8 +++++- - grub-core/lib/arm64/backtrace.c | 62 +++++++++++++++++++++++++++++++++++++++++ - grub-core/lib/backtrace.c | 2 ++ - grub-core/lib/i386/backtrace.c | 14 +++++++++- - 5 files changed, 87 insertions(+), 2 deletions(-) - create mode 100644 grub-core/lib/arm64/backtrace.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index c15e91943b9..058c88ac3af 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -188,6 +188,9 @@ kernel = { - - softdiv = lib/division.c; - -+ x86 = lib/i386/backtrace.c; -+ x86 = lib/backtrace.c; -+ - i386 = kern/i386/dl.c; - i386_xen = kern/i386/dl.c; - i386_xen_pvh = kern/i386/dl.c; -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 63b586d09cb..a3e215155bd 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - union printf_arg - { -@@ -1199,8 +1200,13 @@ grub_printf_fmt_check (const char *fmt, const char *fmt_expected) - static void __attribute__ ((noreturn)) - grub_abort (void) - { -+#ifndef GRUB_UTIL -+#if defined(__i386__) || defined(__x86_64__) -+ grub_backtrace(); -+#endif -+#endif - grub_printf ("\nAborted."); -- -+ - #ifndef GRUB_UTIL - if (grub_term_inputs) - #endif -diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c -new file mode 100644 -index 00000000000..1079b5380e1 ---- /dev/null -+++ b/grub-core/lib/arm64/backtrace.c -@@ -0,0 +1,62 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_STACK_FRAME 102400 -+ -+void -+grub_backtrace_pointer (int frame) -+{ -+ while (1) -+ { -+ void *lp = __builtin_return_address (frame); -+ if (!lp) -+ break; -+ -+ lp = __builtin_extract_return_addr (lp); -+ -+ grub_printf ("%p: ", lp); -+ grub_backtrace_print_address (lp); -+ grub_printf (" ("); -+ for (i = 0; i < 2; i++) -+ grub_printf ("%p,", ((void **)ptr) [i + 2]); -+ grub_printf ("%p)\n", ((void **)ptr) [i + 2]); -+ nptr = *(void **)ptr; -+ if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME -+ || nptr == ptr) -+ { -+ grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); -+ break; -+ } -+ ptr = nptr; -+ } -+} -+ -+void -+grub_backtrace (void) -+{ -+ grub_backtrace_pointer (1); -+} -+ -diff --git a/grub-core/lib/backtrace.c b/grub-core/lib/backtrace.c -index 825a8800e25..c0ad6ab8be1 100644 ---- a/grub-core/lib/backtrace.c -+++ b/grub-core/lib/backtrace.c -@@ -29,6 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - void - grub_backtrace_print_address (void *addr) - { -+#ifndef GRUB_UTIL - grub_dl_t mod; - - FOR_DL_MODULES (mod) -@@ -44,6 +45,7 @@ grub_backtrace_print_address (void *addr) - } - } - -+#endif - grub_printf ("%p", addr); - } - -diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c -index c3e03c7275c..c67273db3ae 100644 ---- a/grub-core/lib/i386/backtrace.c -+++ b/grub-core/lib/i386/backtrace.c -@@ -15,11 +15,23 @@ - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -+#include -+#ifdef GRUB_UTIL -+#define REALLY_GRUB_UTIL GRUB_UTIL -+#undef GRUB_UTIL -+#endif -+ -+#include -+#include -+ -+#ifdef REALLY_GRUB_UTIL -+#define GRUB_UTIL REALLY_GRUB_UTIL -+#undef REALLY_GRUB_UTIL -+#endif - - #include - #include - #include --#include - #include - #include - #include diff --git a/0041-Fix-up-some-man-pages-rpmdiff-noticed.patch b/0041-Fix-up-some-man-pages-rpmdiff-noticed.patch deleted file mode 100644 index be58417..0000000 --- a/0041-Fix-up-some-man-pages-rpmdiff-noticed.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 23 Sep 2014 09:58:49 -0400 -Subject: [PATCH] Fix up some man pages rpmdiff noticed. - ---- - configure.ac | 2 ++ - util/grub-macbless.8 | 26 +++++++++++++++++++ - util/grub-mkimage.1 | 2 +- - util/grub-syslinux2cfg.1 | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 94 insertions(+), 1 deletion(-) - create mode 100644 util/grub-macbless.8 - create mode 100644 util/grub-syslinux2cfg.1 - -diff --git a/configure.ac b/configure.ac -index 58e57a745fa..a0030632220 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -87,6 +87,7 @@ grub_TRANSFORM([grub-get-kernel-settings.3]) - grub_TRANSFORM([grub-glue-efi.3]) - grub_TRANSFORM([grub-install.1]) - grub_TRANSFORM([grub-kbdcomp.3]) -+grub_TRANSFORM([grub-macbless.8]) - grub_TRANSFORM([grub-menulst2cfg.1]) - grub_TRANSFORM([grub-mkconfig.1]) - grub_TRANSFORM([grub-mkfont.3]) -@@ -105,6 +106,7 @@ grub_TRANSFORM([grub-render-label.3]) - grub_TRANSFORM([grub-script-check.3]) - grub_TRANSFORM([grub-set-default.1]) - grub_TRANSFORM([grub-sparc64-setup.3]) -+grub_TRANSFORM([grub-syslinux2cfg.1]) - - # Optimization flag. Allow user to override. - if test "x$TARGET_CFLAGS" = x; then -diff --git a/util/grub-macbless.8 b/util/grub-macbless.8 -new file mode 100644 -index 00000000000..ae842f3a606 ---- /dev/null -+++ b/util/grub-macbless.8 -@@ -0,0 +1,26 @@ -+.TH GRUB-MACBLESS 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-macbless\fR \(em Mac-style bless utility for HFS or HFS+ -+ -+.SH SYNOPSIS -+\fBgrub-macbless\fR [-p | --ppc] [-v | --verbose] [-x | --x86] \fIFILE\fR -+ -+.SH DESCRIPTION -+\fBgrub-mkimage\fR blesses a file on an HFS or HFS+ file system, so that it -+can be used to boot a Mac. -+ -+.SH OPTIONS -+.TP -+--ppc -+Bless the file for use on PPC-based Macs. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.TP -+--x86 -+Bless the file for use on x86-based Macs. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkimage.1 b/util/grub-mkimage.1 -index 4dea4f54597..0eaaafe505b 100644 ---- a/util/grub-mkimage.1 -+++ b/util/grub-mkimage.1 -@@ -17,7 +17,7 @@ - [-v | --verbose] \fIMODULES\fR - - .SH DESCRIPTION --\fBgrub-mkimage\fI builds a bootable image of GRUB. -+\fBgrub-mkimage\fR builds a bootable image of GRUB. - - .SH OPTIONS - .TP -diff --git a/util/grub-syslinux2cfg.1 b/util/grub-syslinux2cfg.1 -new file mode 100644 -index 00000000000..85309482718 ---- /dev/null -+++ b/util/grub-syslinux2cfg.1 -@@ -0,0 +1,65 @@ -+.TH GRUB-SYSLINUX2CFG 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-syslinux2cfg\fR \(em Transform a syslinux config file into a GRUB config. -+ -+.SH SYNOPSIS -+\fBgrub-syslinux2cfg\fR [-c | --cwd=\fRDIR\fI] [-r | --root=\fIDIR\fR] [-v | --verbose] -+.RE -+.RS 25 -+[-t | --target-root=\fIDIR\fR] [-T | --target-cwd=\fIDIR\fR] -+.RE -+.RS 25 -+[-o | --output=\fIFILE\fR] [[-i | --isolinux] | -+.RE -+.RS 46 -+ [-s | --syslinux] | -+.RE -+.RS 46 -+ [-p | --pxelinux]] \fIFILE\fR -+ -+.SH DESCRIPTION -+\fBgrub-syslinux2cfg\fR builds a GRUB configuration file out of an existing -+syslinux configuration file. -+ -+.SH OPTIONS -+.TP -+--cwd=\fIDIR\fR -+Set \fIDIR\fR as syslinux's working directory. The default is to use the -+parent directory of the input file. -+ -+.TP -+--root=\fIDIR\fR -+Set \fIDIR\fR as the root directory of the syslinux disk. The default value -+is "/". -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.TP -+--target-root=\fIDIR\fR -+Root directory as it will be seen at runtime. The default value is "/". -+ -+.TP -+--target-cwd=\fIDIR\fR -+Working directory of syslinux as it will be seen at runtime. The default -+value is the parent directory of the input file. -+ -+.TP -+--output=\fIFILE\fR -+Write the new config file to \fIFILE\fR. The default value is standard output. -+ -+.TP -+--isolinux -+Assume that the input file is an isolinux configuration file. -+ -+.TP -+--pxelinux -+Assume that the input file is a pxelinux configuration file. -+ -+.TP -+--syslinux -+Assume that the input file is a syslinux configuration file. -+ -+.SH SEE ALSO -+.BR "info grub" diff --git a/0042-Make-our-info-pages-say-grub2-where-appropriate.patch b/0042-Make-our-info-pages-say-grub2-where-appropriate.patch deleted file mode 100644 index be28efd..0000000 --- a/0042-Make-our-info-pages-say-grub2-where-appropriate.patch +++ /dev/null @@ -1,1008 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 12:59:58 +0200 -Subject: [PATCH] Make our info pages say "grub2" where appropriate. - -This needs to be hooked up to --program-transform=, but I haven't had -time. - -Signed-off-by: Peter Jones ---- - docs/grub-dev.texi | 4 +- - docs/grub.texi | 321 ++++++++++++++++++++++++++++------------------------- - 2 files changed, 171 insertions(+), 154 deletions(-) - -diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 6c629a23e2d..19f708ee662 100644 ---- a/docs/grub-dev.texi -+++ b/docs/grub-dev.texi -@@ -1,7 +1,7 @@ - \input texinfo - @c -*-texinfo-*- - @c %**start of header --@setfilename grub-dev.info -+@setfilename grub2-dev.info - @include version-dev.texi - @settitle GNU GRUB Developers Manual @value{VERSION} - @c Unify all our little indices for now. -@@ -32,7 +32,7 @@ Invariant Sections. - - @dircategory Kernel - @direntry --* grub-dev: (grub-dev). The GRand Unified Bootloader Dev -+* grub2-dev: (grub2-dev). The GRand Unified Bootloader Dev - @end direntry - - @setchapternewpage odd -diff --git a/docs/grub.texi b/docs/grub.texi -index 69f08d289f9..0615d0ed97e 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -1,7 +1,7 @@ - \input texinfo - @c -*-texinfo-*- - @c %**start of header --@setfilename grub.info -+@setfilename grub2.info - @include version.texi - @settitle GNU GRUB Manual @value{VERSION} - @c Unify all our little indices for now. -@@ -32,15 +32,15 @@ Invariant Sections. - - @dircategory Kernel - @direntry --* GRUB: (grub). The GRand Unified Bootloader --* grub-install: (grub)Invoking grub-install. Install GRUB on your drive --* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration --* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. --* grub-mkrelpath: (grub)Invoking grub-mkrelpath. --* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image --* grub-mount: (grub)Invoking grub-mount. Mount a file system using GRUB --* grub-probe: (grub)Invoking grub-probe. Probe device information --* grub-script-check: (grub)Invoking grub-script-check. -+* GRUB2: (grub2). The GRand Unified Bootloader -+* grub2-install: (grub2)Invoking grub2-install. Install GRUB on your drive -+* grub2-mkconfig: (grub2)Invoking grub2-mkconfig. Generate GRUB configuration -+* grub2-mkpasswd-pbkdf2: (grub2)Invoking grub2-mkpasswd-pbkdf2. -+* grub2-mkrelpath: (grub2)Invoking grub2-mkrelpath. -+* grub2-mkrescue: (grub2)Invoking grub2-mkrescue. Make a GRUB rescue image -+* grub2-mount: (grub2)Invoking grub2-mount. Mount a file system using GRUB -+* grub2-probe: (grub2)Invoking grub2-probe. Probe device information -+* grub2-script-check: (grub2)Invoking grub2-script-check. - @end direntry - - @setchapternewpage odd -@@ -103,15 +103,15 @@ This edition documents version @value{VERSION}. - * Platform-specific operations:: Platform-specific operations - * Supported kernels:: The list of supported kernels - * Troubleshooting:: Error messages produced by GRUB --* Invoking grub-install:: How to use the GRUB installer --* Invoking grub-mkconfig:: Generate a GRUB configuration file --* Invoking grub-mkpasswd-pbkdf2:: -+* Invoking grub2-install:: How to use the GRUB installer -+* Invoking grub2-mkconfig:: Generate a GRUB configuration file -+* Invoking grub2-mkpasswd-pbkdf2:: - Generate GRUB password hashes --* Invoking grub-mkrelpath:: Make system path relative to its root --* Invoking grub-mkrescue:: Make a GRUB rescue image --* Invoking grub-mount:: Mount a file system using GRUB --* Invoking grub-probe:: Probe device information for GRUB --* Invoking grub-script-check:: Check GRUB script file for syntax errors -+* Invoking grub2-mkrelpath:: Make system path relative to its root -+* Invoking grub2-mkrescue:: Make a GRUB rescue image -+* Invoking grub2-mount:: Mount a file system using GRUB -+* Invoking grub2-probe:: Probe device information for GRUB -+* Invoking grub2-script-check:: Check GRUB script file for syntax errors - * Obtaining and Building GRUB:: How to obtain and build GRUB - * Reporting bugs:: Where you should send a bug report - * Future:: Some future plans on GRUB -@@ -230,7 +230,7 @@ surprising. - - @item - @file{grub.cfg} is typically automatically generated by --@command{grub-mkconfig} (@pxref{Simple configuration}). This makes it -+@command{grub2-mkconfig} (@pxref{Simple configuration}). This makes it - easier to handle versioned kernel upgrades. - - @item -@@ -244,7 +244,7 @@ scripting language: variables, conditionals, and loops are available. - @item - A small amount of persistent storage is available across reboots, using the - @command{save_env} and @command{load_env} commands in GRUB and the --@command{grub-editenv} utility. This is not available in all configurations -+@command{grub2-editenv} utility. This is not available in all configurations - (@pxref{Environment block}). - - @item -@@ -549,7 +549,7 @@ On OS which have device nodes similar to Unix-like OS GRUB tools use the - OS name. E.g. for GNU/Linux: - - @example --# @kbd{grub-install /dev/sda} -+# @kbd{grub2-install /dev/sda} - @end example - - On AROS we use another syntax. For volumes: -@@ -572,7 +572,7 @@ For disks we use syntax: - E.g. - - @example --# @kbd{grub-install //:ata.device/0/0} -+# @kbd{grub2-install //:ata.device/0/0} - @end example - - On Windows we use UNC path. For volumes it's typically -@@ -599,7 +599,7 @@ For disks it's - E.g. - - @example --# @kbd{grub-install \\?\PhysicalDrive0} -+# @kbd{grub2-install \\?\PhysicalDrive0} - @end example - - Beware that you may need to further escape the backslashes depending on your -@@ -609,7 +609,7 @@ When compiled with cygwin support then cygwin drive names are automatically - when needed. E.g. - - @example --# @kbd{grub-install /dev/sda} -+# @kbd{grub2-install /dev/sda} - @end example - - @node Installation -@@ -622,7 +622,7 @@ from the source tarball, or as a package for your OS. - - After you have done that, you need to install the boot loader on a - drive (floppy or hard disk) by using the utility --@command{grub-install} (@pxref{Invoking grub-install}) on a UNIX-like OS. -+@command{grub2-install} (@pxref{Invoking grub2-install}) on a UNIX-like OS. - - GRUB comes with boot images, which are normally put in the directory - @file{/usr/lib/grub/-} (for BIOS-based machines -@@ -633,22 +633,22 @@ loader needs to find them (usually @file{/boot}) will be called - the @dfn{boot directory}. - - @menu --* Installing GRUB using grub-install:: -+* Installing GRUB using grub2-install:: - * Making a GRUB bootable CD-ROM:: - * Device map:: - * BIOS installation:: - @end menu - - --@node Installing GRUB using grub-install --@section Installing GRUB using grub-install -+@node Installing GRUB using grub2-install -+@section Installing GRUB using grub2-install - - For information on where GRUB should be installed on PC BIOS platforms, - @pxref{BIOS installation}. - - In order to install GRUB under a UNIX-like OS (such --as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking --grub-install}) as the superuser (@dfn{root}). -+as @sc{gnu}), invoke the program @command{grub2-install} (@pxref{Invoking -+grub2-install}) as the superuser (@dfn{root}). - - The usage is basically very simple. You only need to specify one - argument to the program, namely, where to install the boot loader. The -@@ -657,13 +657,13 @@ For example, under Linux the following will install GRUB into the MBR - of the first IDE disk: - - @example --# @kbd{grub-install /dev/sda} -+# @kbd{grub2-install /dev/sda} - @end example - - Likewise, under GNU/Hurd, this has the same effect: - - @example --# @kbd{grub-install /dev/hd0} -+# @kbd{grub2-install /dev/hd0} - @end example - - But all the above examples assume that GRUB should put images under -@@ -677,7 +677,7 @@ boot floppy with a filesystem. Here is an example: - # @kbd{mke2fs /dev/fd0} - # @kbd{mount -t ext2 /dev/fd0 /mnt} - # @kbd{mkdir /mnt/boot} --# @kbd{grub-install --boot-directory=/mnt/boot /dev/fd0} -+# @kbd{grub2-install --boot-directory=/mnt/boot /dev/fd0} - # @kbd{umount /mnt} - @end group - @end example -@@ -689,30 +689,37 @@ floppy instead of exposing the USB drive as a hard disk (they call it - @example - # @kbd{losetup /dev/loop0 /dev/sdb1} - # @kbd{mount /dev/loop0 /mnt/usb} --# @kbd{grub-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0} -+# @kbd{grub2-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0} - @end example - - This install doesn't conflict with standard install as long as they are in - separate directories. - -+Note that @command{grub2-install} is actually just a shell script and the -+real task is done by other tools such as @command{grub2-mkimage}. Therefore, -+you may run those commands directly to install GRUB, without using -+@command{grub2-install}. Don't do that, however, unless you are very familiar -+with the internals of GRUB. Installing a boot loader on a running OS may be -+extremely dangerous. -+ - On EFI systems for fixed disk install you have to mount EFI System Partition. - If you mount it at @file{/boot/efi} then you don't need any special arguments: - - @example --# @kbd{grub-install} -+# @kbd{grub2-install} - @end example - - Otherwise you need to specify where your EFI System partition is mounted: - - @example --# @kbd{grub-install --efi-directory=/mnt/efi} -+# @kbd{grub2-install --efi-directory=/mnt/efi} - @end example - - For removable installs you have to use @option{--removable} and specify both - @option{--boot-directory} and @option{--efi-directory}: - - @example --# @kbd{grub-install --efi-directory=/mnt/usb --boot-directory=/mnt/usb/boot --removable} -+# @kbd{grub2-install --efi-directory=/mnt/usb --boot-directory=/mnt/usb/boot --removable} - @end example - - @node Making a GRUB bootable CD-ROM -@@ -732,10 +739,10 @@ usually also need to include a configuration file @file{grub.cfg} and some - other GRUB modules. - - To make a simple generic GRUB rescue CD, you can use the --@command{grub-mkrescue} program (@pxref{Invoking grub-mkrescue}): -+@command{grub2-mkrescue} program (@pxref{Invoking grub2-mkrescue}): - - @example --$ @kbd{grub-mkrescue -o grub.iso} -+$ @kbd{grub2-mkrescue -o grub.iso} - @end example - - You will often need to include other files in your image. To do this, first -@@ -758,7 +765,7 @@ directory @file{iso/}. - Finally, make the image: - - @example --$ @kbd{grub-mkrescue -o grub.iso iso} -+$ @kbd{grub2-mkrescue -o grub.iso iso} - @end example - - This produces a file named @file{grub.iso}, which then can be burned -@@ -774,7 +781,7 @@ storage devices. - @node Device map - @section The map between BIOS drives and OS devices - --If the device map file exists, the GRUB utilities (@command{grub-probe}, -+If the device map file exists, the GRUB utilities (@command{grub2-probe}, - etc.) read it to map BIOS drives to OS devices. This file consists of lines - like this: - -@@ -1254,23 +1261,23 @@ need to write the whole thing by hand. - @node Simple configuration - @section Simple configuration handling - --The program @command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}) -+The program @command{grub2-mkconfig} (@pxref{Invoking grub2-mkconfig}) - generates @file{grub.cfg} files suitable for most cases. It is suitable for - use when upgrading a distribution, and will discover available kernels and - attempt to generate menu entries for them. - --@command{grub-mkconfig} does have some limitations. While adding extra -+@command{grub2-mkconfig} does have some limitations. While adding extra - custom menu entries to the end of the list can be done by editing --@file{/etc/grub.d/40_custom} or creating @file{/boot/grub/custom.cfg}, -+@file{/etc/grub.d/40_custom} or creating @file{/boot/grub2/custom.cfg}, - changing the order of menu entries or changing their titles may require - making complex changes to shell scripts stored in @file{/etc/grub.d/}. This - may be improved in the future. In the meantime, those who feel that it - would be easier to write @file{grub.cfg} directly are encouraged to do so - (@pxref{Booting}, and @ref{Shell-like scripting}), and to disable any system --provided by their distribution to automatically run @command{grub-mkconfig}. -+provided by their distribution to automatically run @command{grub2-mkconfig}. - - The file @file{/etc/default/grub} controls the operation of --@command{grub-mkconfig}. It is sourced by a shell script, and so must be -+@command{grub2-mkconfig}. It is sourced by a shell script, and so must be - valid POSIX shell input; normally, it will just be a sequence of - @samp{KEY=value} lines, but if the value contains spaces or other special - characters then it must be quoted. For example: -@@ -1308,7 +1315,7 @@ works it's not recommended since titles often contain unstable device names - and may be translated - - If you set this to @samp{saved}, then the default menu entry will be that --saved by @samp{GRUB_SAVEDEFAULT} or @command{grub-set-default}. This relies on -+saved by @samp{GRUB_SAVEDEFAULT} or @command{grub2-set-default}. This relies on - the environment block, which may not be available in all situations - (@pxref{Environment block}). - -@@ -1319,7 +1326,7 @@ If this option is set to @samp{true}, then, when an entry is selected, save - it as a new default entry for use by future runs of GRUB. This is only - useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because - @samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with --@command{grub-set-default}. Unset by default. -+@command{grub2-set-default}. Unset by default. - This option relies on the environment block, which may not be available in - all situations (@pxref{Environment block}). - -@@ -1449,7 +1456,7 @@ intel-uc.img intel-ucode.img amd-uc.img amd-ucode.img early_ucode.cpio microcode - @end example - - @item GRUB_DISABLE_LINUX_UUID --Normally, @command{grub-mkconfig} will generate menu entries that use -+Normally, @command{grub2-mkconfig} will generate menu entries that use - universally-unique identifiers (UUIDs) to identify the root filesystem to - the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is - usually more reliable, but in some cases it may not be appropriate. To -@@ -1471,7 +1478,7 @@ If this option is set to @samp{true}, disable the generation of recovery - mode menu entries. - - @item GRUB_DISABLE_UUID --Normally, @command{grub-mkconfig} will generate menu entries that use -+Normally, @command{grub2-mkconfig} will generate menu entries that use - universally-unique identifiers (UUIDs) to identify various filesystems to - search for files. This is usually more reliable, but in some cases it may - not be appropriate. To disable this use of UUIDs, set this option to -@@ -1482,12 +1489,12 @@ not be appropriate. To disable this use of UUIDs, set this option to - @item GRUB_VIDEO_BACKEND - If graphical video support is required, either because the @samp{gfxterm} - graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set, --then @command{grub-mkconfig} will normally load all available GRUB video -+then @command{grub2-mkconfig} will normally load all available GRUB video - drivers and use the one most appropriate for your hardware. If you need to - override this for some reason, then you can set this option. - --After @command{grub-install} has been run, the available video drivers are --listed in @file{/boot/grub/video.lst}. -+After @command{grub2-install} has been run, the available video drivers are -+listed in @file{/boot/grub2/video.lst}. - - @item GRUB_GFXMODE - Set the resolution used on the @samp{gfxterm} graphical terminal. Note that -@@ -1519,7 +1526,7 @@ boot sequence. If you have problems, set this option to @samp{text} and - GRUB will tell Linux to boot in normal text mode. - - @item GRUB_DISABLE_OS_PROBER --Normally, @command{grub-mkconfig} will try to use the external -+Normally, @command{grub2-mkconfig} will try to use the external - @command{os-prober} program, if installed, to discover other operating - systems installed on the same system and generate appropriate menu entries - for them. Set this option to @samp{true} to disable this. -@@ -1529,7 +1536,7 @@ List of space-separated FS UUIDs of filesystems to be ignored from os-prober - output. For efi chainloaders it's @@ - - @item GRUB_DISABLE_SUBMENU --Normally, @command{grub-mkconfig} will generate top level menu entry for -+Normally, @command{grub2-mkconfig} will generate top level menu entry for - the kernel with highest version number and put all other found kernels - or alternative menu entries for recovery mode in submenu. For entries returned - by @command{os-prober} first entry will be put on top level and all others -@@ -1537,11 +1544,11 @@ in submenu. If this option is set to @samp{true}, flat menu with all entries - on top level will be generated instead. Changing this option will require - changing existing values of @samp{GRUB_DEFAULT}, @samp{fallback} (@pxref{fallback}) - and @samp{default} (@pxref{default}) environment variables as well as saved --default entry using @command{grub-set-default} and value used with --@command{grub-reboot}. -+default entry using @command{grub2-set-default} and value used with -+@command{grub2-reboot}. - - @item GRUB_ENABLE_CRYPTODISK --If set to @samp{y}, @command{grub-mkconfig} and @command{grub-install} will -+If set to @samp{y}, @command{grub2-mkconfig} and @command{grub2-install} will - check for encrypted disks and generate additional commands needed to access - them during boot. Note that in this case unattended boot is not possible - because GRUB will wait for passphrase to unlock encrypted container. -@@ -1600,7 +1607,7 @@ confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or - - @end table - --For more detailed customisation of @command{grub-mkconfig}'s output, you may -+For more detailed customisation of @command{grub2-mkconfig}'s output, you may - edit the scripts in @file{/etc/grub.d} directly. - @file{/etc/grub.d/40_custom} is particularly useful for adding entire custom - menu entries; simply type the menu entries you want to add at the end of -@@ -1862,7 +1869,7 @@ images as well. - Mount this partition on/mnt/boot and disable GRUB in all OSes and manually - install self-compiled latest GRUB with: - --@code{grub-install --boot-directory=/mnt/boot /dev/sda} -+@code{grub2-install --boot-directory=/mnt/boot /dev/sda} - - In all the OSes install GRUB tools but disable installing GRUB in bootsector, - so you'll have menu.lst and grub.cfg available for use. Also disable os-prober -@@ -1872,20 +1879,20 @@ use by setting: - - in /etc/default/grub - --Then write a grub.cfg (/mnt/boot/grub/grub.cfg): -+Then write a grub.cfg (/mnt/boot/grub2/grub.cfg): - - @example - - menuentry "OS using grub2" @{ - insmod xfs - search --set=root --label OS1 --hint hd0,msdos8 -- configfile /boot/grub/grub.cfg -+ configfile /boot/grub2/grub.cfg - @} - - menuentry "OS using grub2-legacy" @{ - insmod ext2 - search --set=root --label OS2 --hint hd0,msdos6 -- legacy_configfile /boot/grub/menu.lst -+ legacy_configfile /boot/grub2/menu.lst - @} - - menuentry "Windows XP" @{ -@@ -1948,15 +1955,15 @@ GRUB supports embedding a configuration file directly into the core image, - so that it is loaded before entering normal mode. This is useful, for - example, when it is not straightforward to find the real configuration file, - or when you need to debug problems with loading that file. --@command{grub-install} uses this feature when it is not using BIOS disk -+@command{grub2-install} uses this feature when it is not using BIOS disk - functions or when installing to a different disk from the one containing - @file{/boot/grub}, in which case it needs to use the @command{search} - command (@pxref{search}) to find @file{/boot/grub}. - - To embed a configuration file, use the @option{-c} option to --@command{grub-mkimage}. The file is copied into the core image, so it may -+@command{grub2-mkimage}. The file is copied into the core image, so it may - reside anywhere on the file system, and may be removed after running --@command{grub-mkimage}. -+@command{grub2-mkimage}. - - After the embedded configuration file (if any) is executed, GRUB will load - the @samp{normal} module (@pxref{normal}), which will then read the real -@@ -1991,13 +1998,13 @@ included in the core image: - @example - @group - search.fs_label grub root --if [ -e /boot/grub/example/test1.cfg ]; then -+if [ -e /boot/grub2/example/test1.cfg ]; then - set prefix=($root)/boot/grub -- configfile /boot/grub/example/test1.cfg -+ configfile /boot/grub2/example/test1.cfg - else -- if [ -e /boot/grub/example/test2.cfg ]; then -+ if [ -e /boot/grub2/example/test2.cfg ]; then - set prefix=($root)/boot/grub -- configfile /boot/grub/example/test2.cfg -+ configfile /boot/grub2/example/test2.cfg - else - echo "Could not find an example configuration file!" - fi -@@ -2521,7 +2528,7 @@ grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/i38 - @end group - @end example - --Then follow instructions printed out by grub-mknetdir on configuring your DHCP -+Then follow instructions printed out by grub2-mknetdir on configuring your DHCP - server. - - The grub.cfg file is placed in the same directory as the path output by -@@ -2715,7 +2722,7 @@ team are: - @end table - - To take full advantage of this function, install GRUB into the MBR --(@pxref{Installing GRUB using grub-install}). -+(@pxref{Installing GRUB using grub2-install}). - - If you have a laptop which has a similar feature and not in the above list - could you figure your address and contribute? -@@ -2776,7 +2783,7 @@ bytes. - The sole function of @file{boot.img} is to read the first sector of the core - image from a local disk and jump to it. Because of the size restriction, - @file{boot.img} cannot understand any file system structure, so --@command{grub-install} hardcodes the location of the first sector of the -+@command{grub2-install} hardcodes the location of the first sector of the - core image into @file{boot.img} when installing GRUB. - - @item diskboot.img -@@ -2806,7 +2813,7 @@ images. - - @item core.img - This is the core image of GRUB. It is built dynamically from the kernel --image and an arbitrary list of modules by the @command{grub-mkimage} -+image and an arbitrary list of modules by the @command{grub2-mkimage} - program. Usually, it contains enough modules to access @file{/boot/grub}, - and loads everything else (including menu handling, the ability to load - target operating systems, and so on) from the file system at run-time. The -@@ -2858,7 +2865,7 @@ GRUB 2 has no single Stage 2 image. Instead, it loads modules from - In GRUB 2, images for booting from CD-ROM drives are now constructed using - @file{cdboot.img} and @file{core.img}, making sure that the core image - contains the @samp{iso9660} module. It is usually best to use the --@command{grub-mkrescue} program for this. -+@command{grub2-mkrescue} program for this. - - @item nbgrub - There is as yet no equivalent for @file{nbgrub} in GRUB 2; it was used by -@@ -3014,8 +3021,8 @@ There are two ways to specify files, by @dfn{absolute file name} and by - - An absolute file name resembles a Unix absolute file name, using - @samp{/} for the directory separator (not @samp{\} as in DOS). One --example is @samp{(hd0,1)/boot/grub/grub.cfg}. This means the file --@file{/boot/grub/grub.cfg} in the first partition of the first hard -+example is @samp{(hd0,1)/boot/grub2/grub.cfg}. This means the file -+@file{/boot/grub2/grub.cfg} in the first partition of the first hard - disk. If you omit the device name in an absolute file name, GRUB uses - GRUB's @dfn{root device} implicitly. So if you set the root device to, - say, @samp{(hd1,1)} by the command @samp{set root=(hd1,1)} (@pxref{set}), -@@ -3023,8 +3030,8 @@ then @code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. - - On ZFS filesystem the first path component must be - @var{volume}@samp{@@}[@var{snapshot}]. --So @samp{/rootvol@@snap-129/boot/grub/grub.cfg} refers to file --@samp{/boot/grub/grub.cfg} in snapshot of volume @samp{rootvol} with name -+So @samp{/rootvol@@snap-129/boot/grub2/grub.cfg} refers to file -+@samp{/boot/grub2/grub.cfg} in snapshot of volume @samp{rootvol} with name - @samp{snap-129}. Trailing @samp{@@} after volume name is mandatory even if - snapshot name is omitted. - -@@ -3427,7 +3434,7 @@ The more recent release of Minix would then be identified as - @samp{other>minix>minix-3.4.0}. - - This variable is often set by @samp{GRUB_DEFAULT} (@pxref{Simple --configuration}), @command{grub-set-default}, or @command{grub-reboot}. -+configuration}), @command{grub2-set-default}, or @command{grub2-reboot}. - - - @node fallback -@@ -3517,7 +3524,7 @@ If this variable is set, it names the language code that the - example, French would be named as @samp{fr}, and Simplified Chinese as - @samp{zh_CN}. - --@command{grub-mkconfig} (@pxref{Simple configuration}) will try to set a -+@command{grub2-mkconfig} (@pxref{Simple configuration}) will try to set a - reasonable default for this variable based on the system locale. - - -@@ -3525,10 +3532,10 @@ reasonable default for this variable based on the system locale. - @subsection locale_dir - - If this variable is set, it names the directory where translation files may --be found (@pxref{gettext}), usually @file{/boot/grub/locale}. Otherwise, -+be found (@pxref{gettext}), usually @file{/boot/grub2/locale}. Otherwise, - internationalization is disabled. - --@command{grub-mkconfig} (@pxref{Simple configuration}) will set a reasonable -+@command{grub2-mkconfig} (@pxref{Simple configuration}) will set a reasonable - default for this variable if internationalization is needed and any - translation files are available. - -@@ -3646,7 +3653,7 @@ input. The default is not to pause output. - - The location of the @samp{/boot/grub} directory as an absolute file name - (@pxref{File name syntax}). This is normally set by GRUB at startup based --on information provided by @command{grub-install}. GRUB modules are -+on information provided by @command{grub2-install}. GRUB modules are - dynamically loaded from this directory, so it must be set correctly in order - for many parts of GRUB to work. - -@@ -3737,17 +3744,17 @@ GRUB provides an ``environment block'' which can be used to save a small - amount of state. - - The environment block is a preallocated 1024-byte file, which normally lives --in @file{/boot/grub/grubenv} (although you should not assume this). At boot -+in @file{/boot/grub2/grubenv} (although you should not assume this). At boot - time, the @command{load_env} command (@pxref{load_env}) loads environment - variables from it, and the @command{save_env} (@pxref{save_env}) command - saves environment variables to it. From a running system, the --@command{grub-editenv} utility can be used to edit the environment block. -+@command{grub2-editenv} utility can be used to edit the environment block. - - For safety reasons, this storage is only available when installed on a plain - disk (no LVM or RAID), using a non-checksumming filesystem (no ZFS), and - using BIOS or EFI functions (no ATA, USB or IEEE1275). - --@command{grub-mkconfig} uses this facility to implement -+@command{grub2-mkconfig} uses this facility to implement - @samp{GRUB_SAVEDEFAULT} (@pxref{Simple configuration}). - - -@@ -4476,7 +4483,7 @@ Translate @var{string} into the current language. - - The current language code is stored in the @samp{lang} variable in GRUB's - environment (@pxref{lang}). Translation files in MO format are read from --@samp{locale_dir} (@pxref{locale_dir}), usually @file{/boot/grub/locale}. -+@samp{locale_dir} (@pxref{locale_dir}), usually @file{/boot/grub2/locale}. - @end deffn - - -@@ -4871,7 +4878,7 @@ Define a user named @var{user} with password @var{clear-password}. - - @deffn Command password_pbkdf2 user hashed-password - Define a user named @var{user} with password hash @var{hashed-password}. --Use @command{grub-mkpasswd-pbkdf2} (@pxref{Invoking grub-mkpasswd-pbkdf2}) -+Use @command{grub2-mkpasswd-pbkdf2} (@pxref{Invoking grub2-mkpasswd-pbkdf2}) - to generate password hashes. @xref{Security}. - @end deffn - -@@ -5814,8 +5821,8 @@ The @samp{password} (@pxref{password}) and @samp{password_pbkdf2} - which has an associated password. @samp{password} sets the password in - plain text, requiring @file{grub.cfg} to be secure; @samp{password_pbkdf2} - sets the password hashed using the Password-Based Key Derivation Function --(RFC 2898), requiring the use of @command{grub-mkpasswd-pbkdf2} --(@pxref{Invoking grub-mkpasswd-pbkdf2}) to generate password hashes. -+(RFC 2898), requiring the use of @command{grub2-mkpasswd-pbkdf2} -+(@pxref{Invoking grub2-mkpasswd-pbkdf2}) to generate password hashes. - - In order to enable authentication support, the @samp{superusers} environment - variable must be set to a list of usernames, separated by any of spaces, -@@ -5860,7 +5867,7 @@ menuentry "May be run by user1 or a superuser" --users user1 @{ - @end group - @end example - --The @command{grub-mkconfig} program does not yet have built-in support for -+The @command{grub2-mkconfig} program does not yet have built-in support for - generating configuration files with authentication. You can use - @file{/etc/grub.d/40_custom} to add simple superuser authentication, by - adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} -@@ -5887,7 +5894,17 @@ may halt or otherwise impact the boot process. - - An initial trusted public key can be embedded within the GRUB @file{core.img} - using the @code{--pubkey} option to @command{grub-install} --(@pxref{Invoking grub-install}). -+(@pxref{Invoking grub2-install}). -+ -+@comment Unfortunately --pubkey is not yet supported by grub2-install, -+@comment but we should not bring up internal detail grub2-mkimage here -+@comment in the user guide (as opposed to developer's manual). -+ -+@comment An initial trusted public key can be embedded within the GRUB -+@comment @file{core.img} using the @code{--pubkey} option to -+@comment @command{grub2-mkimage} (@pxref{Invoking grub2-install}). Presently it -+@comment is necessary to write a custom wrapper around @command{grub2-mkimage} -+@comment using the @code{--grub-mkimage} flag to @command{grub2-install}. - - GRUB uses GPG-style detached signatures (meaning that a file - @file{foo.sig} will be produced when file @file{foo} is signed), and -@@ -5907,8 +5924,8 @@ gpg --detach-sign /path/to/file - For successful validation of all of GRUB's subcomponents and the - loaded OS kernel, they must all be signed. One way to accomplish this - is the following (after having already produced the desired --@file{grub.cfg} file, e.g., by running @command{grub-mkconfig} --(@pxref{Invoking grub-mkconfig}): -+@file{grub.cfg} file, e.g., by running @command{grub2-mkconfig} -+(@pxref{Invoking grub2-mkconfig}): - - @example - @group -@@ -5930,7 +5947,7 @@ See also: @ref{check_signatures}, @ref{verify_detached}, @ref{trust}, - Note that internally signature enforcement is controlled by setting - the environment variable @code{check_signatures} equal to - @code{enforce}. Passing one or more @code{--pubkey} options to --@command{grub-mkimage} implicitly defines @code{check_signatures} -+@command{grub2-mkimage} implicitly defines @code{check_signatures} - equal to @code{enforce} in @file{core.img} prior to processing any - configuration files. - -@@ -6388,10 +6405,10 @@ Required files are: - - GRUB's normal start-up procedure involves setting the @samp{prefix} - environment variable to a value set in the core image by --@command{grub-install}, setting the @samp{root} variable to match, loading -+@command{grub2-install}, setting the @samp{root} variable to match, loading - the @samp{normal} module from the prefix, and running the @samp{normal} - command (@pxref{normal}). This command is responsible for reading --@file{/boot/grub/grub.cfg}, running the menu, and doing all the useful -+@file{/boot/grub2/grub.cfg}, running the menu, and doing all the useful - things GRUB is supposed to do. - - If, instead, you only get a rescue shell, this usually means that GRUB -@@ -6417,8 +6434,8 @@ normal - - However, any problem that leaves you in the rescue shell probably means that - GRUB was not correctly installed. It may be more useful to try to reinstall --it properly using @kbd{grub-install @var{device}} (@pxref{Invoking --grub-install}). When doing this, there are a few things to remember: -+it properly using @kbd{grub2-install @var{device}} (@pxref{Invoking -+grub2-install}). When doing this, there are a few things to remember: - - @itemize @bullet{} - @item -@@ -6430,7 +6447,7 @@ is usually better to use UUIDs or file system labels and avoid depending on - drive ordering entirely. - - @item --At least on BIOS systems, if you tell @command{grub-install} to install GRUB -+At least on BIOS systems, if you tell @command{grub2-install} to install GRUB - to a partition but GRUB has already been installed in the master boot - record, then the GRUB installation in the partition will be ignored. - -@@ -6461,21 +6478,21 @@ entry which claims partition start at block 0. This change will not hamper - bootability on other machines. - - --@node Invoking grub-install --@chapter Invoking grub-install -+@node Invoking grub2-install -+@chapter Invoking grub2-install - --The program @command{grub-install} generates a GRUB core image using --@command{grub-mkimage} and installs it on your system. You must specify the -+The program @command{grub2-install} generates a GRUB core image using -+@command{grub2-mkimage} and installs it on your system. You must specify the - device name on which you want to install GRUB, like this: - - @example --grub-install @var{install_device} -+grub2-install @var{install_device} - @end example - - The device name @var{install_device} is an OS device name or a GRUB - device name. - --@command{grub-install} accepts the following options: -+@command{grub2-install} accepts the following options: - - @table @option - @item --help -@@ -6491,13 +6508,13 @@ separate partition or a removable disk. - If this option is not specified then it defaults to @file{/boot}, so - - @example --@kbd{grub-install /dev/sda} -+@kbd{grub2-install /dev/sda} - @end example - - is equivalent to - - @example --@kbd{grub-install --boot-directory=/boot/ /dev/sda} -+@kbd{grub2-install --boot-directory=/boot/ /dev/sda} - @end example - - Here is an example in which you have a separate @dfn{boot} partition which is -@@ -6505,16 +6522,16 @@ mounted on - @file{/mnt/boot}: - - @example --@kbd{grub-install --boot-directory=/mnt/boot /dev/sdb} -+@kbd{grub2-install --boot-directory=/mnt/boot /dev/sdb} - @end example - - @item --recheck --Recheck the device map, even if @file{/boot/grub/device.map} already -+Recheck the device map, even if @file{/boot/grub2/device.map} already - exists. You should use this option whenever you add/remove a disk - into/from your computer. - - @item --no-rs-codes --By default on x86 BIOS systems, @command{grub-install} will use some -+By default on x86 BIOS systems, @command{grub2-install} will use some - extra space in the bootloader embedding area for Reed-Solomon - error-correcting codes. This enables GRUB to still boot successfully - if some blocks are corrupted. The exact amount of protection offered -@@ -6527,17 +6544,17 @@ installation}) where GRUB does not reside in any unpartitioned space - outside of the MBR. Disable the Reed-Solomon codes with this option. - @end table - --@node Invoking grub-mkconfig --@chapter Invoking grub-mkconfig -+@node Invoking grub2-mkconfig -+@chapter Invoking grub2-mkconfig - --The program @command{grub-mkconfig} generates a configuration file for GRUB -+The program @command{grub2-mkconfig} generates a configuration file for GRUB - (@pxref{Simple configuration}). - - @example --grub-mkconfig -o /boot/grub/grub.cfg -+grub-mkconfig -o /boot/grub2/grub.cfg - @end example - --@command{grub-mkconfig} accepts the following options: -+@command{grub2-mkconfig} accepts the following options: - - @table @option - @item --help -@@ -6553,17 +6570,17 @@ it to standard output. - @end table - - --@node Invoking grub-mkpasswd-pbkdf2 --@chapter Invoking grub-mkpasswd-pbkdf2 -+@node Invoking grub2-mkpasswd-pbkdf2 -+@chapter Invoking grub2-mkpasswd-pbkdf2 - --The program @command{grub-mkpasswd-pbkdf2} generates password hashes for -+The program @command{grub2-mkpasswd-pbkdf2} generates password hashes for - GRUB (@pxref{Security}). - - @example - grub-mkpasswd-pbkdf2 - @end example - --@command{grub-mkpasswd-pbkdf2} accepts the following options: -+@command{grub2-mkpasswd-pbkdf2} accepts the following options: - - @table @option - @item -c @var{number} -@@ -6581,23 +6598,23 @@ Length of the salt. Defaults to 64. - @end table - - --@node Invoking grub-mkrelpath --@chapter Invoking grub-mkrelpath -+@node Invoking grub2-mkrelpath -+@chapter Invoking grub2-mkrelpath - --The program @command{grub-mkrelpath} makes a file system path relative to -+The program @command{grub2-mkrelpath} makes a file system path relative to - the root of its containing file system. For instance, if @file{/usr} is a - mount point, then: - - @example --$ @kbd{grub-mkrelpath /usr/share/grub/unicode.pf2} -+$ @kbd{grub2-mkrelpath /usr/share/grub/unicode.pf2} - @samp{/share/grub/unicode.pf2} - @end example - - This is mainly used internally by other GRUB utilities such as --@command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}), but may -+@command{grub2-mkconfig} (@pxref{Invoking grub2-mkconfig}), but may - occasionally also be useful for debugging. - --@command{grub-mkrelpath} accepts the following options: -+@command{grub2-mkrelpath} accepts the following options: - - @table @option - @item --help -@@ -6608,17 +6625,17 @@ Print the version number of GRUB and exit. - @end table - - --@node Invoking grub-mkrescue --@chapter Invoking grub-mkrescue -+@node Invoking grub2-mkrescue -+@chapter Invoking grub2-mkrescue - --The program @command{grub-mkrescue} generates a bootable GRUB rescue image -+The program @command{grub2-mkrescue} generates a bootable GRUB rescue image - (@pxref{Making a GRUB bootable CD-ROM}). - - @example - grub-mkrescue -o grub.iso - @end example - --All arguments not explicitly listed as @command{grub-mkrescue} options are -+All arguments not explicitly listed as @command{grub2-mkrescue} options are - passed on directly to @command{xorriso} in @command{mkisofs} emulation mode. - Options passed to @command{xorriso} will normally be interpreted as - @command{mkisofs} options; if the option @samp{--} is used, then anything -@@ -6633,7 +6650,7 @@ mkdir -p disk/boot/grub - grub-mkrescue -o grub.iso disk - @end example - --@command{grub-mkrescue} accepts the following options: -+@command{grub2-mkrescue} accepts the following options: - - @table @option - @item --help -@@ -6661,15 +6678,15 @@ Use @var{file} as the @command{xorriso} program, rather than the built-in - default. - - @item --grub-mkimage=@var{file} --Use @var{file} as the @command{grub-mkimage} program, rather than the -+Use @var{file} as the @command{grub2-mkimage} program, rather than the - built-in default. - @end table - - --@node Invoking grub-mount --@chapter Invoking grub-mount -+@node Invoking grub2-mount -+@chapter Invoking grub2-mount - --The program @command{grub-mount} performs a read-only mount of any file -+The program @command{grub2-mount} performs a read-only mount of any file - system or file system image that GRUB understands, using GRUB's file system - drivers via FUSE. (It is only available if FUSE development files were - present when GRUB was built.) This has a number of uses: -@@ -6701,13 +6718,13 @@ even if nobody has yet written a FUSE module specifically for that file - system type. - @end itemize - --Using @command{grub-mount} is normally as simple as: -+Using @command{grub2-mount} is normally as simple as: - - @example - grub-mount /dev/sda1 /mnt - @end example - --@command{grub-mount} must be given one or more images and a mount point as -+@command{grub2-mount} must be given one or more images and a mount point as - non-option arguments (if it is given more than one image, it will treat them - as a RAID set), and also accepts the following options: - -@@ -6729,13 +6746,13 @@ Show debugging output for conditions matching @var{string}. - @item -K prompt|@var{file} - @itemx --zfs-key=prompt|@var{file} - Load a ZFS encryption key. If you use @samp{prompt} as the argument, --@command{grub-mount} will read a passphrase from the terminal; otherwise, it -+@command{grub2-mount} will read a passphrase from the terminal; otherwise, it - will read key material from the specified file. - - @item -r @var{device} - @itemx --root=@var{device} - Set the GRUB root device to @var{device}. You do not normally need to set --this; @command{grub-mount} will automatically set the root device to the -+this; @command{grub2-mount} will automatically set the root device to the - root of the supplied file system. - - If @var{device} is just a number, then it will be treated as a partition -@@ -6753,10 +6770,10 @@ Print verbose messages. - @end table - - --@node Invoking grub-probe --@chapter Invoking grub-probe -+@node Invoking grub2-probe -+@chapter Invoking grub2-probe - --The program @command{grub-probe} probes device information for a given path -+The program @command{grub2-probe} probes device information for a given path - or device. - - @example -@@ -6764,7 +6781,7 @@ grub-probe --target=fs /boot/grub - grub-probe --target=drive --device /dev/sda1 - @end example - --@command{grub-probe} must be given a path or device as a non-option -+@command{grub2-probe} must be given a path or device as a non-option - argument, and also accepts the following options: - - @table @option -@@ -6777,16 +6794,16 @@ Print the version number of GRUB and exit. - @item -d - @itemx --device - If this option is given, then the non-option argument is a system device --name (such as @samp{/dev/sda1}), and @command{grub-probe} will print -+name (such as @samp{/dev/sda1}), and @command{grub2-probe} will print - information about that device. If it is not given, then the non-option - argument is a filesystem path (such as @samp{/boot/grub}), and --@command{grub-probe} will print information about the device containing that -+@command{grub2-probe} will print information about the device containing that - part of the filesystem. - - @item -m @var{file} - @itemx --device-map=@var{file} - Use @var{file} as the device map (@pxref{Device map}) rather than the --default, usually @samp{/boot/grub/device.map}. -+default, usually @samp{/boot/grub2/device.map}. - - @item -t @var{target} - @itemx --target=@var{target} -@@ -6839,19 +6856,19 @@ Print verbose messages. - @end table - - --@node Invoking grub-script-check --@chapter Invoking grub-script-check -+@node Invoking grub2-script-check -+@chapter Invoking grub2-script-check - --The program @command{grub-script-check} takes a GRUB script file -+The program @command{grub2-script-check} takes a GRUB script file - (@pxref{Shell-like scripting}) and checks it for syntax errors, similar to - commands such as @command{sh -n}. It may take a @var{path} as a non-option - argument; if none is supplied, it will read from standard input. - - @example --grub-script-check /boot/grub/grub.cfg -+grub-script-check /boot/grub2/grub.cfg - @end example - --@command{grub-script-check} accepts the following options: -+@command{grub2-script-check} accepts the following options: - - @table @option - @item --help diff --git a/0043-macos-just-build-chainloader-entries-don-t-try-any-x.patch b/0043-macos-just-build-chainloader-entries-don-t-try-any-x.patch deleted file mode 100644 index 574d117..0000000 --- a/0043-macos-just-build-chainloader-entries-don-t-try-any-x.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 24 May 2017 12:42:32 -0400 -Subject: [PATCH] macos: just build chainloader entries, don't try any xnu xnu. - -Since our bugs tell us that the xnu boot entries really just don't work -most of the time, and they create piles of extra boot entries, because -they can't quite figure out 32-vs-64 and other stuff like that. - -It's rediculous, and we should just boot their bootloader through the -chainloader instead. - -So this patch does that. - -Resolves: rhbz#893179 - -Signed-off-by: Peter Jones ---- - util/grub.d/30_os-prober.in | 78 +++++++++++---------------------------------- - 1 file changed, 18 insertions(+), 60 deletions(-) - -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 1b91c102f35..4b27bd20153 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -42,68 +42,25 @@ if [ -z "${OSPROBED}" ] ; then - fi - - osx_entry() { -- if [ x$2 = x32 ]; then -- # TRANSLATORS: it refers to kernel architecture (32-bit) -- bitstr="$(gettext "(32-bit)")" -- else -- # TRANSLATORS: it refers to kernel architecture (64-bit) -- bitstr="$(gettext "(64-bit)")" -- fi - # TRANSLATORS: it refers on the OS residing on device %s - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" -- cat << EOF --menuentry '$(echo "${LONGNAME} $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' { -+ hints="" -+ for hint in `"${grub_probe}" --device ${device} --target=efi_hints 2> /dev/null` ; do -+ hints="${hints} --hint=${hint}" -+ done -+ cat << EOF -+menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' { - EOF - save_default_entry | grub_add_tab - prepare_grub_to_access_device ${DEVICE} | grub_add_tab - cat << EOF -+ set gfxpayload=keep - load_video -- set do_resume=0 -- if [ /var/vm/sleepimage -nt10 / ]; then -- if xnu_resume /var/vm/sleepimage; then -- set do_resume=1 -- fi -- fi -- if [ \$do_resume = 0 ]; then -- xnu_uuid ${OSXUUID} uuid -- if [ -f /Extra/DSDT.aml ]; then -- acpi -e /Extra/DSDT.aml -- fi -- if [ /kernelcache -nt /System/Library/Extensions ]; then -- $1 /kernelcache boot-uuid=\${uuid} rd=*uuid -- elif [ -f /System/Library/Kernels/kernel ]; then -- $1 /System/Library/Kernels/kernel boot-uuid=\${uuid} rd=*uuid -- xnu_kextdir /System/Library/Extensions -- else -- $1 /mach_kernel boot-uuid=\${uuid} rd=*uuid -- if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then -- xnu_mkext /System/Library/Extensions.mkext -- else -- xnu_kextdir /System/Library/Extensions -- fi -- fi -- if [ -f /Extra/Extensions.mkext ]; then -- xnu_mkext /Extra/Extensions.mkext -- fi -- if [ -d /Extra/Extensions ]; then -- xnu_kextdir /Extra/Extensions -- fi -- if [ -f /Extra/devprop.bin ]; then -- xnu_devprop_load /Extra/devprop.bin -- fi -- if [ -f /Extra/splash.jpg ]; then -- insmod jpeg -- xnu_splash /Extra/splash.jpg -- fi -- if [ -f /Extra/splash.png ]; then -- insmod png -- xnu_splash /Extra/splash.png -- fi -- if [ -f /Extra/splash.tga ]; then -- insmod tga -- xnu_splash /Extra/splash.tga -- fi -- fi -+ insmod part_gpt -+ insmod hfsplus -+ search --no-floppy --fs-uuid --set=root ${hints} $(grub_get_device_id "${DEVICE}") -+ chainloader (\$root)/System/Library/CoreServices/boot.efi -+ boot - } - EOF - } -@@ -292,11 +249,12 @@ EOF - echo "$title_correction_code" - ;; - macosx) -- if [ "${UUID}" ]; then -- OSXUUID="${UUID}" -- osx_entry xnu_kernel 32 -- osx_entry xnu_kernel64 64 -- fi -+ for subdevice in ${DEVICE%[[:digit:]]*}* ; do -+ parttype="`"${grub_probe}" --device ${device} --target=gpt_parttype "${subdevice}" 2> /dev/null`" -+ if [[ "$parttype" = "426f6f74-0000-11aa-aa11-00306543ecac" ]]; then -+ DEVICE="${subdevice}" osx_entry -+ fi -+ done - ;; - hurd) - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" diff --git a/0044-grub2-btrfs-Add-ability-to-boot-from-subvolumes.patch b/0044-grub2-btrfs-Add-ability-to-boot-from-subvolumes.patch deleted file mode 100644 index 68dfc1d..0000000 --- a/0044-grub2-btrfs-Add-ability-to-boot-from-subvolumes.patch +++ /dev/null @@ -1,703 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jeff Mahoney -Date: Tue, 9 Jul 2019 13:39:45 +0200 -Subject: [PATCH] grub2/btrfs: Add ability to boot from subvolumes - -This patch adds the ability to specify a different root on a btrfs -filesystem too boot from other than the default one. - -btrfs-list-snapshots will list the subvolumes available on the -filesystem. - -set btrfs_subvol= and set btrfs_subvolid= will specify -which subvolume to use and any pathnames provided with either of those -variables set will start using that root. If the subvolume or subvolume id -doesn't exist, then an error case will result. - -It is possible to boot into a separate GRUB instance by exporting the -variable and loading the config file from the subvolume. - -Signed-off-by: Jeff Mahoney ---- - grub-core/fs/btrfs.c | 552 +++++++++++++++++++++++++++++++++++++++++++++++++-- - include/grub/btrfs.h | 1 + - 2 files changed, 533 insertions(+), 20 deletions(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 63203034dfc..f1fff7385b5 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -38,6 +38,9 @@ - #include - #include - #include -+#include -+#include -+#include - #include - #include - #include -@@ -79,9 +82,11 @@ struct grub_btrfs_superblock - grub_uint64_t generation; - grub_uint64_t root_tree; - grub_uint64_t chunk_tree; -- grub_uint8_t dummy2[0x20]; -+ grub_uint8_t dummy2[0x18]; -+ grub_uint64_t bytes_used; - grub_uint64_t root_dir_objectid; -- grub_uint8_t dummy3[0x41]; -+ grub_uint64_t num_devices; -+ grub_uint8_t dummy3[0x39]; - struct grub_btrfs_device this_device; - char label[0x100]; - grub_uint8_t dummy4[0x100]; -@@ -121,6 +126,7 @@ struct grub_btrfs_data - grub_uint64_t exttree; - grub_size_t extsize; - struct grub_btrfs_extent_data *extent; -+ grub_uint64_t fs_tree; - }; - - struct grub_btrfs_chunk_item -@@ -191,6 +197,14 @@ struct grub_btrfs_leaf_descriptor - } *data; - }; - -+struct grub_btrfs_root_ref -+{ -+ grub_uint64_t dirid; -+ grub_uint64_t sequence; -+ grub_uint16_t name_len; -+ const char name[0]; -+} __attribute__ ((packed)); -+ - struct grub_btrfs_time - { - grub_int64_t sec; -@@ -236,6 +250,14 @@ struct grub_btrfs_extent_data - - #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 - -+#define GRUB_BTRFS_ROOT_TREE_OBJECTID 1ULL -+#define GRUB_BTRFS_FS_TREE_OBJECTID 5ULL -+#define GRUB_BTRFS_ROOT_REF_KEY 156 -+#define GRUB_BTRFS_ROOT_ITEM_KEY 132 -+ -+static grub_uint64_t btrfs_default_subvolid = 0; -+static char *btrfs_default_subvol = NULL; -+ - static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, - 256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2 - }; -@@ -1173,6 +1195,62 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - return GRUB_ERR_NONE; - } - -+static grub_err_t -+get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree, -+ grub_uint64_t objectid, grub_uint64_t offset, -+ grub_uint64_t *fs_root); -+ -+static grub_err_t -+lookup_root_by_id(struct grub_btrfs_data *data, grub_uint64_t id) -+{ -+ grub_err_t err; -+ grub_uint64_t tree; -+ -+ err = get_fs_root(data, data->sblock.root_tree, id, -1, &tree); -+ if (!err) -+ data->fs_tree = tree; -+ return err; -+} -+ -+static grub_err_t -+find_path (struct grub_btrfs_data *data, -+ const char *path, struct grub_btrfs_key *key, -+ grub_uint64_t *tree, grub_uint8_t *type); -+ -+static grub_err_t -+lookup_root_by_name(struct grub_btrfs_data *data, const char *path) -+{ -+ grub_err_t err; -+ grub_uint64_t tree = 0; -+ grub_uint8_t type; -+ struct grub_btrfs_key key; -+ -+ err = find_path (data, path, &key, &tree, &type); -+ if (err) -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, "couldn't locate %s\n", path); -+ -+ if (key.object_id != grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK) || tree == 0) -+ return grub_error(GRUB_ERR_BAD_FILE_TYPE, "%s: not a subvolume\n", path); -+ -+ data->fs_tree = tree; -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+btrfs_handle_subvol(struct grub_btrfs_data *data __attribute__ ((unused))) -+{ -+ if (btrfs_default_subvol) -+ return lookup_root_by_name(data, btrfs_default_subvol); -+ -+ if (btrfs_default_subvolid) -+ return lookup_root_by_id(data, btrfs_default_subvolid); -+ -+ data->fs_tree = 0; -+ -+ return GRUB_ERR_NONE; -+} -+ -+ - static struct grub_btrfs_data * - grub_btrfs_mount (grub_device_t dev) - { -@@ -1208,6 +1286,13 @@ grub_btrfs_mount (grub_device_t dev) - data->devices_attached[0].dev = dev; - data->devices_attached[0].id = data->sblock.this_device.device_id; - -+ err = btrfs_handle_subvol (data); -+ if (err) -+ { -+ grub_free (data); -+ return NULL; -+ } -+ - return data; - } - -@@ -1673,6 +1758,91 @@ get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key, - return GRUB_ERR_NONE; - } - -+static grub_err_t -+find_pathname(struct grub_btrfs_data *data, grub_uint64_t objectid, -+ grub_uint64_t fs_root, const char *name, char **pathname) -+{ -+ grub_err_t err; -+ struct grub_btrfs_key key = { -+ .object_id = objectid, -+ .type = GRUB_BTRFS_ITEM_TYPE_INODE_REF, -+ .offset = 0, -+ }; -+ struct grub_btrfs_key key_out; -+ struct grub_btrfs_leaf_descriptor desc; -+ char *p = grub_strdup (name); -+ grub_disk_addr_t elemaddr; -+ grub_size_t elemsize; -+ grub_size_t alloc = grub_strlen(name) + 1; -+ -+ err = lower_bound(data, &key, &key_out, fs_root, -+ &elemaddr, &elemsize, &desc, 0); -+ if (err) -+ return grub_error(err, "lower_bound caught %d\n", err); -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF) -+ next(data, &desc, &elemaddr, &elemsize, &key_out); -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF) -+ { -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, -+ "Can't find inode ref for {%"PRIuGRUB_UINT64_T -+ ", %u, %"PRIuGRUB_UINT64_T"} %"PRIuGRUB_UINT64_T -+ "/%"PRIuGRUB_SIZE"\n", -+ key_out.object_id, key_out.type, -+ key_out.offset, elemaddr, elemsize); -+ } -+ -+ -+ while (key_out.type == GRUB_BTRFS_ITEM_TYPE_INODE_REF && -+ key_out.object_id != key_out.offset) { -+ struct grub_btrfs_inode_ref *inode_ref; -+ char *new; -+ -+ inode_ref = grub_malloc(elemsize + 1); -+ if (!inode_ref) -+ return grub_error(GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't allocate memory for inode_ref (%"PRIuGRUB_SIZE")\n", elemsize); -+ -+ err = grub_btrfs_read_logical(data, elemaddr, inode_ref, elemsize, 0); -+ if (err) -+ return grub_error(err, "read_logical caught %d\n", err); -+ -+ alloc += grub_le_to_cpu16 (inode_ref->n) + 2; -+ new = grub_malloc(alloc); -+ if (!new) -+ return grub_error(GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't allocate memory for name (%"PRIuGRUB_SIZE")\n", alloc); -+ -+ grub_memcpy(new, inode_ref->name, grub_le_to_cpu16 (inode_ref->n)); -+ if (p) -+ { -+ new[grub_le_to_cpu16 (inode_ref->n)] = '/'; -+ grub_strcpy (new + grub_le_to_cpu16 (inode_ref->n) + 1, p); -+ grub_free(p); -+ } -+ else -+ new[grub_le_to_cpu16 (inode_ref->n)] = 0; -+ grub_free(inode_ref); -+ -+ p = new; -+ -+ key.object_id = key_out.offset; -+ -+ err = lower_bound(data, &key, &key_out, fs_root, &elemaddr, -+ &elemsize, &desc, 0); -+ if (err) -+ return grub_error(err, "lower_bound caught %d\n", err); -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_INODE_REF) -+ next(data, &desc, &elemaddr, &elemsize, &key_out); -+ -+ } -+ -+ *pathname = p; -+ return 0; -+} -+ - static grub_err_t - find_path (struct grub_btrfs_data *data, - const char *path, struct grub_btrfs_key *key, -@@ -1691,14 +1861,26 @@ find_path (struct grub_btrfs_data *data, - char *origpath = NULL; - unsigned symlinks_max = 32; - -- err = get_root (data, key, tree, type); -- if (err) -- return err; -- - origpath = grub_strdup (path); - if (!origpath) - return grub_errno; - -+ if (data->fs_tree) -+ { -+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; -+ *tree = data->fs_tree; -+ /* This is a tree root, so everything starts at objectid 256 */ -+ key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); -+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -+ key->offset = 0; -+ } -+ else -+ { -+ err = get_root (data, key, tree, type); -+ if (err) -+ return err; -+ } -+ - while (1) - { - while (path[0] == '/') -@@ -1871,9 +2053,21 @@ find_path (struct grub_btrfs_data *data, - path = path_alloc = tmp; - if (path[0] == '/') - { -- err = get_root (data, key, tree, type); -- if (err) -- return err; -+ if (data->fs_tree) -+ { -+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; -+ *tree = data->fs_tree; -+ /* This is a tree root, so everything starts at objectid 256 */ -+ key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); -+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -+ key->offset = 0; -+ } -+ else -+ { -+ err = get_root (data, key, tree, type); -+ if (err) -+ return err; -+ } - } - continue; - } -@@ -2114,18 +2308,10 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) - data->tree, file->offset, buf, len); - } - --static grub_err_t --grub_btrfs_uuid (grub_device_t device, char **uuid) -+static char * -+btrfs_unparse_uuid(struct grub_btrfs_data *data) - { -- struct grub_btrfs_data *data; -- -- *uuid = NULL; -- -- data = grub_btrfs_mount (device); -- if (!data) -- return grub_errno; -- -- *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", -+ return grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", - grub_be_to_cpu16 (data->sblock.uuid[0]), - grub_be_to_cpu16 (data->sblock.uuid[1]), - grub_be_to_cpu16 (data->sblock.uuid[2]), -@@ -2134,6 +2320,20 @@ grub_btrfs_uuid (grub_device_t device, char **uuid) - grub_be_to_cpu16 (data->sblock.uuid[5]), - grub_be_to_cpu16 (data->sblock.uuid[6]), - grub_be_to_cpu16 (data->sblock.uuid[7])); -+} -+ -+static grub_err_t -+grub_btrfs_uuid (grub_device_t device, char **uuid) -+{ -+ struct grub_btrfs_data *data; -+ -+ *uuid = NULL; -+ -+ data = grub_btrfs_mount (device); -+ if (!data) -+ return grub_errno; -+ -+ *uuid = btrfs_unparse_uuid(data); - - grub_btrfs_unmount (data); - -@@ -2190,6 +2390,242 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), - } - #endif - -+static grub_err_t -+grub_cmd_btrfs_info (grub_command_t cmd __attribute__ ((unused)), int argc, -+ char **argv) -+{ -+ grub_device_t dev; -+ char *devname; -+ struct grub_btrfs_data *data; -+ char *uuid; -+ -+ if (argc < 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); -+ -+ devname = grub_file_get_device_name(argv[0]); -+ -+ if (!devname) -+ return grub_errno; -+ -+ dev = grub_device_open (devname); -+ grub_free (devname); -+ if (!dev) -+ return grub_errno; -+ -+ data = grub_btrfs_mount (dev); -+ if (!data) -+ { -+ grub_device_close(dev); -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to open fs"); -+ } -+ -+ if (data->sblock.label) -+ grub_printf("Label: '%s' ", data->sblock.label); -+ else -+ grub_printf("Label: none "); -+ -+ uuid = btrfs_unparse_uuid(data); -+ -+ grub_printf(" uuid: %s\n\tTotal devices %" PRIuGRUB_UINT64_T -+ " FS bytes used %" PRIuGRUB_UINT64_T "\n", -+ uuid, grub_cpu_to_le64(data->sblock.num_devices), -+ grub_cpu_to_le64(data->sblock.bytes_used)); -+ -+ grub_btrfs_unmount (data); -+ -+ return 0; -+} -+ -+static grub_err_t -+get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree, -+ grub_uint64_t objectid, grub_uint64_t offset, -+ grub_uint64_t *fs_root) -+{ -+ grub_err_t err; -+ struct grub_btrfs_key key_in = { -+ .object_id = objectid, -+ .type = GRUB_BTRFS_ROOT_ITEM_KEY, -+ .offset = offset, -+ }, key_out; -+ struct grub_btrfs_leaf_descriptor desc; -+ grub_disk_addr_t elemaddr; -+ grub_size_t elemsize; -+ struct grub_btrfs_root_item ri; -+ -+ err = lower_bound(data, &key_in, &key_out, tree, -+ &elemaddr, &elemsize, &desc, 0); -+ -+ if (err) -+ return err; -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM || elemaddr == 0) -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, -+ N_("can't find fs root for subvol %"PRIuGRUB_UINT64_T"\n"), -+ key_in.object_id); -+ -+ err = grub_btrfs_read_logical (data, elemaddr, &ri, sizeof (ri), 0); -+ if (err) -+ return err; -+ -+ *fs_root = ri.tree; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static const struct grub_arg_option options[] = { -+ {"output", 'o', 0, N_("Output to a variable instead of the console."), -+ N_("VARNAME"), ARG_TYPE_STRING}, -+ {"path-only", 'p', 0, N_("Show only the path of the subvolume."), 0, 0}, -+ {"id-only", 'i', 0, N_("Show only the id of the subvolume."), 0, 0}, -+ {0, 0, 0, 0, 0, 0} -+}; -+ -+static grub_err_t -+grub_cmd_btrfs_list_subvols (struct grub_extcmd_context *ctxt, -+ int argc, char **argv) -+{ -+ struct grub_btrfs_data *data; -+ grub_device_t dev; -+ char *devname; -+ grub_uint64_t tree; -+ struct grub_btrfs_key key_in = { -+ .object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_FS_TREE_OBJECTID), -+ .type = GRUB_BTRFS_ROOT_REF_KEY, -+ .offset = 0, -+ }, key_out; -+ struct grub_btrfs_leaf_descriptor desc; -+ grub_disk_addr_t elemaddr; -+ grub_uint64_t fs_root = 0; -+ grub_size_t elemsize; -+ grub_size_t allocated = 0; -+ int r = 0; -+ grub_err_t err; -+ char *buf = NULL; -+ int print = 1; -+ int path_only = ctxt->state[1].set; -+ int num_only = ctxt->state[2].set; -+ char *varname = NULL; -+ char *output = NULL; -+ -+ if (ctxt->state[0].set) { -+ varname = ctxt->state[0].arg; -+ print = 0; -+ } -+ -+ if (argc < 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); -+ -+ devname = grub_file_get_device_name(argv[0]); -+ if (!devname) -+ return grub_errno; -+ -+ dev = grub_device_open (devname); -+ grub_free (devname); -+ if (!dev) -+ return grub_errno; -+ -+ data = grub_btrfs_mount(dev); -+ if (!data) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "could not open device"); -+ -+ tree = data->sblock.root_tree; -+ err = get_fs_root(data, tree, grub_cpu_to_le64_compile_time (GRUB_BTRFS_FS_TREE_OBJECTID), -+ 0, &fs_root); -+ if (err) -+ goto out; -+ -+ err = lower_bound(data, &key_in, &key_out, tree, -+ &elemaddr, &elemsize, &desc, 0); -+ -+ if (err) -+ { -+ grub_btrfs_unmount(data); -+ return err; -+ } -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF || elemaddr == 0) -+ { -+ r = next(data, &desc, &elemaddr, &elemsize, &key_out); -+ } -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF) { -+ err = GRUB_ERR_FILE_NOT_FOUND; -+ grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("can't find root refs")); -+ goto out; -+ } -+ -+ do -+ { -+ struct grub_btrfs_root_ref *ref; -+ char *p = NULL; -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_REF) -+ { -+ r = 0; -+ break; -+ } -+ -+ if (elemsize > allocated) -+ { -+ grub_free(buf); -+ allocated = 2 * elemsize; -+ buf = grub_malloc(allocated + 1); -+ if (!buf) -+ { -+ r = -grub_errno; -+ break; -+ } -+ } -+ ref = (struct grub_btrfs_root_ref *)buf; -+ -+ err = grub_btrfs_read_logical(data, elemaddr, buf, elemsize, 0); -+ if (err) -+ { -+ r = -err; -+ break; -+ } -+ buf[elemsize] = 0; -+ -+ find_pathname(data, ref->dirid, fs_root, ref->name, &p); -+ -+ if (print) -+ { -+ if (num_only) -+ grub_printf("ID %"PRIuGRUB_UINT64_T"\n", key_out.offset); -+ else if (path_only) -+ grub_printf("%s\n", p); -+ else -+ grub_printf("ID %"PRIuGRUB_UINT64_T" path %s\n", key_out.offset, p); -+ } else { -+ char *old = output; -+ if (num_only) -+ output = grub_xasprintf("%s%"PRIuGRUB_UINT64_T"\n", -+ old ?: "", key_out.offset); -+ else if (path_only) -+ output = grub_xasprintf("%s%s\n", old ?: "", p); -+ else -+ output = grub_xasprintf("%sID %"PRIuGRUB_UINT64_T" path %s\n", -+ old ?: "", key_out.offset, p); -+ -+ if (old) -+ grub_free(old); -+ } -+ -+ r = next(data, &desc, &elemaddr, &elemsize, &key_out); -+ } while(r > 0); -+ -+ if (output) -+ grub_env_set(varname, output); -+ -+out: -+ free_iterator(&desc); -+ grub_btrfs_unmount(data); -+ -+ grub_device_close (dev); -+ -+ return 0; -+} -+ - static struct grub_fs grub_btrfs_fs = { - .name = "btrfs", - .fs_dir = grub_btrfs_dir, -@@ -2205,12 +2641,88 @@ static struct grub_fs grub_btrfs_fs = { - #endif - }; - -+static grub_command_t cmd_info; -+static grub_extcmd_t cmd_list_subvols; -+ -+static char * -+subvolid_set_env (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val) -+{ -+ unsigned long long result = 0; -+ -+ grub_errno = GRUB_ERR_NONE; -+ if (*val) -+ { -+ result = grub_strtoull(val, NULL, 10); -+ if (grub_errno) -+ return NULL; -+ } -+ -+ grub_free (btrfs_default_subvol); -+ btrfs_default_subvol = NULL; -+ btrfs_default_subvolid = result; -+ return grub_strdup(val); -+} -+ -+static const char * -+subvolid_get_env (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val __attribute__ ((unused))) -+{ -+ if (btrfs_default_subvol) -+ return grub_xasprintf("subvol:%s", btrfs_default_subvol); -+ else if (btrfs_default_subvolid) -+ return grub_xasprintf("%"PRIuGRUB_UINT64_T, btrfs_default_subvolid); -+ else -+ return ""; -+} -+ -+static char * -+subvol_set_env (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val) -+{ -+ grub_free (btrfs_default_subvol); -+ btrfs_default_subvol = grub_strdup (val); -+ btrfs_default_subvolid = 0; -+ return grub_strdup(val); -+} -+ -+static const char * -+subvol_get_env (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val __attribute__ ((unused))) -+{ -+ if (btrfs_default_subvol) -+ return btrfs_default_subvol; -+ else if (btrfs_default_subvolid) -+ return grub_xasprintf("subvolid:%" PRIuGRUB_UINT64_T, -+ btrfs_default_subvolid); -+ else -+ return ""; -+} -+ - GRUB_MOD_INIT (btrfs) - { - grub_fs_register (&grub_btrfs_fs); -+ cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info, -+ "DEVICE", -+ "Print BtrFS info about DEVICE."); -+ cmd_list_subvols = grub_register_extcmd("btrfs-list-subvols", -+ grub_cmd_btrfs_list_subvols, 0, -+ "[-p|-n] [-o var] DEVICE", -+ "Print list of BtrFS subvolumes on " -+ "DEVICE.", options); -+ grub_register_variable_hook ("btrfs_subvol", subvol_get_env, -+ subvol_set_env); -+ grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env, -+ subvolid_set_env); - } - - GRUB_MOD_FINI (btrfs) - { -+ grub_register_variable_hook ("btrfs_subvol", NULL, NULL); -+ grub_register_variable_hook ("btrfs_subvolid", NULL, NULL); -+ grub_unregister_command (cmd_info); -+ grub_unregister_extcmd (cmd_list_subvols); - grub_fs_unregister (&grub_btrfs_fs); - } -+ -+// vim: si et sw=2: -diff --git a/include/grub/btrfs.h b/include/grub/btrfs.h -index 9d93fb6c182..234ad976771 100644 ---- a/include/grub/btrfs.h -+++ b/include/grub/btrfs.h -@@ -29,6 +29,7 @@ enum - GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM = 0x84, - GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF = 0x90, - GRUB_BTRFS_ITEM_TYPE_DEVICE = 0xd8, -+ GRUB_BTRFS_ITEM_TYPE_ROOT_REF = 0x9c, - GRUB_BTRFS_ITEM_TYPE_CHUNK = 0xe4 - }; - diff --git a/0045-export-btrfs_subvol-and-btrfs_subvolid.patch b/0045-export-btrfs_subvol-and-btrfs_subvolid.patch deleted file mode 100644 index d38a6b8..0000000 --- a/0045-export-btrfs_subvol-and-btrfs_subvolid.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Wed, 18 Dec 2013 09:57:04 +0000 -Subject: [PATCH] export btrfs_subvol and btrfs_subvolid - -We should export btrfs_subvol and btrfs_subvolid to have both visible -to subsidiary configuration files loaded using configfile. - -Signed-off-by: Michael Chang ---- - grub-core/fs/btrfs.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index f1fff7385b5..ad1b56b716d 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -2714,6 +2714,8 @@ GRUB_MOD_INIT (btrfs) - subvol_set_env); - grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env, - subvolid_set_env); -+ grub_env_export ("btrfs_subvol"); -+ grub_env_export ("btrfs_subvolid"); - } - - GRUB_MOD_FINI (btrfs) diff --git a/0046-grub2-btrfs-03-follow_default.patch b/0046-grub2-btrfs-03-follow_default.patch deleted file mode 100644 index ca203f4..0000000 --- a/0046-grub2-btrfs-03-follow_default.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 21 Aug 2014 03:39:11 +0000 -Subject: [PATCH] grub2-btrfs-03-follow_default - -Signed-off-by: Michael Chang -Signed-off-by: Robbie Harwood ---- - grub-core/fs/btrfs.c | 107 ++++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 76 insertions(+), 31 deletions(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index ad1b56b716d..113c1f746c9 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -1256,6 +1256,7 @@ grub_btrfs_mount (grub_device_t dev) - { - struct grub_btrfs_data *data; - grub_err_t err; -+ const char *relpath = grub_env_get ("btrfs_relative_path"); - - if (!dev->disk) - { -@@ -1286,11 +1287,14 @@ grub_btrfs_mount (grub_device_t dev) - data->devices_attached[0].dev = dev; - data->devices_attached[0].id = data->sblock.this_device.device_id; - -- err = btrfs_handle_subvol (data); -- if (err) -+ if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) - { -- grub_free (data); -- return NULL; -+ err = btrfs_handle_subvol (data); -+ if (err) -+ { -+ grub_free (data); -+ return NULL; -+ } - } - - return data; -@@ -1855,24 +1859,39 @@ find_path (struct grub_btrfs_data *data, - grub_size_t allocated = 0; - struct grub_btrfs_dir_item *direl = NULL; - struct grub_btrfs_key key_out; -+ int follow_default; - const char *ctoken; - grub_size_t ctokenlen; - char *path_alloc = NULL; - char *origpath = NULL; - unsigned symlinks_max = 32; -+ const char *relpath = grub_env_get ("btrfs_relative_path"); - -+ follow_default = 0; - origpath = grub_strdup (path); - if (!origpath) - return grub_errno; - -- if (data->fs_tree) -+ if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) - { -- *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; -- *tree = data->fs_tree; -- /* This is a tree root, so everything starts at objectid 256 */ -- key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); -- key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -- key->offset = 0; -+ if (data->fs_tree) -+ { -+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; -+ *tree = data->fs_tree; -+ /* This is a tree root, so everything starts at objectid 256 */ -+ key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); -+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -+ key->offset = 0; -+ } -+ else -+ { -+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; -+ *tree = data->sblock.root_tree; -+ key->object_id = data->sblock.root_dir_objectid; -+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -+ key->offset = 0; -+ follow_default = 1; -+ } - } - else - { -@@ -1883,15 +1902,23 @@ find_path (struct grub_btrfs_data *data, - - while (1) - { -- while (path[0] == '/') -- path++; -- if (!path[0]) -- break; -- slash = grub_strchr (path, '/'); -- if (!slash) -- slash = path + grub_strlen (path); -- ctoken = path; -- ctokenlen = slash - path; -+ if (!follow_default) -+ { -+ while (path[0] == '/') -+ path++; -+ if (!path[0]) -+ break; -+ slash = grub_strchr (path, '/'); -+ if (!slash) -+ slash = path + grub_strlen (path); -+ ctoken = path; -+ ctokenlen = slash - path; -+ } -+ else -+ { -+ ctoken = "default"; -+ ctokenlen = sizeof ("default") - 1; -+ } - - if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) - { -@@ -1902,7 +1929,9 @@ find_path (struct grub_btrfs_data *data, - - if (ctokenlen == 1 && ctoken[0] == '.') - { -- path = slash; -+ if (!follow_default) -+ path = slash; -+ follow_default = 0; - continue; - } - if (ctokenlen == 2 && ctoken[0] == '.' && ctoken[1] == '.') -@@ -1933,8 +1962,9 @@ find_path (struct grub_btrfs_data *data, - *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; - key->object_id = key_out.offset; - -- path = slash; -- -+ if (!follow_default) -+ path = slash; -+ follow_default = 0; - continue; - } - -@@ -2003,7 +2033,9 @@ find_path (struct grub_btrfs_data *data, - return err; - } - -- path = slash; -+ if (!follow_default) -+ path = slash; -+ follow_default = 0; - if (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) - { - struct grub_btrfs_inode inode; -@@ -2053,14 +2085,26 @@ find_path (struct grub_btrfs_data *data, - path = path_alloc = tmp; - if (path[0] == '/') - { -- if (data->fs_tree) -+ if (relpath && (relpath[0] == '1' || relpath[0] == 'y')) - { -- *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; -- *tree = data->fs_tree; -- /* This is a tree root, so everything starts at objectid 256 */ -- key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); -- key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -- key->offset = 0; -+ if (data->fs_tree) -+ { -+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; -+ *tree = data->fs_tree; -+ /* This is a tree root, so everything starts at objectid 256 */ -+ key->object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK); -+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -+ key->offset = 0; -+ } -+ else -+ { -+ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; -+ *tree = data->sblock.root_tree; -+ key->object_id = data->sblock.root_dir_objectid; -+ key->type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -+ key->offset = 0; -+ follow_default = 1; -+ } - } - else - { -@@ -2716,6 +2760,7 @@ GRUB_MOD_INIT (btrfs) - subvolid_set_env); - grub_env_export ("btrfs_subvol"); - grub_env_export ("btrfs_subvolid"); -+ grub_env_export ("btrfs_relative_path"); - } - - GRUB_MOD_FINI (btrfs) diff --git a/0047-grub2-btrfs-04-grub2-install.patch b/0047-grub2-btrfs-04-grub2-install.patch deleted file mode 100644 index 451f61d..0000000 --- a/0047-grub2-btrfs-04-grub2-install.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 21 Aug 2014 03:39:11 +0000 -Subject: [PATCH] grub2-btrfs-04-grub2-install - -Signed-off-by: Michael Chang -Signed-off-by: Robbie Harwood ---- - grub-core/osdep/linux/getroot.c | 7 +++++++ - grub-core/osdep/unix/config.c | 17 +++++++++++++++-- - util/config.c | 10 ++++++++++ - util/grub-install.c | 15 +++++++++++++++ - util/grub-mkrelpath.c | 6 ++++++ - include/grub/emu/config.h | 1 + - 6 files changed, 54 insertions(+), 2 deletions(-) - -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index 001b818fe58..caf9b1ccd3f 100644 ---- a/grub-core/osdep/linux/getroot.c -+++ b/grub-core/osdep/linux/getroot.c -@@ -376,6 +376,7 @@ get_btrfs_fs_prefix (const char *mount_path) - return NULL; - } - -+int use_relative_path_on_btrfs = 0; - - char ** - grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) -@@ -519,6 +520,12 @@ again: - { - ret = grub_find_root_devices_from_btrfs (dir); - fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); -+ if (use_relative_path_on_btrfs) -+ { -+ if (fs_prefix) -+ free (fs_prefix); -+ fs_prefix = xstrdup ("/"); -+ } - } - else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0) - { -diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c -index 7d6325138ce..46a881530c0 100644 ---- a/grub-core/osdep/unix/config.c -+++ b/grub-core/osdep/unix/config.c -@@ -82,6 +82,19 @@ grub_util_load_config (struct grub_util_config *cfg) - if (v) - cfg->grub_distributor = xstrdup (v); - -+ v = getenv ("SUSE_BTRFS_SNAPSHOT_BOOTING"); -+ if (v) -+ { -+ if (grub_strncmp(v, "true", sizeof ("true") - 1) == 0) -+ { -+ cfg->is_suse_btrfs_snapshot_enabled = 1; -+ } -+ else -+ { -+ cfg->is_suse_btrfs_snapshot_enabled = 0; -+ } -+ } -+ - cfgfile = grub_util_get_config_filename (); - if (!grub_util_is_regular (cfgfile)) - return; -@@ -105,8 +118,8 @@ grub_util_load_config (struct grub_util_config *cfg) - *ptr++ = *iptr; - } - -- strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" " -- "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\""); -+ strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\nSUSE_BTRFS_SNAPSHOT_BOOTING=%s\\n\" " -+ "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\" \"$SUSE_BTRFS_SNAPSHOT_BOOTING\""); - - argv[2] = script; - argv[3] = '\0'; -diff --git a/util/config.c b/util/config.c -index ebcdd8f5e22..f044a880a76 100644 ---- a/util/config.c -+++ b/util/config.c -@@ -42,6 +42,16 @@ grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple) - cfg->is_cryptodisk_enabled = 1; - continue; - } -+ if (grub_strncmp (ptr, "SUSE_BTRFS_SNAPSHOT_BOOTING=", -+ sizeof ("SUSE_BTRFS_SNAPSHOT_BOOTING=") - 1) == 0) -+ { -+ ptr += sizeof ("SUSE_BTRFS_SNAPSHOT_BOOTING=") - 1; -+ if (*ptr == '"' || *ptr == '\'') -+ ptr++; -+ if (grub_strncmp(ptr, "true", sizeof ("true") - 1) == 0) -+ cfg->is_suse_btrfs_snapshot_enabled = 1; -+ continue; -+ } - if (grub_strncmp (ptr, "GRUB_DISTRIBUTOR=", - sizeof ("GRUB_DISTRIBUTOR=") - 1) == 0) - { -diff --git a/util/grub-install.c b/util/grub-install.c -index 0fbe7f78c6d..0f66f36d23a 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -827,6 +827,8 @@ fill_core_services (const char *core_services) - free (sysv_plist); - } - -+extern int use_relative_path_on_btrfs; -+ - int - main (int argc, char *argv[]) - { -@@ -860,6 +862,9 @@ main (int argc, char *argv[]) - - grub_util_load_config (&config); - -+ if (config.is_suse_btrfs_snapshot_enabled) -+ use_relative_path_on_btrfs = 1; -+ - if (!bootloader_id && config.grub_distributor) - { - char *ptr; -@@ -1352,6 +1357,16 @@ main (int argc, char *argv[]) - fprintf (load_cfg_f, "set debug='%s'\n", - debug_image); - } -+ -+ if (config.is_suse_btrfs_snapshot_enabled -+ && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0) -+ { -+ if (!load_cfg_f) -+ load_cfg_f = grub_util_fopen (load_cfg, "wb"); -+ have_load_cfg = 1; -+ fprintf (load_cfg_f, "set btrfs_relative_path='y'\n"); -+ } -+ - char *prefix_drive = NULL; - char *install_drive = NULL; - -diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c -index 47a241a391b..5db7a9a7d97 100644 ---- a/util/grub-mkrelpath.c -+++ b/util/grub-mkrelpath.c -@@ -40,9 +40,12 @@ struct arguments - }; - - static struct argp_option options[] = { -+ {"relative", 'r', 0, 0, "use relative path on btrfs", 0}, - { 0, 0, 0, 0, 0, 0 } - }; - -+extern int use_relative_path_on_btrfs; -+ - static error_t - argp_parser (int key, char *arg, struct argp_state *state) - { -@@ -52,6 +55,9 @@ argp_parser (int key, char *arg, struct argp_state *state) - - switch (key) - { -+ case 'r': -+ use_relative_path_on_btrfs = 1; -+ break; - case ARGP_KEY_ARG: - if (state->arg_num == 0) - arguments->pathname = xstrdup (arg); -diff --git a/include/grub/emu/config.h b/include/grub/emu/config.h -index 875d5896ce1..c9a7e5f4ade 100644 ---- a/include/grub/emu/config.h -+++ b/include/grub/emu/config.h -@@ -37,6 +37,7 @@ struct grub_util_config - { - int is_cryptodisk_enabled; - char *grub_distributor; -+ int is_suse_btrfs_snapshot_enabled; - }; - - void diff --git a/0048-grub2-btrfs-05-grub2-mkconfig.patch b/0048-grub2-btrfs-05-grub2-mkconfig.patch deleted file mode 100644 index 5afd183..0000000 --- a/0048-grub2-btrfs-05-grub2-mkconfig.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 21 Aug 2014 03:39:11 +0000 -Subject: [PATCH] grub2-btrfs-05-grub2-mkconfig - -Signed-off-by: Michael Chang ---- - util/grub-mkconfig.in | 3 ++- - util/grub-mkconfig_lib.in | 4 ++++ - util/grub.d/00_header.in | 25 ++++++++++++++++++++++++- - util/grub.d/10_linux.in | 4 ++++ - util/grub.d/20_linux_xen.in | 4 ++++ - 5 files changed, 38 insertions(+), 2 deletions(-) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index 005f093809b..535c0f02499 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -252,7 +252,8 @@ export GRUB_DEFAULT \ - GRUB_BADRAM \ - GRUB_OS_PROBER_SKIP_LIST \ - GRUB_DISABLE_SUBMENU \ -- GRUB_DEFAULT_DTB -+ GRUB_DEFAULT_DTB \ -+ SUSE_BTRFS_SNAPSHOT_BOOTING - - if test "x${grub_cfg}" != "x"; then - rm -f "${grub_cfg}.new" -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index 42c2ea9ba50..fafeac95061 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -52,7 +52,11 @@ grub_warn () - - make_system_path_relative_to_its_root () - { -+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] ; then -+ "${grub_mkrelpath}" -r "$1" -+ else - "${grub_mkrelpath}" "$1" -+ fi - } - - is_path_readable_by_grub () -diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in -index 858b526c925..de727e6ee6b 100644 ---- a/util/grub.d/00_header.in -+++ b/util/grub.d/00_header.in -@@ -27,6 +27,14 @@ export TEXTDOMAINDIR="@localedir@" - - . "$pkgdatadir/grub-mkconfig_lib" - -+if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] && -+ [ "x${GRUB_FS}" = "xbtrfs" ] ; then -+ cat </dev/null || true` -diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in -index ada20775a14..e9e73b815fb 100644 ---- a/util/grub.d/20_linux_xen.in -+++ b/util/grub.d/20_linux_xen.in -@@ -73,10 +73,14 @@ fi - - case x"$GRUB_FS" in - xbtrfs) -+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ]; then -+ GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} \${extra_cmdline}" -+ else - rootsubvol="`make_system_path_relative_to_its_root /`" - rootsubvol="${rootsubvol#/}" - if [ "x${rootsubvol}" != x ]; then - GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" -+ fi - fi;; - xzfs) - rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true` diff --git a/0049-grub2-btrfs-06-subvol-mount.patch b/0049-grub2-btrfs-06-subvol-mount.patch deleted file mode 100644 index 14117ab..0000000 --- a/0049-grub2-btrfs-06-subvol-mount.patch +++ /dev/null @@ -1,539 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Tue, 9 Jul 2019 13:56:16 +0200 -Subject: [PATCH] grub2-btrfs-06-subvol-mount - -Signed-off-by: Michael Chang -Signed-off-by: Robbie Harwood ---- - grub-core/fs/btrfs.c | 195 +++++++++++++++++++++++++++++++++++++++- - grub-core/osdep/linux/getroot.c | 148 +++++++++++++++++++++++++++++- - util/grub-install.c | 49 ++++++++++ - include/grub/emu/getroot.h | 5 ++ - 4 files changed, 392 insertions(+), 5 deletions(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 113c1f746c9..d323746ecfa 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -266,6 +267,12 @@ static grub_err_t - grub_btrfs_read_logical (struct grub_btrfs_data *data, - grub_disk_addr_t addr, void *buf, grub_size_t size, - int recursion_depth); -+static grub_err_t -+get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key, -+ grub_uint64_t *tree, grub_uint8_t *type); -+ -+grub_uint64_t -+find_mtab_subvol_tree (const char *path, char **path_in_subvol); - - static grub_err_t - read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb) -@@ -1223,9 +1230,26 @@ lookup_root_by_name(struct grub_btrfs_data *data, const char *path) - grub_err_t err; - grub_uint64_t tree = 0; - grub_uint8_t type; -+ grub_uint64_t saved_tree; - struct grub_btrfs_key key; - -+ if (path[0] == '\0') -+ { -+ data->fs_tree = 0; -+ return GRUB_ERR_NONE; -+ } -+ -+ err = get_root (data, &key, &tree, &type); -+ if (err) -+ return err; -+ -+ saved_tree = data->fs_tree; -+ data->fs_tree = tree; -+ - err = find_path (data, path, &key, &tree, &type); -+ -+ data->fs_tree = saved_tree; -+ - if (err) - return grub_error(GRUB_ERR_FILE_NOT_FOUND, "couldn't locate %s\n", path); - -@@ -2199,11 +2223,20 @@ grub_btrfs_dir (grub_device_t device, const char *path, - int r = 0; - grub_uint64_t tree; - grub_uint8_t type; -+ char *new_path = NULL; - - if (!data) - return grub_errno; - -- err = find_path (data, path, &key_in, &tree, &type); -+ tree = find_mtab_subvol_tree (path, &new_path); -+ -+ if (tree) -+ data->fs_tree = tree; -+ -+ err = find_path (data, new_path ? new_path : path, &key_in, &tree, &type); -+ if (new_path) -+ grub_free (new_path); -+ - if (err) - { - grub_btrfs_unmount (data); -@@ -2305,11 +2338,21 @@ grub_btrfs_open (struct grub_file *file, const char *name) - struct grub_btrfs_inode inode; - grub_uint8_t type; - struct grub_btrfs_key key_in; -+ grub_uint64_t tree; -+ char *new_path = NULL; - - if (!data) - return grub_errno; - -- err = find_path (data, name, &key_in, &data->tree, &type); -+ tree = find_mtab_subvol_tree (name, &new_path); -+ -+ if (tree) -+ data->fs_tree = tree; -+ -+ err = find_path (data, new_path ? new_path : name, &key_in, &data->tree, &type); -+ if (new_path) -+ grub_free (new_path); -+ - if (err) - { - grub_btrfs_unmount (data); -@@ -2480,6 +2523,150 @@ grub_cmd_btrfs_info (grub_command_t cmd __attribute__ ((unused)), int argc, - return 0; - } - -+struct grub_btrfs_mtab -+{ -+ struct grub_btrfs_mtab *next; -+ struct grub_btrfs_mtab **prev; -+ char *path; -+ char *subvol; -+ grub_uint64_t tree; -+}; -+ -+typedef struct grub_btrfs_mtab* grub_btrfs_mtab_t; -+ -+static struct grub_btrfs_mtab *btrfs_mtab; -+ -+#define FOR_GRUB_MTAB(var) FOR_LIST_ELEMENTS (var, btrfs_mtab) -+#define FOR_GRUB_MTAB_SAFE(var, next) FOR_LIST_ELEMENTS_SAFE((var), (next), btrfs_mtab) -+ -+static void -+add_mountpoint (const char *path, const char *subvol, grub_uint64_t tree) -+{ -+ grub_btrfs_mtab_t m = grub_malloc (sizeof (*m)); -+ -+ m->path = grub_strdup (path); -+ m->subvol = grub_strdup (subvol); -+ m->tree = tree; -+ grub_list_push (GRUB_AS_LIST_P (&btrfs_mtab), GRUB_AS_LIST (m)); -+} -+ -+static grub_err_t -+grub_cmd_btrfs_mount_subvol (grub_command_t cmd __attribute__ ((unused)), int argc, -+ char **argv) -+{ -+ char *devname, *dirname, *subvol; -+ struct grub_btrfs_key key_in; -+ grub_uint8_t type; -+ grub_uint64_t tree; -+ grub_uint64_t saved_tree; -+ grub_err_t err; -+ struct grub_btrfs_data *data = NULL; -+ grub_device_t dev = NULL; -+ -+ if (argc < 3) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "required and "); -+ -+ devname = grub_file_get_device_name(argv[0]); -+ dev = grub_device_open (devname); -+ grub_free (devname); -+ -+ if (!dev) -+ { -+ err = grub_errno; -+ goto err_out; -+ } -+ -+ dirname = argv[1]; -+ subvol = argv[2]; -+ -+ data = grub_btrfs_mount (dev); -+ if (!data) -+ { -+ err = grub_errno; -+ goto err_out; -+ } -+ -+ err = find_path (data, dirname, &key_in, &tree, &type); -+ if (err) -+ goto err_out; -+ -+ if (type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) -+ { -+ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory")); -+ goto err_out; -+ } -+ -+ err = get_root (data, &key_in, &tree, &type); -+ -+ if (err) -+ goto err_out; -+ -+ saved_tree = data->fs_tree; -+ data->fs_tree = tree; -+ err = find_path (data, subvol, &key_in, &tree, &type); -+ data->fs_tree = saved_tree; -+ -+ if (err) -+ goto err_out; -+ -+ if (key_in.object_id != grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK) || tree == 0) -+ { -+ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "%s: not a subvolume\n", subvol); -+ goto err_out; -+ } -+ -+ grub_btrfs_unmount (data); -+ grub_device_close (dev); -+ add_mountpoint (dirname, subvol, tree); -+ -+ return GRUB_ERR_NONE; -+ -+err_out: -+ -+ if (data) -+ grub_btrfs_unmount (data); -+ -+ if (dev) -+ grub_device_close (dev); -+ -+ return err; -+} -+ -+grub_uint64_t -+find_mtab_subvol_tree (const char *path, char **path_in_subvol) -+{ -+ grub_btrfs_mtab_t m, cm; -+ grub_uint64_t tree; -+ -+ if (!path || !path_in_subvol) -+ return 0; -+ -+ *path_in_subvol = NULL; -+ tree = 0; -+ cm = NULL; -+ -+ FOR_GRUB_MTAB (m) -+ { -+ if (grub_strncmp (path, m->path, grub_strlen (m->path)) == 0) -+ { -+ if (!cm) -+ cm = m; -+ else -+ if (grub_strcmp (m->path, cm->path) > 0) -+ cm = m; -+ } -+ } -+ -+ if (cm) -+ { -+ const char *s = path + grub_strlen (cm->path); -+ *path_in_subvol = (s[0] == '\0') ? grub_strdup ("/") : grub_strdup (s); -+ tree = cm->tree; -+ } -+ -+ return tree; -+} -+ - static grub_err_t - get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree, - grub_uint64_t objectid, grub_uint64_t offset, -@@ -2686,6 +2873,7 @@ static struct grub_fs grub_btrfs_fs = { - }; - - static grub_command_t cmd_info; -+static grub_command_t cmd_mount_subvol; - static grub_extcmd_t cmd_list_subvols; - - static char * -@@ -2749,6 +2937,9 @@ GRUB_MOD_INIT (btrfs) - cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info, - "DEVICE", - "Print BtrFS info about DEVICE."); -+ cmd_mount_subvol = grub_register_command("btrfs-mount-subvol", grub_cmd_btrfs_mount_subvol, -+ "DEVICE DIRECTORY SUBVOL", -+ "Set btrfs DEVICE the DIRECTORY a mountpoint of SUBVOL."); - cmd_list_subvols = grub_register_extcmd("btrfs-list-subvols", - grub_cmd_btrfs_list_subvols, 0, - "[-p|-n] [-o var] DEVICE", -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index caf9b1ccd3f..28790307e00 100644 ---- a/grub-core/osdep/linux/getroot.c -+++ b/grub-core/osdep/linux/getroot.c -@@ -107,6 +107,14 @@ struct btrfs_ioctl_search_key - grub_uint32_t unused[9]; - }; - -+struct btrfs_ioctl_search_header { -+ grub_uint64_t transid; -+ grub_uint64_t objectid; -+ grub_uint64_t offset; -+ grub_uint32_t type; -+ grub_uint32_t len; -+}; -+ - struct btrfs_ioctl_search_args { - struct btrfs_ioctl_search_key key; - grub_uint64_t buf[(4096 - sizeof(struct btrfs_ioctl_search_key)) -@@ -378,6 +386,109 @@ get_btrfs_fs_prefix (const char *mount_path) - - int use_relative_path_on_btrfs = 0; - -+static char * -+get_btrfs_subvol (const char *path) -+{ -+ struct btrfs_ioctl_ino_lookup_args args; -+ grub_uint64_t tree_id; -+ int fd = -1; -+ char *ret = NULL; -+ -+ fd = open (path, O_RDONLY); -+ -+ if (fd < 0) -+ return NULL; -+ -+ memset (&args, 0, sizeof(args)); -+ args.objectid = GRUB_BTRFS_TREE_ROOT_OBJECTID; -+ -+ if (ioctl (fd, BTRFS_IOC_INO_LOOKUP, &args) < 0) -+ goto error; -+ -+ tree_id = args.treeid; -+ -+ while (tree_id != GRUB_BTRFS_ROOT_VOL_OBJECTID) -+ { -+ struct btrfs_ioctl_search_args sargs; -+ struct grub_btrfs_root_backref *br; -+ struct btrfs_ioctl_search_header *search_header; -+ char *old; -+ grub_uint16_t len; -+ grub_uint64_t inode_id; -+ -+ memset (&sargs, 0, sizeof(sargs)); -+ -+ sargs.key.tree_id = 1; -+ sargs.key.min_objectid = tree_id; -+ sargs.key.max_objectid = tree_id; -+ -+ sargs.key.min_offset = 0; -+ sargs.key.max_offset = ~0ULL; -+ sargs.key.min_transid = 0; -+ sargs.key.max_transid = ~0ULL; -+ sargs.key.min_type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF; -+ sargs.key.max_type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF; -+ -+ sargs.key.nr_items = 1; -+ -+ if (ioctl (fd, BTRFS_IOC_TREE_SEARCH, &sargs) < 0) -+ goto error; -+ -+ if (sargs.key.nr_items == 0) -+ goto error; -+ -+ search_header = (struct btrfs_ioctl_search_header *)sargs.buf; -+ br = (struct grub_btrfs_root_backref *) (search_header + 1); -+ -+ len = grub_le_to_cpu16 (br->n); -+ inode_id = grub_le_to_cpu64 (br->inode_id); -+ tree_id = search_header->offset; -+ -+ old = ret; -+ ret = malloc (len + 1); -+ memcpy (ret, br->name, len); -+ ret[len] = '\0'; -+ -+ if (inode_id != GRUB_BTRFS_TREE_ROOT_OBJECTID) -+ { -+ char *s; -+ -+ memset(&args, 0, sizeof(args)); -+ args.treeid = search_header->offset; -+ args.objectid = inode_id; -+ -+ if (ioctl (fd, BTRFS_IOC_INO_LOOKUP, &args) < 0) -+ goto error; -+ -+ s = xasprintf ("%s%s", args.name, ret); -+ free (ret); -+ ret = s; -+ } -+ -+ if (old) -+ { -+ char *s = xasprintf ("%s/%s", ret, old); -+ free (ret); -+ free (old); -+ ret = s; -+ } -+ } -+ -+ close (fd); -+ return ret; -+ -+error: -+ -+ if (fd >= 0) -+ close (fd); -+ if (ret) -+ free (ret); -+ -+ return NULL; -+} -+ -+void (*grub_find_root_btrfs_mount_path_hook)(const char *mount_path); -+ - char ** - grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) - { -@@ -519,12 +630,15 @@ again: - else if (grub_strcmp (entries[i].fstype, "btrfs") == 0) - { - ret = grub_find_root_devices_from_btrfs (dir); -- fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); - if (use_relative_path_on_btrfs) - { -- if (fs_prefix) -- free (fs_prefix); - fs_prefix = xstrdup ("/"); -+ if (grub_find_root_btrfs_mount_path_hook) -+ grub_find_root_btrfs_mount_path_hook (entries[i].enc_path); -+ } -+ else -+ { -+ fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); - } - } - else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0) -@@ -1150,6 +1264,34 @@ grub_util_get_grub_dev_os (const char *os_dev) - return grub_dev; - } - -+ -+char * -+grub_util_get_btrfs_subvol (const char *path, char **mount_path) -+{ -+ char *mp = NULL; -+ -+ if (mount_path) -+ *mount_path = NULL; -+ -+ auto void -+ mount_path_hook (const char *m) -+ { -+ mp = strdup (m); -+ } -+ -+ grub_find_root_btrfs_mount_path_hook = mount_path_hook; -+ grub_free (grub_find_root_devices_from_mountinfo (path, NULL)); -+ grub_find_root_btrfs_mount_path_hook = NULL; -+ -+ if (!mp) -+ return NULL; -+ -+ if (mount_path) -+ *mount_path = mp; -+ -+ return get_btrfs_subvol (mp); -+} -+ - char * - grub_make_system_path_relative_to_its_root_os (const char *path) - { -diff --git a/util/grub-install.c b/util/grub-install.c -index 0f66f36d23a..84ed6e88ecb 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -1569,6 +1569,55 @@ main (int argc, char *argv[]) - prefix_drive = xasprintf ("(%s)", grub_drives[0]); - } - -+#ifdef __linux__ -+ -+ if (config.is_suse_btrfs_snapshot_enabled -+ && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0) -+ { -+ char *subvol = NULL; -+ char *mount_path = NULL; -+ char **rootdir_devices = NULL; -+ char *rootdir_path = grub_util_path_concat (2, "/", rootdir); -+ -+ if (grub_util_is_directory (rootdir_path)) -+ rootdir_devices = grub_guess_root_devices (rootdir_path); -+ -+ free (rootdir_path); -+ -+ if (rootdir_devices && rootdir_devices[0]) -+ if (grub_strcmp (rootdir_devices[0], grub_devices[0]) == 0) -+ subvol = grub_util_get_btrfs_subvol (platdir, &mount_path); -+ -+ if (subvol && mount_path) -+ { -+ char *def_subvol; -+ -+ def_subvol = grub_util_get_btrfs_subvol ("/", NULL); -+ -+ if (def_subvol) -+ { -+ if (!load_cfg_f) -+ load_cfg_f = grub_util_fopen (load_cfg, "wb"); -+ have_load_cfg = 1; -+ -+ if (grub_strcmp (subvol, def_subvol) != 0) -+ fprintf (load_cfg_f, "btrfs-mount-subvol ($root) %s %s\n", mount_path, subvol); -+ free (def_subvol); -+ } -+ } -+ -+ for (curdev = rootdir_devices; *curdev; curdev++) -+ free (*curdev); -+ if (rootdir_devices) -+ free (rootdir_devices); -+ if (subvol) -+ free (subvol); -+ if (mount_path) -+ free (mount_path); -+ } -+ -+#endif -+ - char mkimage_target[200]; - const char *core_name = NULL; - -diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h -index 73fa2d34abb..9c642ae3fe3 100644 ---- a/include/grub/emu/getroot.h -+++ b/include/grub/emu/getroot.h -@@ -53,6 +53,11 @@ char ** - grub_find_root_devices_from_mountinfo (const char *dir, char **relroot); - #endif - -+#ifdef __linux__ -+char * -+grub_util_get_btrfs_subvol (const char *path, char **mount_path); -+#endif -+ - /* Devmapper functions provided by getroot_devmapper.c. */ - void - grub_util_pull_devmapper (const char *os_dev); diff --git a/0050-Fallback-to-old-subvol-name-scheme-to-support-old-sn.patch b/0050-Fallback-to-old-subvol-name-scheme-to-support-old-sn.patch deleted file mode 100644 index b02ab53..0000000 --- a/0050-Fallback-to-old-subvol-name-scheme-to-support-old-sn.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Andrei Borzenkov -Date: Tue, 21 Jun 2016 16:44:17 +0000 -Subject: [PATCH] Fallback to old subvol name scheme to support old snapshot - config - -Ref: bsc#953538 ---- - grub-core/fs/btrfs.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index d323746ecfa..673ded03522 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -1260,11 +1260,41 @@ lookup_root_by_name(struct grub_btrfs_data *data, const char *path) - return GRUB_ERR_NONE; - } - -+static grub_err_t -+lookup_root_by_name_fallback(struct grub_btrfs_data *data, const char *path) -+{ -+ grub_err_t err; -+ grub_uint64_t tree = 0; -+ grub_uint8_t type; -+ struct grub_btrfs_key key; -+ -+ err = find_path (data, path, &key, &tree, &type); -+ if (err) -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, "couldn't locate %s\n", path); -+ -+ if (key.object_id != grub_cpu_to_le64_compile_time (GRUB_BTRFS_OBJECT_ID_CHUNK) || tree == 0) -+ return grub_error(GRUB_ERR_BAD_FILE_TYPE, "%s: not a subvolume\n", path); -+ -+ data->fs_tree = tree; -+ return GRUB_ERR_NONE; -+} -+ - static grub_err_t - btrfs_handle_subvol(struct grub_btrfs_data *data __attribute__ ((unused))) - { - if (btrfs_default_subvol) -- return lookup_root_by_name(data, btrfs_default_subvol); -+ { -+ grub_err_t err; -+ err = lookup_root_by_name(data, btrfs_default_subvol); -+ -+ /* Fallback to old schemes */ -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ { -+ err = GRUB_ERR_NONE; -+ return lookup_root_by_name_fallback(data, btrfs_default_subvol); -+ } -+ return err; -+ } - - if (btrfs_default_subvolid) - return lookup_root_by_id(data, btrfs_default_subvolid); diff --git a/0051-Grub-not-working-correctly-with-btrfs-snapshots-bsc-.patch b/0051-Grub-not-working-correctly-with-btrfs-snapshots-bsc-.patch deleted file mode 100644 index b54b196..0000000 --- a/0051-Grub-not-working-correctly-with-btrfs-snapshots-bsc-.patch +++ /dev/null @@ -1,274 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 11 May 2017 08:56:57 +0000 -Subject: [PATCH] Grub not working correctly with btrfs snapshots (bsc#1026511) - -Signed-off-by: Michael Chang -Signed-off-by: Robbie Harwood ---- - grub-core/fs/btrfs.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 238 insertions(+) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 673ded03522..2b21cbaa67e 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -2887,6 +2887,238 @@ out: - return 0; - } - -+static grub_err_t -+grub_btrfs_get_parent_subvol_path (struct grub_btrfs_data *data, -+ grub_uint64_t child_id, -+ const char *child_path, -+ grub_uint64_t *parent_id, -+ char **path_out) -+{ -+ grub_uint64_t fs_root = 0; -+ struct grub_btrfs_key key_in = { -+ .object_id = child_id, -+ .type = GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF, -+ .offset = 0, -+ }, key_out; -+ struct grub_btrfs_root_ref *ref; -+ char *buf; -+ struct grub_btrfs_leaf_descriptor desc; -+ grub_size_t elemsize; -+ grub_disk_addr_t elemaddr; -+ grub_err_t err; -+ char *parent_path; -+ -+ *parent_id = 0; -+ *path_out = 0; -+ -+ err = lower_bound(data, &key_in, &key_out, data->sblock.root_tree, -+ &elemaddr, &elemsize, &desc, 0); -+ if (err) -+ return err; -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF || elemaddr == 0) -+ next(data, &desc, &elemaddr, &elemsize, &key_out); -+ -+ if (key_out.type != GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF) -+ { -+ free_iterator(&desc); -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("can't find root backrefs")); -+ } -+ -+ buf = grub_malloc(elemsize + 1); -+ if (!buf) -+ { -+ free_iterator(&desc); -+ return grub_errno; -+ } -+ -+ err = grub_btrfs_read_logical(data, elemaddr, buf, elemsize, 0); -+ if (err) -+ { -+ grub_free(buf); -+ free_iterator(&desc); -+ return err; -+ } -+ -+ buf[elemsize] = 0; -+ ref = (struct grub_btrfs_root_ref *)buf; -+ -+ err = get_fs_root(data, data->sblock.root_tree, grub_le_to_cpu64 (key_out.offset), -+ 0, &fs_root); -+ if (err) -+ { -+ grub_free(buf); -+ free_iterator(&desc); -+ return err; -+ } -+ -+ find_pathname(data, grub_le_to_cpu64 (ref->dirid), fs_root, ref->name, &parent_path); -+ -+ if (child_path) -+ { -+ *path_out = grub_xasprintf ("%s/%s", parent_path, child_path); -+ grub_free (parent_path); -+ } -+ else -+ *path_out = parent_path; -+ -+ *parent_id = grub_le_to_cpu64 (key_out.offset); -+ -+ grub_free(buf); -+ free_iterator(&desc); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_btrfs_get_default_subvolume_id (struct grub_btrfs_data *data, grub_uint64_t *id) -+{ -+ grub_err_t err; -+ grub_disk_addr_t elemaddr; -+ grub_size_t elemsize; -+ struct grub_btrfs_key key, key_out; -+ struct grub_btrfs_dir_item *direl = NULL; -+ const char *ctoken = "default"; -+ grub_size_t ctokenlen = sizeof ("default") - 1; -+ -+ *id = 0; -+ key.object_id = data->sblock.root_dir_objectid; -+ key.type = GRUB_BTRFS_ITEM_TYPE_DIR_ITEM; -+ key.offset = grub_cpu_to_le64 (~grub_getcrc32c (1, ctoken, ctokenlen)); -+ err = lower_bound (data, &key, &key_out, data->sblock.root_tree, &elemaddr, &elemsize, -+ NULL, 0); -+ if (err) -+ return err; -+ -+ if (key_cmp (&key, &key_out) != 0) -+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found")); -+ -+ struct grub_btrfs_dir_item *cdirel; -+ direl = grub_malloc (elemsize + 1); -+ err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0); -+ if (err) -+ { -+ grub_free (direl); -+ return err; -+ } -+ for (cdirel = direl; -+ (grub_uint8_t *) cdirel - (grub_uint8_t *) direl -+ < (grub_ssize_t) elemsize; -+ cdirel = (void *) ((grub_uint8_t *) (direl + 1) -+ + grub_le_to_cpu16 (cdirel->n) -+ + grub_le_to_cpu16 (cdirel->m))) -+ { -+ if (ctokenlen == grub_le_to_cpu16 (cdirel->n) -+ && grub_memcmp (cdirel->name, ctoken, ctokenlen) == 0) -+ break; -+ } -+ if ((grub_uint8_t *) cdirel - (grub_uint8_t *) direl -+ >= (grub_ssize_t) elemsize) -+ { -+ grub_free (direl); -+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found")); -+ return err; -+ } -+ -+ if (cdirel->key.type != GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM) -+ { -+ grub_free (direl); -+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found")); -+ return err; -+ } -+ -+ *id = grub_le_to_cpu64 (cdirel->key.object_id); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_btrfs_get_default_subvol (struct grub_extcmd_context *ctxt, -+ int argc, char **argv) -+{ -+ char *devname; -+ grub_device_t dev; -+ struct grub_btrfs_data *data; -+ grub_err_t err; -+ grub_uint64_t id; -+ char *subvol = NULL; -+ grub_uint64_t subvolid = 0; -+ char *varname = NULL; -+ char *output = NULL; -+ int path_only = ctxt->state[1].set; -+ int num_only = ctxt->state[2].set; -+ -+ if (ctxt->state[0].set) -+ varname = ctxt->state[0].arg; -+ -+ if (argc < 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); -+ -+ devname = grub_file_get_device_name(argv[0]); -+ if (!devname) -+ return grub_errno; -+ -+ dev = grub_device_open (devname); -+ grub_free (devname); -+ if (!dev) -+ return grub_errno; -+ -+ data = grub_btrfs_mount(dev); -+ if (!data) -+ { -+ grub_device_close (dev); -+ grub_dprintf ("btrfs", "failed to open fs\n"); -+ grub_errno = GRUB_ERR_NONE; -+ return 0; -+ } -+ -+ err = grub_btrfs_get_default_subvolume_id (data, &subvolid); -+ if (err) -+ { -+ grub_btrfs_unmount (data); -+ grub_device_close (dev); -+ return err; -+ } -+ -+ id = subvolid; -+ while (id != GRUB_BTRFS_ROOT_VOL_OBJECTID) -+ { -+ grub_uint64_t parent_id; -+ char *path_out; -+ -+ err = grub_btrfs_get_parent_subvol_path (data, grub_cpu_to_le64 (id), subvol, &parent_id, &path_out); -+ if (err) -+ { -+ grub_btrfs_unmount (data); -+ grub_device_close (dev); -+ return err; -+ } -+ -+ if (subvol) -+ grub_free (subvol); -+ subvol = path_out; -+ id = parent_id; -+ } -+ -+ if (num_only && path_only) -+ output = grub_xasprintf ("%"PRIuGRUB_UINT64_T" /%s", subvolid, subvol); -+ else if (num_only) -+ output = grub_xasprintf ("%"PRIuGRUB_UINT64_T, subvolid); -+ else -+ output = grub_xasprintf ("/%s", subvol); -+ -+ if (varname) -+ grub_env_set(varname, output); -+ else -+ grub_printf ("%s\n", output); -+ -+ grub_free (output); -+ grub_free (subvol); -+ -+ grub_btrfs_unmount (data); -+ grub_device_close (dev); -+ -+ return GRUB_ERR_NONE; -+} -+ - static struct grub_fs grub_btrfs_fs = { - .name = "btrfs", - .fs_dir = grub_btrfs_dir, -@@ -2905,6 +3137,7 @@ static struct grub_fs grub_btrfs_fs = { - static grub_command_t cmd_info; - static grub_command_t cmd_mount_subvol; - static grub_extcmd_t cmd_list_subvols; -+static grub_extcmd_t cmd_get_default_subvol; - - static char * - subvolid_set_env (struct grub_env_var *var __attribute__ ((unused)), -@@ -2975,6 +3208,11 @@ GRUB_MOD_INIT (btrfs) - "[-p|-n] [-o var] DEVICE", - "Print list of BtrFS subvolumes on " - "DEVICE.", options); -+ cmd_get_default_subvol = grub_register_extcmd("btrfs-get-default-subvol", -+ grub_cmd_btrfs_get_default_subvol, 0, -+ "[-p|-n] [-o var] DEVICE", -+ "Print default BtrFS subvolume on " -+ "DEVICE.", options); - grub_register_variable_hook ("btrfs_subvol", subvol_get_env, - subvol_set_env); - grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env, diff --git a/0052-Add-grub_efi_allocate_pool-and-grub_efi_free_pool-wr.patch b/0052-Add-grub_efi_allocate_pool-and-grub_efi_free_pool-wr.patch deleted file mode 100644 index bde7096..0000000 --- a/0052-Add-grub_efi_allocate_pool-and-grub_efi_free_pool-wr.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 1 Jun 2017 09:59:56 -0400 -Subject: [PATCH] Add grub_efi_allocate_pool() and grub_efi_free_pool() - wrappers. - -Signed-off-by: Peter Jones ---- - include/grub/efi/efi.h | 36 ++++++++++++++++++++++++++++++++---- - 1 file changed, 32 insertions(+), 4 deletions(-) - -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 585fa6662b6..03f9a9d0118 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -24,6 +24,10 @@ - #include - #include - -+/* Variables. */ -+extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); -+extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); -+ - /* Functions. */ - void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol, - void *registration); -@@ -60,6 +64,33 @@ EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size, - grub_efi_uintn_t *descriptor_size, - grub_efi_uint32_t *descriptor_version); - void grub_efi_memory_fini (void); -+ -+static inline grub_efi_status_t -+__attribute__((__unused__)) -+grub_efi_allocate_pool (grub_efi_memory_type_t pool_type, -+ grub_efi_uintn_t buffer_size, -+ void **buffer) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_status_t status; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_3 (b->allocate_pool, pool_type, buffer_size, buffer); -+ return status; -+} -+ -+static inline grub_efi_status_t -+__attribute__((__unused__)) -+grub_efi_free_pool (void *buffer) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_status_t status; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_1 (b->free_pool, buffer); -+ return status; -+} -+ - grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle); - void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); - char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); -@@ -115,10 +146,7 @@ void grub_efi_init (void); - void grub_efi_fini (void); - void grub_efi_set_prefix (void); - --/* Variables. */ --extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); --extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); -- -+/* More variables. */ - extern int EXPORT_VAR(grub_efi_is_finished); - - struct grub_net_card; diff --git a/0053-Use-grub_efi_.-memory-helpers-where-reasonable.patch b/0053-Use-grub_efi_.-memory-helpers-where-reasonable.patch deleted file mode 100644 index ccdf282..0000000 --- a/0053-Use-grub_efi_.-memory-helpers-where-reasonable.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 1 Jun 2017 10:06:38 -0400 -Subject: [PATCH] Use grub_efi_...() memory helpers where reasonable. - -This uses grub_efi_allocate_pool(), grub_efi_free_pool(), and -grub_efi_free_pages() instead of open-coded efi_call_N() calls, so we -get more reasonable type checking. - -Signed-off-by: Peter Jones ---- - grub-core/loader/efi/chainloader.c | 24 +++++++++--------------- - 1 file changed, 9 insertions(+), 15 deletions(-) - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 07c4937898d..89ac84cc663 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -65,7 +65,7 @@ grub_chainloader_unload (void) - - b = grub_efi_system_table->boot_services; - efi_call_1 (b->unload_image, image_handle); -- efi_call_2 (b->free_pages, address, pages); -+ grub_efi_free_pages (address, pages); - - grub_free (file_path); - grub_free (cmdline); -@@ -108,7 +108,7 @@ grub_chainloader_boot (void) - } - - if (exit_data) -- efi_call_1 (b->free_pool, exit_data); -+ grub_efi_free_pool (exit_data); - - grub_loader_unset (); - -@@ -527,10 +527,9 @@ grub_efi_get_media_file_path (grub_efi_device_path_t *dp) - static grub_efi_boolean_t - handle_image (void *data, grub_efi_uint32_t datasize) - { -- grub_efi_boot_services_t *b; - grub_efi_loaded_image_t *li, li_bak; - grub_efi_status_t efi_status; -- char *buffer = NULL; -+ void *buffer = NULL; - char *buffer_aligned = NULL; - grub_efi_uint32_t i; - struct grub_pe32_section_table *section; -@@ -541,8 +540,6 @@ handle_image (void *data, grub_efi_uint32_t datasize) - int found_entry_point = 0; - int rc; - -- b = grub_efi_system_table->boot_services; -- - rc = read_header (data, datasize, &context); - if (rc < 0) - { -@@ -582,8 +579,8 @@ handle_image (void *data, grub_efi_uint32_t datasize) - grub_dprintf ("chain", "image size is %08"PRIxGRUB_UINT64_T", datasize is %08x\n", - context.image_size, datasize); - -- efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, -- buffer_size, &buffer); -+ efi_status = grub_efi_allocate_pool (GRUB_EFI_LOADER_DATA, buffer_size, -+ &buffer); - - if (efi_status != GRUB_EFI_SUCCESS) - { -@@ -815,14 +812,14 @@ handle_image (void *data, grub_efi_uint32_t datasize) - - grub_dprintf ("chain", "entry_point returned %ld\n", efi_status); - grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); -- efi_status = efi_call_1 (b->free_pool, buffer); -+ efi_status = grub_efi_free_pool (buffer); - - return 1; - - error_exit: - grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno); - if (buffer) -- efi_call_1 (b->free_pool, buffer); -+ grub_efi_free_pool (buffer); - - return 0; - } -@@ -830,10 +827,7 @@ error_exit: - static grub_err_t - grub_secureboot_chainloader_unload (void) - { -- grub_efi_boot_services_t *b; -- -- b = grub_efi_system_table->boot_services; -- efi_call_2 (b->free_pages, address, pages); -+ grub_efi_free_pages (address, pages); - grub_free (file_path); - grub_free (cmdline); - cmdline = 0; -@@ -1100,7 +1094,7 @@ fail: - grub_free (file_path); - - if (address) -- efi_call_2 (b->free_pages, address, pages); -+ grub_efi_free_pages (address, pages); - - if (cmdline) - grub_free (cmdline); diff --git a/0054-Add-PRIxGRUB_EFI_STATUS-and-use-it.patch b/0054-Add-PRIxGRUB_EFI_STATUS-and-use-it.patch deleted file mode 100644 index ef41fe1..0000000 --- a/0054-Add-PRIxGRUB_EFI_STATUS-and-use-it.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 1 Jun 2017 10:07:50 -0400 -Subject: [PATCH] Add PRIxGRUB_EFI_STATUS and use it. - -This avoids syntax checkers getting confused about if it's llx or lx. - -Signed-off-by: Peter Jones ---- - grub-core/loader/efi/chainloader.c | 3 ++- - include/grub/efi/api.h | 9 +++++++++ - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 89ac84cc663..ac8dfd40c61 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -810,7 +810,8 @@ handle_image (void *data, grub_efi_uint32_t datasize) - efi_status = efi_call_2 (entry_point, grub_efi_image_handle, - grub_efi_system_table); - -- grub_dprintf ("chain", "entry_point returned %ld\n", efi_status); -+ grub_dprintf ("chain", "entry_point returned 0x%"PRIxGRUB_EFI_STATUS"\n", -+ efi_status); - grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); - efi_status = grub_efi_free_pool (buffer); - -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 117469450d3..99628801478 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -546,7 +546,16 @@ typedef grub_uint64_t grub_efi_uint64_t; - typedef grub_uint8_t grub_efi_char8_t; - typedef grub_uint16_t grub_efi_char16_t; - -+ - typedef grub_efi_uintn_t grub_efi_status_t; -+/* Make grub_efi_status_t reasonably printable. */ -+#if GRUB_CPU_SIZEOF_VOID_P == 8 -+#define PRIxGRUB_EFI_STATUS "lx" -+#define PRIdGRUB_EFI_STATUS "ld" -+#else -+#define PRIxGRUB_EFI_STATUS "llx" -+#define PRIdGRUB_EFI_STATUS "lld" -+#endif - - #define GRUB_EFI_ERROR_CODE(value) \ - ((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) diff --git a/0055-don-t-use-int-for-efi-status.patch b/0055-don-t-use-int-for-efi-status.patch deleted file mode 100644 index 44d3555..0000000 --- a/0055-don-t-use-int-for-efi-status.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 26 Jun 2017 12:44:59 -0400 -Subject: [PATCH] don't use int for efi status - ---- - grub-core/kern/efi/efi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 05d8237a9b2..ae9885edb84 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -167,7 +167,7 @@ grub_reboot (void) - void - grub_exit (int retval) - { -- int rc = GRUB_EFI_LOAD_ERROR; -+ grub_efi_status_t rc = GRUB_EFI_LOAD_ERROR; - - if (retval == 0) - rc = GRUB_EFI_SUCCESS; diff --git a/0056-make-GRUB_MOD_INIT-declare-its-function-prototypes.patch b/0056-make-GRUB_MOD_INIT-declare-its-function-prototypes.patch deleted file mode 100644 index 1014900..0000000 --- a/0056-make-GRUB_MOD_INIT-declare-its-function-prototypes.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 26 Jun 2017 12:46:23 -0400 -Subject: [PATCH] make GRUB_MOD_INIT() declare its function prototypes. - ---- - include/grub/dl.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/include/grub/dl.h b/include/grub/dl.h -index b3753c9ca26..91933b85f2c 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -54,6 +54,7 @@ grub_mod_fini (void) - - #define GRUB_MOD_INIT(name) \ - static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ -+extern void grub_##name##_init (void); \ - void \ - grub_##name##_init (void) { grub_mod_init (0); } \ - static void \ -@@ -61,6 +62,7 @@ grub_mod_init (grub_dl_t mod __attribute__ ((unused))) - - #define GRUB_MOD_FINI(name) \ - static void grub_mod_fini (void) __attribute__ ((used)); \ -+extern void grub_##name##_fini (void); \ - void \ - grub_##name##_fini (void) { grub_mod_fini (); } \ - static void \ diff --git a/0057-Don-t-guess-boot-efi-as-HFS-on-ppc-machines-in-grub-.patch b/0057-Don-t-guess-boot-efi-as-HFS-on-ppc-machines-in-grub-.patch deleted file mode 100644 index 890aa34..0000000 --- a/0057-Don-t-guess-boot-efi-as-HFS-on-ppc-machines-in-grub-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 20 Apr 2017 13:29:06 -0400 -Subject: [PATCH] Don't guess /boot/efi/ as HFS+ on ppc machines in - grub-install - -This should never be trying this, and since we've consolidated the -grubenv to always be on /boot/efi/EFI/fedora/, this code causes it to -always make the wrong decision. - -Resolves: rhbz#1484474 - -Signed-off-by: Peter Jones ---- - util/grub-install.c | 12 +----------- - 1 file changed, 1 insertion(+), 11 deletions(-) - -diff --git a/util/grub-install.c b/util/grub-install.c -index 84ed6e88ecb..a2bec7446cb 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -1190,18 +1190,8 @@ main (int argc, char *argv[]) - char *d; - - is_guess = 1; -- d = grub_util_path_concat (2, bootdir, "macppc"); -- if (!grub_util_is_directory (d)) -- { -- free (d); -- d = grub_util_path_concat (2, bootdir, "efi"); -- } - /* Find the Mac HFS(+) System Partition. */ -- if (!grub_util_is_directory (d)) -- { -- free (d); -- d = grub_util_path_concat (2, bootdir, "EFI"); -- } -+ d = grub_util_path_concat (2, bootdir, "macppc"); - if (!grub_util_is_directory (d)) - { - free (d); diff --git a/0058-20_linux_xen-load-xen-or-multiboot-2-modules-as-need.patch b/0058-20_linux_xen-load-xen-or-multiboot-2-modules-as-need.patch deleted file mode 100644 index 3fd779f..0000000 --- a/0058-20_linux_xen-load-xen-or-multiboot-2-modules-as-need.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 14:31:19 +0200 -Subject: [PATCH] 20_linux_xen: load xen or multiboot{,2} modules as needed. - -Signed-off-by: Peter Jones ---- - util/grub.d/20_linux_xen.in | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in -index e9e73b815fb..c23b064be6c 100644 ---- a/util/grub.d/20_linux_xen.in -+++ b/util/grub.d/20_linux_xen.in -@@ -153,6 +153,7 @@ linux_entry_xsm () - else - xen_rm_opts="no-real-mode edd=off" - fi -+ insmod ${xen_module} - ${xen_loader} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts} - echo '$(echo "$lmessage" | grub_quote)' - ${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} -@@ -166,6 +167,7 @@ EOF - done - sed "s/^/$submenu_indentation/" << EOF - echo '$(echo "$message" | grub_quote)' -+ insmod ${xen_module} - ${module_loader} --nounzip $(echo $initrd_path) - EOF - fi -@@ -253,13 +255,16 @@ while [ "x${xen_list}" != "x" ] ; do - echo " submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {" - fi - if ($grub_file --is-arm64-efi $current_xen); then -+ xen_module="xen_boot" - xen_loader="xen_hypervisor" - module_loader="xen_module" - else - if ($grub_file --is-x86-multiboot2 $current_xen); then -+ xen_module="multiboot2" - xen_loader="multiboot2" - module_loader="module2" - else -+ xen_module="multiboot" - xen_loader="multiboot" - module_loader="module" - fi diff --git a/0059-Make-pmtimer-tsc-calibration-not-take-51-seconds-to-.patch b/0059-Make-pmtimer-tsc-calibration-not-take-51-seconds-to-.patch deleted file mode 100644 index acfb116..0000000 --- a/0059-Make-pmtimer-tsc-calibration-not-take-51-seconds-to-.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 7 Nov 2017 17:12:17 -0500 -Subject: [PATCH] Make pmtimer tsc calibration not take 51 seconds to fail. - -On my laptop running at 2.4GHz, if I run a VM where tsc calibration -using pmtimer will fail presuming a broken pmtimer, it takes ~51 seconds -to do so (as measured with the stopwatch on my phone), with a tsc delta -of 0x1cd1c85300, or around 125 billion cycles. - -If instead of trying to wait for 5-200ms to show up on the pmtimer, we try -to wait for 5-200us, it decides it's broken in ~0x2626aa0 TSCs, aka ~2.4 -million cycles, or more or less instantly. - -Additionally, this reading the pmtimer was returning 0xffffffff anyway, -and that's obviously an invalid return. I've added a check for that and -0 so we don't bother waiting for the test if what we're seeing is dead -pins with no response at all. - -If "debug" is includes "pmtimer", you will see one of the following -three outcomes. If pmtimer gives all 0 or all 1 bits, you will see: - -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 1 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 2 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 3 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 4 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 5 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 6 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 7 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 8 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 9 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 10 -kern/i386/tsc_pmtimer.c:78: timer is broken; giving up. - -This outcome was tested using qemu+kvm with UEFI (OVMF) firmware and -these options: -machine pc-q35-2.10 -cpu Broadwell-noTSX - -If pmtimer gives any other bit patterns but is not actually marching -forward fast enough to use for clock calibration, you will see: - -kern/i386/tsc_pmtimer.c:121: pmtimer delta is 0x0 (1904 iterations) -kern/i386/tsc_pmtimer.c:124: tsc delta is implausible: 0x2626aa0 - -This outcome was tested using grub compiled with GRUB_PMTIMER_IGNORE_BAD_READS -defined (so as not to trip the bad read test) using qemu+kvm with UEFI -(OVMF) firmware, and these options: -machine pc-q35-2.10 -cpu Broadwell-noTSX - -If pmtimer actually works, you'll see something like: - -kern/i386/tsc_pmtimer.c:121: pmtimer delta is 0x0 (1904 iterations) -kern/i386/tsc_pmtimer.c:124: tsc delta is implausible: 0x2626aa0 - -This outcome was tested using qemu+kvm with UEFI (OVMF) firmware, and -these options: -machine pc-i440fx-2.4 -cpu Broadwell-noTSX - -I've also tested this outcome on a real Intel Xeon E3-1275v3 on an Intel -Server Board S1200V3RPS using the SDV.RP.B8 "Release" build here: -https://firmware.intel.com/sites/default/files/UEFIDevKit_S1200RP_vB8.zip - -Signed-off-by: Peter Jones ---- - grub-core/kern/i386/tsc_pmtimer.c | 109 +++++++++++++++++++++++++++++++------- - 1 file changed, 89 insertions(+), 20 deletions(-) - -diff --git a/grub-core/kern/i386/tsc_pmtimer.c b/grub-core/kern/i386/tsc_pmtimer.c -index c9c36169978..ca15c3aacd7 100644 ---- a/grub-core/kern/i386/tsc_pmtimer.c -+++ b/grub-core/kern/i386/tsc_pmtimer.c -@@ -28,40 +28,101 @@ - #include - #include - -+/* -+ * Define GRUB_PMTIMER_IGNORE_BAD_READS if you're trying to test a timer that's -+ * present but doesn't keep time well. -+ */ -+// #define GRUB_PMTIMER_IGNORE_BAD_READS -+ - grub_uint64_t - grub_pmtimer_wait_count_tsc (grub_port_t pmtimer, - grub_uint16_t num_pm_ticks) - { - grub_uint32_t start; -- grub_uint32_t last; -- grub_uint32_t cur, end; -+ grub_uint64_t cur, end; - grub_uint64_t start_tsc; - grub_uint64_t end_tsc; -- int num_iter = 0; -+ unsigned int num_iter = 0; -+#ifndef GRUB_PMTIMER_IGNORE_BAD_READS -+ int bad_reads = 0; -+#endif - -- start = grub_inl (pmtimer) & 0xffffff; -- last = start; -+ /* -+ * Some timers are 24-bit and some are 32-bit, but it doesn't make much -+ * difference to us. Caring which one we have isn't really worth it since -+ * the low-order digits will give us enough data to calibrate TSC. So just -+ * mask the top-order byte off. -+ */ -+ cur = start = grub_inl (pmtimer) & 0xffffffUL; - end = start + num_pm_ticks; - start_tsc = grub_get_tsc (); - while (1) - { -- cur = grub_inl (pmtimer) & 0xffffff; -- if (cur < last) -- cur |= 0x1000000; -- num_iter++; -+ cur &= 0xffffffffff000000ULL; -+ cur |= grub_inl (pmtimer) & 0xffffffUL; -+ -+ end_tsc = grub_get_tsc(); -+ -+#ifndef GRUB_PMTIMER_IGNORE_BAD_READS -+ /* -+ * If we get 10 reads in a row that are obviously dead pins, there's no -+ * reason to do this thousands of times. -+ */ -+ if (cur == 0xffffffUL || cur == 0) -+ { -+ bad_reads++; -+ grub_dprintf ("pmtimer", -+ "pmtimer: 0x%"PRIxGRUB_UINT64_T" bad_reads: %d\n", -+ cur, bad_reads); -+ grub_dprintf ("pmtimer", "timer is broken; giving up.\n"); -+ -+ if (bad_reads == 10) -+ return 0; -+ } -+#endif -+ -+ if (cur < start) -+ cur += 0x1000000; -+ - if (cur >= end) - { -- end_tsc = grub_get_tsc (); -+ grub_dprintf ("pmtimer", "pmtimer delta is 0x%"PRIxGRUB_UINT64_T"\n", -+ cur - start); -+ grub_dprintf ("pmtimer", "tsc delta is 0x%"PRIxGRUB_UINT64_T"\n", -+ end_tsc - start_tsc); - return end_tsc - start_tsc; - } -- /* Check for broken PM timer. -- 50000000 TSCs is between 5 ms (10GHz) and 200 ms (250 MHz) -- if after this time we still don't have 1 ms on pmtimer, then -- pmtimer is broken. -+ -+ /* -+ * Check for broken PM timer. 1ms at 10GHz should be 1E+7 TSCs; at -+ * 250MHz it should be 2.5E6. So if after 4E+7 TSCs on a 10GHz machine, -+ * we should have seen pmtimer show 4ms of change (i.e. cur =~ -+ * start+14320); on a 250MHz machine that should be 16ms (start+57280). -+ * If after this a time we still don't have 1ms on pmtimer, then pmtimer -+ * is broken. -+ * -+ * Likewise, if our code is perfectly efficient and introduces no delays -+ * whatsoever, on a 10GHz system we should see a TSC delta of 3580 in -+ * ~3580 iterations. On a 250MHz machine that should be ~900 iterations. -+ * -+ * With those factors in mind, there are two limits here. There's a hard -+ * limit here at 8x our desired pm timer delta, picked as an arbitrarily -+ * large value that's still not a lot of time to humans, because if we -+ * get that far this is either an implausibly fast machine or the pmtimer -+ * is not running. And there's another limit on 4x our 10GHz tsc delta -+ * without seeing cur converge on our target value. - */ -- if ((num_iter & 0xffffff) == 0 && grub_get_tsc () - start_tsc > 5000000) { -- return 0; -- } -+ if ((++num_iter > (grub_uint32_t)num_pm_ticks << 3UL) || -+ end_tsc - start_tsc > 40000000) -+ { -+ grub_dprintf ("pmtimer", -+ "pmtimer delta is 0x%"PRIxGRUB_UINT64_T" (%u iterations)\n", -+ cur - start, num_iter); -+ grub_dprintf ("pmtimer", -+ "tsc delta is implausible: 0x%"PRIxGRUB_UINT64_T"\n", -+ end_tsc - start_tsc); -+ return 0; -+ } - } - } - -@@ -74,12 +135,20 @@ grub_tsc_calibrate_from_pmtimer (void) - - fadt = grub_acpi_find_fadt (); - if (!fadt) -- return 0; -+ { -+ grub_dprintf ("pmtimer", "No FADT found; not using pmtimer.\n"); -+ return 0; -+ } - pmtimer = fadt->pmtimer; - if (!pmtimer) -- return 0; -+ { -+ grub_dprintf ("pmtimer", "FADT does not specify pmtimer; skipping.\n"); -+ return 0; -+ } - -- /* It's 3.579545 MHz clock. Wait 1 ms. */ -+ /* -+ * It's 3.579545 MHz clock. Wait 1 ms. -+ */ - tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer, 3580); - if (tsc_diff == 0) - return 0; diff --git a/0060-align-struct-efi_variable-better.patch b/0060-align-struct-efi_variable-better.patch deleted file mode 100644 index ec26def..0000000 --- a/0060-align-struct-efi_variable-better.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 27 Feb 2018 13:55:35 -0500 -Subject: [PATCH] align struct efi_variable better... - ---- - include/grub/efiemu/runtime.h | 2 +- - include/grub/types.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h -index 36d2dedf47e..9d93ba88bac 100644 ---- a/include/grub/efiemu/runtime.h -+++ b/include/grub/efiemu/runtime.h -@@ -33,5 +33,5 @@ struct efi_variable - grub_uint32_t namelen; - grub_uint32_t size; - grub_efi_uint32_t attributes; --} GRUB_PACKED; -+} GRUB_PACKED GRUB_ALIGNED(8); - #endif /* ! GRUB_EFI_EMU_RUNTIME_HEADER */ -diff --git a/include/grub/types.h b/include/grub/types.h -index 0a3ff159136..ba446d99040 100644 ---- a/include/grub/types.h -+++ b/include/grub/types.h -@@ -29,6 +29,7 @@ - #else - #define GRUB_PACKED __attribute__ ((packed)) - #endif -+#define GRUB_ALIGNED(x) __attribute__((aligned (x))) - - #ifdef GRUB_BUILD - # define GRUB_CPU_SIZEOF_VOID_P BUILD_SIZEOF_VOID_P diff --git a/0061-Add-BLS-support-to-grub-mkconfig.patch b/0061-Add-BLS-support-to-grub-mkconfig.patch deleted file mode 100644 index f7c8064..0000000 --- a/0061-Add-BLS-support-to-grub-mkconfig.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 9 Dec 2016 15:40:29 -0500 -Subject: [PATCH] Add BLS support to grub-mkconfig - -GRUB now has BootLoaderSpec support, the user can choose to use this by -setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup, -the boot menu entries are not added to the grub.cfg, instead BLS config -files are parsed by blscfg command and the entries created dynamically. - -A 10_linux_bls grub.d snippet to generate menu entries from BLS files -is also added that can be used on platforms where the bootloader doesn't -have BLS support and only can parse a normal grub configuration file. - -Portions of the 10_linux_bls were taken from the ostree-grub-generator -script that's included in the OSTree project. - -Fixes to support multi-devices and generate a BLS section even if no -kernels are found in the boot directory were proposed by Yclept Nemo -and Tom Gundersen respectively. - -Signed-off-by: Peter Jones -[javierm: remove outdated URL for BLS document] -Signed-off-by: Javier Martinez Canillas -Signed-off-by: Robbie Harwood ---- - util/grub-mkconfig.8 | 4 + - util/grub-mkconfig.in | 9 +- - util/grub-mkconfig_lib.in | 22 ++++- - util/grub.d/10_linux.in | 223 +++++++++++++++++++++++++++++++++++++++++++++- - 4 files changed, 252 insertions(+), 6 deletions(-) - -diff --git a/util/grub-mkconfig.8 b/util/grub-mkconfig.8 -index a2d1f577b9b..434fa4deda4 100644 ---- a/util/grub-mkconfig.8 -+++ b/util/grub-mkconfig.8 -@@ -13,5 +13,9 @@ - \fB--output\fR=\fIFILE\fR - Write generated output to \fIFILE\fR. - -+.TP -+\fB--no-grubenv-update\fR -+Do not update variables in the grubenv file. -+ - .SH SEE ALSO - .BR "info grub" -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index 535c0f02499..f55339a3f64 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -50,6 +50,8 @@ grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" - export TEXTDOMAIN=@PACKAGE@ - export TEXTDOMAINDIR="@localedir@" - -+export GRUB_GRUBENV_UPDATE="yes" -+ - . "${pkgdatadir}/grub-mkconfig_lib" - - # Usage: usage -@@ -59,6 +61,7 @@ usage () { - gettext "Generate a grub config file"; echo - echo - print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")" -+ print_option_help "--no-grubenv-update" "$(gettext "do not update variables in the grubenv file")" - print_option_help "-h, --help" "$(gettext "print this message and exit")" - print_option_help "-V, --version" "$(gettext "print the version information and exit")" - echo -@@ -94,6 +97,9 @@ do - --output=*) - grub_cfg=`echo "$option" | sed 's/--output=//'` - ;; -+ --no-grubenv-update) -+ GRUB_GRUBENV_UPDATE="no" -+ ;; - -*) - gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 - usage -@@ -253,7 +259,8 @@ export GRUB_DEFAULT \ - GRUB_OS_PROBER_SKIP_LIST \ - GRUB_DISABLE_SUBMENU \ - GRUB_DEFAULT_DTB \ -- SUSE_BTRFS_SNAPSHOT_BOOTING -+ SUSE_BTRFS_SNAPSHOT_BOOTING \ -+ GRUB_ENABLE_BLSCFG - - if test "x${grub_cfg}" != "x"; then - rm -f "${grub_cfg}.new" -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index fafeac95061..d8bb4069360 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -30,6 +30,9 @@ fi - if test "x$grub_file" = x; then - grub_file="${bindir}/@grub_file@" - fi -+if test "x$grub_editenv" = x; then -+ grub_editenv="${bindir}/@grub_editenv@" -+fi - if test "x$grub_mkrelpath" = x; then - grub_mkrelpath="${bindir}/@grub_mkrelpath@" - fi -@@ -125,8 +128,19 @@ EOF - fi - } - -+prepare_grub_to_access_device_with_variable () -+{ -+ device_variable="$1" -+ shift -+ prepare_grub_to_access_device "$@" -+ unset "device_variable" -+} -+ - prepare_grub_to_access_device () - { -+ if [ -z "$device_variable" ]; then -+ device_variable="root" -+ fi - old_ifs="$IFS" - IFS=' - ' -@@ -161,18 +175,18 @@ prepare_grub_to_access_device () - # otherwise set root as per value in device.map. - fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`" - if [ "x$fs_hint" != x ]; then -- echo "set root='$fs_hint'" -+ echo "set ${device_variable}='$fs_hint'" - fi - if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then - hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints= - if [ "x$hints" != x ]; then - echo "if [ x\$feature_platform_search_hint = xy ]; then" -- echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" -+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${hints} ${fs_uuid}" - echo "else" -- echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" -+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" - echo "fi" - else -- echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}" -+ echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" - fi - fi - IFS="$old_ifs" -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 7bb3a211a7c..6bceabf3dc9 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -82,6 +82,223 @@ case x"$GRUB_FS" in - ;; - esac - -+populate_header_warn() -+{ -+if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then -+ bls_parser="10_linux script" -+else -+ bls_parser="blscfg command" -+fi -+cat </dev/null | tac)) || : -+ -+ echo "${files[@]}" -+} -+ -+update_bls_cmdline() -+{ -+ local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+ local -a files=($(get_sorted_bls)) -+ -+ for bls in "${files[@]}"; do -+ local options="${cmdline}" -+ if [ -z "${bls##*debug*}" ]; then -+ options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}" -+ fi -+ options="$(echo "${options}" | sed -e 's/\//\\\//g')" -+ sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf" -+ done -+} -+ -+populate_menu() -+{ -+ local -a files=($(get_sorted_bls)) -+ -+ gettext_printf "Generating boot entries from BLS files...\n" >&2 -+ -+ for bls in "${files[@]}"; do -+ read_config "${blsdir}/${bls}.conf" -+ -+ menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n" -+ menu="${menu}\t linux ${linux} ${options}\n" -+ if [ -n "${initrd}" ] ; then -+ menu="${menu}\t initrd ${boot_prefix}${initrd}\n" -+ fi -+ menu="${menu}}\n\n" -+ done -+ # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation -+ printf "$menu" -+} -+ -+# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed. -+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && [ -z "$(which new-kernel-pkg 2> /dev/null)" ]; then -+ GRUB_ENABLE_BLSCFG="true" -+fi -+ -+if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then -+ if [ x$dirname = x/ ]; then -+ if [ -z "${prepare_root_cache}" ]; then -+ prepare_grub_to_access_device ${GRUB_DEVICE} -+ fi -+ else -+ if [ -z "${prepare_boot_cache}" ]; then -+ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} -+ fi -+ fi -+ -+ if [ -d /sys/firmware/efi ]; then -+ bootefi_device="`${grub_probe} --target=device /boot/efi/`" -+ prepare_grub_to_access_device_with_variable boot ${bootefi_device} -+ else -+ boot_device="`${grub_probe} --target=device /boot/`" -+ prepare_grub_to_access_device_with_variable boot ${boot_device} -+ fi -+ -+ arch="$(uname -m)" -+ if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then -+ -+ BLS_POPULATE_MENU="true" -+ petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot" -+ -+ if test -e ${petitboot_path}; then -+ read -r -d '' petitboot_version < ${petitboot_path} -+ petitboot_version="$(echo ${petitboot_version//v})" -+ -+ if test -n ${petitboot_version}; then -+ major_version="$(echo ${petitboot_version} | cut -d . -f1)" -+ minor_version="$(echo ${petitboot_version} | cut -d . -f2)" -+ -+ re='^[0-9]+$' -+ if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] && -+ ([[ ${major_version} -gt 1 ]] || -+ [[ ${major_version} -eq 1 && -+ ${minor_version} -ge 8 ]]); then -+ BLS_POPULATE_MENU="false" -+ fi -+ fi -+ fi -+ fi -+ -+ populate_header_warn -+ -+ cat << EOF -+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu -+# entries populated from BootLoaderSpec files that use this variable work correctly even -+# without a grubenv file, define a fallback kernelopts variable if this has not been set. -+# -+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by -+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX -+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both -+# the kernelopts variable in the grubenv file and the fallback kernelopts variable. -+if [ -z "\${kernelopts}" ]; then -+ set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+fi -+EOF -+ -+ update_bls_cmdline -+ -+ if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then -+ populate_menu -+ else -+ cat << EOF -+ -+insmod blscfg -+blscfg -+EOF -+ fi -+ -+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then -+ blsdir="/boot/loader/entries" -+ [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})" -+ if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then -+ blsdir=$(make_system_path_relative_to_its_root "${blsdir}") -+ if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then -+ ${grub_editenv} - set blsdir="${blsdir}" -+ fi -+ fi -+ -+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then -+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}" -+ fi -+ -+ if [ -n "${GRUB_DEFAULT_DTB}" ]; then -+ ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}" -+ fi -+ -+ if [ -n "${GRUB_SAVEDEFAULT}" ]; then -+ ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}" -+ fi -+ fi -+ -+ exit 0 -+fi -+ - mktitle () - { - local title_type -@@ -121,6 +338,7 @@ linux_entry () - if [ -z "$boot_device_id" ]; then - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" - fi -+ - if [ x$type != xsimple ] ; then - title=$(mktitle "$type" "$version") - if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then -@@ -231,6 +449,7 @@ is_top_level=true - while [ "x$list" != "x" ] ; do - linux=`version_find_latest $list` - gettext_printf "Found linux image: %s\n" "$linux" >&2 -+ - basename=`basename $linux` - dirname=`dirname $linux` - rel_dirname=`make_system_path_relative_to_its_root $dirname` -@@ -269,7 +488,9 @@ while [ "x$list" != "x" ] ; do - for i in ${initrd}; do - initrd_display="${initrd_display} ${dirname}/${i}" - done -- gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 -+ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then -+ gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 -+ fi - fi - - fdt= diff --git a/0062-Don-t-attempt-to-backtrace-on-grub_abort-for-grub-em.patch b/0062-Don-t-attempt-to-backtrace-on-grub_abort-for-grub-em.patch deleted file mode 100644 index 9ff4c8b..0000000 --- a/0062-Don-t-attempt-to-backtrace-on-grub_abort-for-grub-em.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 6 Feb 2018 11:16:28 +0100 -Subject: [PATCH] Don't attempt to backtrace on grub_abort() for grub-emu - -The emu platform doesn't have a grub_backtrace() implementation, so this -causes a build error. Don't attempt to call this when building grub-emu. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/kern/misc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index a3e215155bd..c60601b699d 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -1201,7 +1201,7 @@ static void __attribute__ ((noreturn)) - grub_abort (void) - { - #ifndef GRUB_UTIL --#if defined(__i386__) || defined(__x86_64__) -+#if (defined(__i386__) || defined(__x86_64__)) && !defined(GRUB_MACHINE_EMU) - grub_backtrace(); - #endif - #endif diff --git a/0063-Add-linux-and-initrd-commands-for-grub-emu.patch b/0063-Add-linux-and-initrd-commands-for-grub-emu.patch deleted file mode 100644 index 2431a4d..0000000 --- a/0063-Add-linux-and-initrd-commands-for-grub-emu.patch +++ /dev/null @@ -1,350 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Raymund Will -Date: Tue, 6 Feb 2018 09:09:00 +0100 -Subject: [PATCH] Add linux and initrd commands for grub-emu - -When using grub-emu, the linux and initrd commands are used as arguments -to the kexec command line tool, to allow booting the selected menu entry. - -Signed-off-by: Raymund Will -Signed-off-by: Robbie Harwood ---- - grub-core/Makefile.core.def | 1 - - grub-core/kern/emu/main.c | 4 + - grub-core/kern/emu/misc.c | 18 ++++- - grub-core/loader/emu/linux.c | 172 +++++++++++++++++++++++++++++++++++++++++++ - include/grub/emu/exec.h | 4 +- - include/grub/emu/hostfile.h | 3 +- - include/grub/emu/misc.h | 3 + - grub-core/Makefile.am | 1 + - 8 files changed, 202 insertions(+), 4 deletions(-) - create mode 100644 grub-core/loader/emu/linux.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 058c88ac3af..5354f9613d3 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -1826,7 +1826,6 @@ module = { - - common = loader/linux.c; - common = lib/cmdline.c; -- enable = noemu; - - efi = loader/efi/linux.c; - }; -diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c -index 55ea5a11ccd..846fe9715ec 100644 ---- a/grub-core/kern/emu/main.c -+++ b/grub-core/kern/emu/main.c -@@ -107,6 +107,7 @@ static struct argp_option options[] = { - N_("use GRUB files in the directory DIR [default=%s]"), 0}, - {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, - {"hold", 'H', N_("SECS"), OPTION_ARG_OPTIONAL, N_("wait until a debugger will attach"), 0}, -+ {"kexec", 'X', 0, 0, N_("try the untryable."), 0}, - { 0, 0, 0, 0, 0, 0 } - }; - -@@ -164,6 +165,9 @@ argp_parser (int key, char *arg, struct argp_state *state) - case 'v': - verbosity++; - break; -+ case 'X': -+ grub_util_set_kexecute(); -+ break; - - case ARGP_KEY_ARG: - { -diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c -index 0ff13bcaf8c..eeea092752d 100644 ---- a/grub-core/kern/emu/misc.c -+++ b/grub-core/kern/emu/misc.c -@@ -39,6 +39,7 @@ - #include - - int verbosity; -+int kexecute; - - void - grub_util_warn (const char *fmt, ...) -@@ -82,7 +83,7 @@ grub_util_error (const char *fmt, ...) - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); -- exit (1); -+ grub_exit (1); - } - - void * -@@ -154,6 +155,9 @@ void - __attribute__ ((noreturn)) - grub_exit (int rc) - { -+#if defined (GRUB_KERNEL) -+ grub_reboot(); -+#endif - exit (rc < 0 ? 1 : rc); - } - #endif -@@ -215,3 +219,15 @@ grub_util_load_image (const char *path, char *buf) - - fclose (fp); - } -+ -+void -+grub_util_set_kexecute(void) -+{ -+ kexecute++; -+} -+ -+int -+grub_util_get_kexecute(void) -+{ -+ return kexecute; -+} -diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c -new file mode 100644 -index 00000000000..fda9e00d24c ---- /dev/null -+++ b/grub-core/loader/emu/linux.c -@@ -0,0 +1,172 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_dl_t my_mod; -+ -+static char *kernel_path; -+static char *initrd_path; -+static char *boot_cmdline; -+ -+static grub_err_t -+grub_linux_boot (void) -+{ -+ grub_err_t rc = GRUB_ERR_NONE; -+ char *initrd_param; -+ const char *kexec[] = { "kexec", "-l", kernel_path, boot_cmdline, NULL, NULL }; -+ const char *systemctl[] = { "systemctl", "kexec", NULL }; -+ int kexecute = grub_util_get_kexecute(); -+ -+ if (initrd_path) { -+ initrd_param = grub_xasprintf("--initrd=%s", initrd_path); -+ kexec[3] = initrd_param; -+ kexec[4] = boot_cmdline; -+ } else { -+ initrd_param = grub_xasprintf("%s", ""); -+ } -+ -+ grub_printf("%serforming 'kexec -l %s %s %s'\n", -+ (kexecute) ? "P" : "Not p", -+ kernel_path, initrd_param, boot_cmdline); -+ -+ if (kexecute) -+ rc = grub_util_exec(kexec); -+ -+ grub_free(initrd_param); -+ -+ if (rc != GRUB_ERR_NONE) { -+ grub_error (rc, N_("Error trying to perform kexec load operation.")); -+ grub_sleep (3); -+ return rc; -+ } -+ if (kexecute < 1) -+ grub_fatal (N_("Use '"PACKAGE"-emu --kexec' to force a system restart.")); -+ -+ grub_printf("Performing 'systemctl kexec' (%s) ", -+ (kexecute==1) ? "do-or-die" : "just-in-case"); -+ rc = grub_util_exec (systemctl); -+ -+ if (kexecute == 1) -+ grub_fatal (N_("Error trying to perform 'systemctl kexec'")); -+ -+ /* need to check read-only root before resetting hard!? */ -+ grub_printf("Performing 'kexec -e'"); -+ kexec[1] = "-e"; -+ kexec[2] = NULL; -+ rc = grub_util_exec(kexec); -+ if ( rc != GRUB_ERR_NONE ) -+ grub_fatal (N_("Error trying to directly perform 'kexec -e'.")); -+ -+ return rc; -+} -+ -+static grub_err_t -+grub_linux_unload (void) -+{ -+ grub_dl_unref (my_mod); -+ if ( boot_cmdline != NULL ) -+ grub_free (boot_cmdline); -+ boot_cmdline = NULL; -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) -+{ -+ int i; -+ char *tempstr; -+ -+ grub_dl_ref (my_mod); -+ -+ if (argc == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ -+ if ( !grub_util_is_regular(argv[0]) ) -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("Cannot find kernel file %s"), argv[0]); -+ -+ if ( kernel_path != NULL ) -+ grub_free(kernel_path); -+ -+ kernel_path = grub_xasprintf("%s", argv[0]); -+ -+ if ( boot_cmdline != NULL ) { -+ grub_free(boot_cmdline); -+ boot_cmdline = NULL; -+ } -+ -+ if ( argc > 1 ) -+ { -+ boot_cmdline = grub_xasprintf("--command-line=%s", argv[1]); -+ for ( i = 2; i < argc; i++ ) { -+ tempstr = grub_xasprintf("%s %s", boot_cmdline, argv[i]); -+ grub_free(boot_cmdline); -+ boot_cmdline = tempstr; -+ } -+ } -+ -+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) -+{ -+ if (argc == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ -+ if ( !grub_util_is_regular(argv[0]) ) -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("Cannot find initrd file %s"), argv[0]); -+ -+ if ( initrd_path != NULL ) -+ grub_free(initrd_path); -+ -+ initrd_path = grub_xasprintf("%s", argv[0]); -+ -+ grub_dl_unref (my_mod); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_command_t cmd_linux, cmd_initrd; -+ -+GRUB_MOD_INIT(linux) -+{ -+ cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0, N_("Load Linux.")); -+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0, N_("Load initrd.")); -+ my_mod = mod; -+ kernel_path = NULL; -+ initrd_path = NULL; -+ boot_cmdline = NULL; -+} -+ -+GRUB_MOD_FINI(linux) -+{ -+ grub_unregister_command (cmd_linux); -+ grub_unregister_command (cmd_initrd); -+} -diff --git a/include/grub/emu/exec.h b/include/grub/emu/exec.h -index d1073ef86af..1b61b4a2e5d 100644 ---- a/include/grub/emu/exec.h -+++ b/include/grub/emu/exec.h -@@ -23,6 +23,8 @@ - #include - - #include -+#include -+ - pid_t - grub_util_exec_pipe (const char *const *argv, int *fd); - pid_t -@@ -32,7 +34,7 @@ int - grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, - const char *stdout_file, const char *stderr_file); - int --grub_util_exec (const char *const *argv); -+EXPORT_FUNC(grub_util_exec) (const char *const *argv); - int - grub_util_exec_redirect (const char *const *argv, const char *stdin_file, - const char *stdout_file); -diff --git a/include/grub/emu/hostfile.h b/include/grub/emu/hostfile.h -index cfb1e2b5661..a61568e36e9 100644 ---- a/include/grub/emu/hostfile.h -+++ b/include/grub/emu/hostfile.h -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - - int -@@ -29,7 +30,7 @@ grub_util_is_directory (const char *path); - int - grub_util_is_special_file (const char *path); - int --grub_util_is_regular (const char *path); -+EXPORT_FUNC(grub_util_is_regular) (const char *path); - - char * - grub_util_path_concat (size_t n, ...); -diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h -index ff9c48a6490..01056954b96 100644 ---- a/include/grub/emu/misc.h -+++ b/include/grub/emu/misc.h -@@ -57,6 +57,9 @@ void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...) __attribute__ ((format ( - void EXPORT_FUNC(grub_util_info) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); - void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2), noreturn)); - -+void EXPORT_FUNC(grub_util_set_kexecute) (void); -+int EXPORT_FUNC(grub_util_get_kexecute) (void) WARN_UNUSED_RESULT; -+ - grub_uint64_t EXPORT_FUNC (grub_util_get_cpu_time_ms) (void); - - #ifdef HAVE_DEVICE_MAPPER -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index ee88e44e97a..80e7a83edf9 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -307,6 +307,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/net.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostfile.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/exec.h - if COND_GRUB_EMU_SDL - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h - endif diff --git a/0064-Add-grub2-switch-to-blscfg.patch b/0064-Add-grub2-switch-to-blscfg.patch deleted file mode 100644 index ac30490..0000000 --- a/0064-Add-grub2-switch-to-blscfg.patch +++ /dev/null @@ -1,410 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 15 Mar 2018 14:12:40 -0400 -Subject: [PATCH] Add grub2-switch-to-blscfg - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub] -Signed-off-by: Jan Hlavac ---- - Makefile.util.def | 7 + - util/grub-set-password.in | 2 +- - util/grub-switch-to-blscfg.8 | 33 +++++ - util/grub-switch-to-blscfg.in | 317 ++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 358 insertions(+), 1 deletion(-) - create mode 100644 util/grub-switch-to-blscfg.8 - create mode 100644 util/grub-switch-to-blscfg.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 43a1c7453b1..a90879fa9ba 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -1365,6 +1365,13 @@ program = { - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - }; - -+script = { -+ name = grub-switch-to-blscfg; -+ common = util/grub-switch-to-blscfg.in; -+ mansection = 8; -+ installdir = sbin; -+}; -+ - program = { - name = grub-glue-efi; - mansection = 1; -diff --git a/util/grub-set-password.in b/util/grub-set-password.in -index 5ebf50576d6..c0b5ebbfdc5 100644 ---- a/util/grub-set-password.in -+++ b/util/grub-set-password.in -@@ -1,6 +1,6 @@ - #!/bin/sh -e - --EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/') -+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') - if [ -d /sys/firmware/efi/efivars/ ]; then - grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` - else -diff --git a/util/grub-switch-to-blscfg.8 b/util/grub-switch-to-blscfg.8 -new file mode 100644 -index 00000000000..9a886282976 ---- /dev/null -+++ b/util/grub-switch-to-blscfg.8 -@@ -0,0 +1,33 @@ -+.TH GRUB-SWITCH-TO-BLSCFG 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-switch-to-blscfg\fR \(em Switch to using BLS config files. -+ -+.SH SYNOPSIS -+\fBgrub-switch-to-blscfg\fR [--grub-directory=\fIDIR\fR] [--config-file=\fIFILE\fR] [--grub-defaults=\fIFILE\fR] -+ -+.SH DESCRIPTION -+\fBgrub-switch-to-blscfg\fR reconfigures grub-mkconfig to use BLS-style config files, and then regenerates the GRUB configuration. -+ -+.SH OPTIONS -+.TP -+--grub-directory=\fIDIR\fR -+Search for grub.cfg under \fIDIR\fR. The default value is \fI/boot/efi/EFI/\fBVENDOR\fR on UEFI machines and \fI/boot/grub2\fR elsewhere. -+ -+.TP -+--config-file=\fIFILE\fR -+The grub config file to use. The default value is \fI/etc/grub2-efi.cfg\fR on UEFI machines and \fI/etc/grub2.cfg\fR elsewhere. Symbolic links will be followed. -+ -+.TP -+--grub-defaults=\fIFILE\fR -+The defaults file for grub-mkconfig. The default value is \fI/etc/default/grub\fR. -+ -+.TP -+--bls-directory=\fIDIR\fR -+Create BootLoaderSpec fragments in \fIDIR\fR. The default value is \fI/boot/loader/entries\fR. -+ -+.TP -+--backup-suffix=\fSUFFIX\fR -+The suffix to use for saved backup files. The default value is \fI.bak\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in -new file mode 100644 -index 00000000000..a851424beb2 ---- /dev/null -+++ b/util/grub-switch-to-blscfg.in -@@ -0,0 +1,317 @@ -+#! /bin/sh -+# -+# Set a default boot entry for GRUB. -+# Copyright (C) 2004,2009 Free Software Foundation, Inc. -+# -+# GRUB is free software: you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation, either version 3 of the License, or -+# (at your option) any later version. -+# -+# GRUB is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with GRUB. If not, see . -+ -+#set -eu -+ -+# Initialize some variables. -+prefix=@prefix@ -+exec_prefix=@exec_prefix@ -+sbindir=@sbindir@ -+bindir=@bindir@ -+sysconfdir="@sysconfdir@" -+PACKAGE_NAME=@PACKAGE_NAME@ -+PACKAGE_VERSION=@PACKAGE_VERSION@ -+datarootdir="@datarootdir@" -+datadir="@datadir@" -+if [ ! -v pkgdatadir ]; then -+ pkgdatadir="${datadir}/@PACKAGE@" -+fi -+ -+self=`basename $0` -+ -+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" -+grub_editenv=${bindir}/@grub_editenv@ -+etcdefaultgrub=/etc/default/grub -+ -+eval "$("${grub_get_kernel_settings}")" || true -+ -+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') -+if [ -d /sys/firmware/efi/efivars/ ]; then -+ startlink=/etc/grub2-efi.cfg -+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` -+else -+ startlink=/etc/grub2.cfg -+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` -+fi -+ -+blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'` -+ -+backupsuffix=.bak -+ -+arch="$(uname -m)" -+ -+export TEXTDOMAIN=@PACKAGE@ -+export TEXTDOMAINDIR="@localedir@" -+ -+. "${pkgdatadir}/grub-mkconfig_lib" -+ -+# Usage: usage -+# Print the usage. -+usage () { -+ gettext_printf "Usage: %s\n" "$self" -+ gettext "Switch to BLS config files.\n"; echo -+ echo -+ print_option_help "-h, --help" "$(gettext "print this message and exit")" -+ print_option_help "-V, --version" "$(gettext "print the version information and exit")" -+ echo -+ print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix" -+ print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir" -+ print_option_help "--config-file=$(gettext "FILE")" "$startlink" -+ print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub" -+ print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir" -+ # echo -+ # gettext "Report bugs to ."; echo -+} -+ -+argument () { -+ opt=$1 -+ shift -+ -+ if test $# -eq 0; then -+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 -+ exit 1 -+ fi -+ echo $1 -+} -+ -+# Check the arguments. -+while test $# -gt 0 -+do -+ option=$1 -+ shift -+ -+ case "$option" in -+ -h | --help) -+ usage -+ exit 0 ;; -+ -V | --version) -+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" -+ exit 0 ;; -+ -+ --backup-suffix) -+ backupsuffix=`argument $option "$@"` -+ shift -+ ;; -+ --backup-suffix=*) -+ backupsuffix=`echo "$option" | sed 's/--backup-suffix=//'` -+ ;; -+ -+ --bls-directory) -+ blsdir=`argument $option "$@"` -+ shift -+ ;; -+ --bls-directory=*) -+ blsdir=`echo "$option" | sed 's/--bls-directory=//'` -+ ;; -+ -+ --config-file) -+ startlink=`argument $option "$@"` -+ shift -+ ;; -+ --config-file=*) -+ startlink=`echo "$option" | sed 's/--config-file=//'` -+ ;; -+ -+ --grub-defaults) -+ etcdefaultgrub=`argument $option "$@"` -+ shift -+ ;; -+ --grub-defaults=*) -+ etcdefaultgrub=`echo "$option" | sed 's/--grub-defaults=//'` -+ ;; -+ -+ --grub-directory) -+ grubdir=`argument $option "$@"` -+ shift -+ ;; -+ --grub-directory=*) -+ grubdir=`echo "$option" | sed 's/--grub-directory=//'` -+ ;; -+ -+ *) -+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 -+ usage -+ exit 1 -+ ;; -+ esac -+done -+ -+find_grub_cfg() { -+ local candidate="" -+ while [ -e "${candidate}" -o $# -gt 0 ] -+ do -+ if [ ! -e "${candidate}" ] ; then -+ candidate="$1" -+ shift -+ fi -+ -+ if [ -L "${candidate}" ]; then -+ candidate="$(realpath "${candidate}")" -+ fi -+ -+ if [ -f "${candidate}" ]; then -+ export GRUB_CONFIG_FILE="${candidate}" -+ return 0 -+ fi -+ done -+ return 1 -+} -+ -+if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then -+ gettext_printf "Couldn't find config file\n" 1>&2 -+ exit 1 -+fi -+ -+if [ ! -d "${blsdir}" ]; then -+ install -m 700 -d "${blsdir}" -+fi -+ -+if [ -f /etc/machine-id ]; then -+ MACHINE_ID=$(cat /etc/machine-id) -+else -+ MACHINE_ID=$(dmesg | sha256sum) -+fi -+ -+mkbls() { -+ local kernelver=$1 && shift -+ local datetime=$1 && shift -+ local kernelopts=$1 && shift -+ -+ local debugname="" -+ local debugid="" -+ local flavor="" -+ -+ if [ "$kernelver" == *\+* ] ; then -+ local flavor=-"${kernelver##*+}" -+ if [ "${flavor}" == "-debug" ]; then -+ local debugname=" with debugging" -+ local debugid="-debug" -+ fi -+ fi -+ ( -+ source /etc/os-release -+ -+ cat <"${bls_target}" -+ -+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then -+ bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")" -+ cp -aT "${bls_target}" "${bls_debug}" -+ title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')" -+ options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')" -+ sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}" -+ sed -i -e "s/^options.*/options ${options}/" "${bls_debug}" -+ fi -+ done -+ -+ if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then -+ mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf" -+ fi -+} -+ -+# The grub2 EFI binary is not copied to the ESP as a part of an ostree -+# transaction. Make sure a grub2 version with BLS support is installed -+# but only do this if the blsdir is not set, to make sure that the BLS -+# parsing module will search for the BLS snippets in the default path. -+if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \ -+ ! ${grub_editenv} - list | grep -q blsdir && \ -+ mountpoint -q /boot; then -+ grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)" -+ install -m 700 ${grub_binary} ${grubdir} || exit 1 -+ # Create a hidden file to indicate that grub2 now has BLS support. -+ touch /boot/grub2/.grub2-blscfg-supported -+fi -+ -+GENERATE=0 -+if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \ -+ | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then -+ if ! sed -i"${backupsuffix}" \ -+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=true,' \ -+ "${etcdefaultgrub}" ; then -+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" -+ exit 1 -+ fi -+ GENERATE=1 -+elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then -+ if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then -+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" -+ exit 1 -+ fi -+ GENERATE=1 -+fi -+ -+if [ "${GENERATE}" -eq 1 ] ; then -+ copy_bls -+ -+ if [ $arch = "x86_64" ] && [ ! -d /sys/firmware/efi ]; then -+ mod_dir="i386-pc" -+ elif [ $arch = "ppc64" -o $arch = "ppc64le" ] && [ ! -d /sys/firmware/opal ]; then -+ mod_dir="powerpc-ieee1275" -+ fi -+ -+ if [ -n "${mod_dir}" ]; then -+ for mod in blscfg increment; do -+ install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1 -+ done -+ fi -+ -+ cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}" -+ if ! grub2-mkconfig -o "${GRUB_CONFIG_FILE}" ; then -+ install -m 700 "${GRUB_CONFIG_FILE}${backupsuffix}" "${GRUB_CONFIG_FILE}" -+ sed -i"${backupsuffix}" \ -+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=false,' \ -+ "${etcdefaultgrub}" -+ gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}" -+ exit 1 -+ fi -+fi -+ -+# Bye. -+exit 0 diff --git a/0065-make-better-backtraces.patch b/0065-make-better-backtraces.patch deleted file mode 100644 index 6376567..0000000 --- a/0065-make-better-backtraces.patch +++ /dev/null @@ -1,910 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 17:05:03 +0200 -Subject: [PATCH] make better backtraces - -Signed-off-by: Peter Jones ---- - Makefile.util.def | 6 ++ - grub-core/Makefile.core.def | 16 ++-- - grub-core/{lib => commands}/backtrace.c | 2 +- - grub-core/gdb/cstub.c | 1 - - grub-core/kern/arm64/backtrace.c | 94 ++++++++++++++++++++++++ - grub-core/kern/backtrace.c | 97 +++++++++++++++++++++++++ - grub-core/kern/dl.c | 45 ++++++++++++ - grub-core/kern/i386/backtrace.c | 125 ++++++++++++++++++++++++++++++++ - grub-core/kern/i386/pc/init.c | 4 +- - grub-core/kern/ieee1275/init.c | 1 - - grub-core/kern/misc.c | 13 ++-- - grub-core/kern/mm.c | 6 +- - grub-core/lib/arm64/backtrace.c | 62 ---------------- - grub-core/lib/i386/backtrace.c | 78 -------------------- - include/grub/backtrace.h | 10 ++- - include/grub/dl.h | 2 + - include/grub/kernel.h | 3 + - grub-core/kern/arm/efi/startup.S | 2 + - grub-core/kern/arm/startup.S | 2 + - grub-core/kern/arm64/efi/startup.S | 2 + - grub-core/kern/i386/qemu/startup.S | 3 +- - grub-core/kern/ia64/efi/startup.S | 3 +- - grub-core/kern/sparc64/ieee1275/crt0.S | 3 +- - grub-core/Makefile.am | 1 + - 24 files changed, 414 insertions(+), 167 deletions(-) - rename grub-core/{lib => commands}/backtrace.c (98%) - create mode 100644 grub-core/kern/arm64/backtrace.c - create mode 100644 grub-core/kern/backtrace.c - create mode 100644 grub-core/kern/i386/backtrace.c - delete mode 100644 grub-core/lib/arm64/backtrace.c - delete mode 100644 grub-core/lib/i386/backtrace.c - -diff --git a/Makefile.util.def b/Makefile.util.def -index a90879fa9ba..48512bc6311 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -51,6 +51,12 @@ library = { - common = grub-core/partmap/msdos.c; - common = grub-core/fs/proc.c; - common = grub-core/fs/archelp.c; -+ common = grub-core/kern/backtrace.c; -+ -+ x86 = grub-core/kern/i386/backtrace.c; -+ i386_xen = grub-core/kern/i386/backtrace.c; -+ x86_64_xen = grub-core/kern/i386/backtrace.c; -+ arm64 = grub-core/kern/arm64/backtrace.c; - }; - - library = { -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 5354f9613d3..4b7c45a7b06 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -142,6 +142,12 @@ kernel = { - common = kern/rescue_reader.c; - common = kern/term.c; - common = kern/verifiers.c; -+ common = kern/backtrace.c; -+ -+ x86 = kern/i386/backtrace.c; -+ i386_xen = kern/i386/backtrace.c; -+ x86_64_xen = kern/i386/backtrace.c; -+ arm64 = kern/arm64/backtrace.c; - - noemu = kern/compiler-rt.c; - noemu = kern/mm.c; -@@ -188,9 +194,6 @@ kernel = { - - softdiv = lib/division.c; - -- x86 = lib/i386/backtrace.c; -- x86 = lib/backtrace.c; -- - i386 = kern/i386/dl.c; - i386_xen = kern/i386/dl.c; - i386_xen_pvh = kern/i386/dl.c; -@@ -2398,15 +2401,12 @@ module = { - - module = { - name = backtrace; -- x86 = lib/i386/backtrace.c; -- i386_xen_pvh = lib/i386/backtrace.c; -- i386_xen = lib/i386/backtrace.c; -- x86_64_xen = lib/i386/backtrace.c; -- common = lib/backtrace.c; -+ common = commands/backtrace.c; - enable = x86; - enable = i386_xen_pvh; - enable = i386_xen; - enable = x86_64_xen; -+ enable = arm64; - }; - - module = { -diff --git a/grub-core/lib/backtrace.c b/grub-core/commands/backtrace.c -similarity index 98% -rename from grub-core/lib/backtrace.c -rename to grub-core/commands/backtrace.c -index c0ad6ab8be1..8b5ec3913b5 100644 ---- a/grub-core/lib/backtrace.c -+++ b/grub-core/commands/backtrace.c -@@ -54,7 +54,7 @@ grub_cmd_backtrace (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) - { -- grub_backtrace (); -+ grub_backtrace (1); - return 0; - } - -diff --git a/grub-core/gdb/cstub.c b/grub-core/gdb/cstub.c -index b64acd70fee..99281472d36 100644 ---- a/grub-core/gdb/cstub.c -+++ b/grub-core/gdb/cstub.c -@@ -215,7 +215,6 @@ grub_gdb_trap (int trap_no) - grub_printf ("Unhandled exception 0x%x at ", trap_no); - grub_backtrace_print_address ((void *) grub_gdb_regs[PC]); - grub_printf ("\n"); -- grub_backtrace_pointer ((void *) grub_gdb_regs[EBP]); - grub_fatal ("Unhandled exception"); - } - -diff --git a/grub-core/kern/arm64/backtrace.c b/grub-core/kern/arm64/backtrace.c -new file mode 100644 -index 00000000000..019c6fdfef2 ---- /dev/null -+++ b/grub-core/kern/arm64/backtrace.c -@@ -0,0 +1,94 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_STACK_FRAME 102400 -+ -+struct fplr -+{ -+ void *lr; -+ struct fplr *fp; -+}; -+ -+void -+grub_backtrace_pointer (void *frame, unsigned int skip) -+{ -+ unsigned int x = 0; -+ struct fplr *fplr = (struct fplr *)frame; -+ -+ while (fplr) -+ { -+ const char *name = NULL; -+ char *addr = NULL; -+ -+ grub_dprintf("backtrace", "fp is %p next_fp is %p\n", -+ fplr, fplr->fp); -+ -+ if (x >= skip) -+ { -+ name = grub_get_symbol_by_addr (fplr->lr, 1); -+ if (name) -+ addr = grub_resolve_symbol (name); -+ grub_backtrace_print_address (fplr->lr); -+ -+ if (addr && addr != fplr->lr) -+ grub_printf (" %s() %p+%p \n", name ? name : "unknown", addr, -+ (void *)((grub_uint64_t)fplr->lr - (grub_uint64_t)addr)); -+ else -+ grub_printf(" %s() %p \n", name ? name : "unknown", addr); -+ -+ } -+ -+ x += 1; -+ -+ if (fplr->fp < fplr || -+ (grub_uint64_t)fplr->fp - (grub_uint64_t)fplr > MAX_STACK_FRAME || -+ fplr->fp == fplr) -+ { -+ break; -+ } -+ fplr = fplr->fp; -+ } -+} -+ -+asm ("\t.global \"_text\"\n" -+ "_text:\n" -+ "\t.quad .text\n" -+ "\t.global \"_data\"\n" -+ "_data:\n" -+ "\t.quad .data\n" -+ ); -+ -+extern grub_uint64_t _text; -+extern grub_uint64_t _data; -+ -+void -+grub_backtrace_arch (unsigned int skip) -+{ -+ grub_printf ("Backtrace (.text %p .data %p):\n", -+ (void *)_text, (void *)_data); -+ skip += 1; -+ grub_backtrace_pointer(__builtin_frame_address(0), skip); -+} -diff --git a/grub-core/kern/backtrace.c b/grub-core/kern/backtrace.c -new file mode 100644 -index 00000000000..4a82e865cc6 ---- /dev/null -+++ b/grub-core/kern/backtrace.c -@@ -0,0 +1,97 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static void -+grub_backtrace_print_address_default (void *addr) -+{ -+#ifndef GRUB_UTIL -+ grub_dl_t mod; -+ void *start_addr; -+ -+ FOR_DL_MODULES (mod) -+ { -+ grub_dl_segment_t segment; -+ for (segment = mod->segment; segment; segment = segment->next) -+ if (segment->addr <= addr && (grub_uint8_t *) segment->addr -+ + segment->size > (grub_uint8_t *) addr) -+ { -+ grub_printf ("%s.%x+%" PRIxGRUB_SIZE, mod->name, -+ segment->section, -+ (grub_size_t) -+ ((grub_uint8_t *)addr - (grub_uint8_t *)segment->addr)); -+ return; -+ } -+ } -+ -+ start_addr = grub_resolve_symbol ("_start"); -+ if (start_addr && start_addr < addr) -+ grub_printf ("kernel+%" PRIxGRUB_SIZE, -+ (grub_size_t) -+ ((grub_uint8_t *)addr - (grub_uint8_t *)start_addr)); -+ else -+#endif -+ grub_printf ("%p", addr); -+} -+ -+static void -+grub_backtrace_pointer_default (void *frame __attribute__((__unused__)), -+ unsigned int skip __attribute__((__unused__))) -+{ -+ return; -+} -+ -+void -+grub_backtrace_pointer (void *frame, unsigned int skip) -+ __attribute__((__weak__, -+ __alias__(("grub_backtrace_pointer_default")))); -+ -+void -+grub_backtrace_print_address (void *addr) -+ __attribute__((__weak__, -+ __alias__(("grub_backtrace_print_address_default")))); -+ -+static void -+grub_backtrace_arch_default(unsigned int skip) -+{ -+ grub_backtrace_pointer(__builtin_frame_address(0), skip + 1); -+} -+ -+void grub_backtrace_arch (unsigned int skip) -+ __attribute__((__weak__, __alias__(("grub_backtrace_arch_default")))); -+ -+void grub_backtrace (unsigned int skip) -+{ -+ grub_backtrace_arch(skip + 1); -+} -+ -+void grub_debug_backtrace (const char * const debug, -+ unsigned int skip) -+{ -+ if (grub_debug_enabled (debug)) -+ grub_backtrace (skip + 1); -+} -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 7afb9e6f724..88d2077709e 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -124,6 +124,50 @@ grub_dl_resolve_symbol (const char *name) - return 0; - } - -+void * -+grub_resolve_symbol (const char *name) -+{ -+ grub_symbol_t sym; -+ -+ sym = grub_dl_resolve_symbol (name); -+ if (sym) -+ return sym->addr; -+ return NULL; -+} -+ -+const char * -+grub_get_symbol_by_addr(const void *addr, int isfunc) -+{ -+ unsigned int i; -+ grub_symbol_t before = NULL, after = NULL; -+ for (i = 0; i < GRUB_SYMTAB_SIZE; i++) -+ { -+ grub_symbol_t sym; -+ for (sym = grub_symtab[i]; sym; sym = sym->next) -+ { -+ //grub_printf ("addr 0x%08llx symbol %s\n", (unsigned long long)sym->addr, sym->name); -+ if (sym->addr > addr) -+ { -+ if (!after || sym->addr > after->addr) -+ after = sym; -+ } -+ -+ if (isfunc != sym->isfunc) -+ continue; -+ if (sym->addr > addr) -+ continue; -+ -+ if ((!before && sym->addr <= addr) || (before && before->addr <= sym->addr)) -+ before = sym; -+ } -+ } -+ -+ if (before && addr < after->addr) -+ return before->name; -+ -+ return NULL; -+} -+ - /* Register a symbol with the name NAME and the address ADDR. */ - grub_err_t - grub_dl_register_symbol (const char *name, void *addr, int isfunc, -@@ -336,6 +380,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) - const char *str; - Elf_Word size, entsize; - -+ grub_dprintf ("modules", "Resolving symbols for \"%s\"\n", mod->name); - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) -diff --git a/grub-core/kern/i386/backtrace.c b/grub-core/kern/i386/backtrace.c -new file mode 100644 -index 00000000000..2413f9a57db ---- /dev/null -+++ b/grub-core/kern/i386/backtrace.c -@@ -0,0 +1,125 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_STACK_FRAME 102400 -+ -+void -+grub_backtrace_pointer (void *frame, unsigned int skip) -+{ -+ void **ebp = (void **)frame; -+ unsigned long x = 0; -+ -+ while (ebp) -+ { -+ void **next_ebp = (void **)ebp[0]; -+ const char *name = NULL; -+ char *addr = NULL; -+ -+ grub_dprintf("backtrace", "ebp is %p next_ebp is %p\n", ebp, next_ebp); -+ -+ if (x >= skip) -+ { -+ name = grub_get_symbol_by_addr (ebp[1], 1); -+ if (name) -+ addr = grub_resolve_symbol (name); -+ grub_backtrace_print_address (ebp[1]); -+ -+ if (addr && addr != ebp[1]) -+ grub_printf (" %s() %p+%p \n", name ? name : "unknown", addr, -+ (char *)((char *)ebp[1] - addr)); -+ else -+ grub_printf(" %s() %p \n", name ? name : "unknown", addr); -+ -+#if 0 -+ grub_printf ("("); -+ for (i = 0, arg = ebp[2]; arg != next_ebp && i < 12; arg++, i++) -+ grub_printf ("%p,", arg); -+ grub_printf (")\n"); -+#endif -+ } -+ -+ x += 1; -+ -+ if (next_ebp < ebp || next_ebp - ebp > MAX_STACK_FRAME || next_ebp == ebp) -+ { -+ //grub_printf ("Invalid stack frame at %p (%p)\n", ebp, next_ebp); -+ break; -+ } -+ ebp = next_ebp; -+ } -+} -+ -+#if defined (__x86_64__) -+asm ("\t.global \"_text\"\n" -+ "_text:\n" -+ "\t.quad .text\n" -+ "\t.global \"_data\"\n" -+ "_data:\n" -+ "\t.quad .data\n" -+ ); -+#elif defined(__i386__) -+asm ("\t.global \"_text\"\n" -+ "_text:\n" -+ "\t.long .text\n" -+ "\t.global \"_data\"\n" -+ "_data:\n" -+ "\t.long .data\n" -+ ); -+#else -+#warning I dunno... -+#endif -+ -+extern unsigned long _text; -+extern unsigned long _data; -+ -+#ifdef GRUB_UTIL -+#define EXT_C(x) x -+#endif -+ -+void -+grub_backtrace_arch (unsigned int skip) -+{ -+ grub_printf ("Backtrace (.text %p .data %p):\n", -+ (void *)_text, (void *)_data); -+ skip += 1; -+#if defined (__x86_64__) -+ asm volatile ("movq %%rbp, %%rdi\n" -+ "movq 0, %%rsi\n" -+ "movl %0, %%esi\n" -+ "call " EXT_C("grub_backtrace_pointer") -+ : -+ : "r" (skip)); -+#elif defined(__i386__) -+ asm volatile ("addl $8, %%esp\n" -+ "pushl %0\n" -+ "pushl %%ebp\n" -+ "call " EXT_C("grub_backtrace_pointer") -+ : -+ : "r" (skip)); -+#else -+ grub_backtrace_pointer(__builtin_frame_address(0), skip); -+#endif -+} -diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c -index 27bc68b8a53..b51d0abfa6e 100644 ---- a/grub-core/kern/i386/pc/init.c -+++ b/grub-core/kern/i386/pc/init.c -@@ -153,7 +153,7 @@ compact_mem_regions (void) - } - - grub_addr_t grub_modbase; --extern grub_uint8_t _start[], _edata[]; -+extern grub_uint8_t _edata[]; - - /* Helper for grub_machine_init. */ - static int -@@ -217,7 +217,7 @@ grub_machine_init (void) - /* This has to happen before any BIOS calls. */ - grub_via_workaround_init (); - -- grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start); -+ grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - (grub_uint8_t *)_start); - - /* Initialize the console as early as possible. */ - grub_console_init (); -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index 0cd2a627231..937c1bc44cb 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -63,7 +63,6 @@ - #define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024) - #endif - --extern char _start[]; - extern char _end[]; - - #ifdef __sparc__ -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index c60601b699d..a432a6be54a 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -1197,15 +1197,15 @@ grub_printf_fmt_check (const char *fmt, const char *fmt_expected) - - - /* Abort GRUB. This function does not return. */ --static void __attribute__ ((noreturn)) -+static inline void __attribute__ ((noreturn)) - grub_abort (void) - { --#ifndef GRUB_UTIL --#if (defined(__i386__) || defined(__x86_64__)) && !defined(GRUB_MACHINE_EMU) -- grub_backtrace(); -+#if !defined(GRUB_MACHINE_EMU) && !defined(GRUB_UTIL) -+ grub_backtrace (1); -+#else -+ grub_printf ("\n"); - #endif --#endif -- grub_printf ("\nAborted."); -+ grub_printf ("Aborted."); - - #ifndef GRUB_UTIL - if (grub_term_inputs) -@@ -1232,6 +1232,7 @@ grub_fatal (const char *fmt, ...) - { - va_list ap; - -+ grub_printf ("\n"); - va_start (ap, fmt); - grub_vprintf (_(fmt), ap); - va_end (ap); -diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c -index c070afc621f..d8c8377578b 100644 ---- a/grub-core/kern/mm.c -+++ b/grub-core/kern/mm.c -@@ -97,13 +97,13 @@ get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r) - break; - - if (! *r) -- grub_fatal ("out of range pointer %p", ptr); -+ grub_fatal ("out of range pointer %p\n", ptr); - - *p = (grub_mm_header_t) ptr - 1; - if ((*p)->magic == GRUB_MM_FREE_MAGIC) -- grub_fatal ("double free at %p", *p); -+ grub_fatal ("double free at %p\n", *p); - if ((*p)->magic != GRUB_MM_ALLOC_MAGIC) -- grub_fatal ("alloc magic is broken at %p: %lx", *p, -+ grub_fatal ("alloc magic is broken at %p: %lx\n", *p, - (unsigned long) (*p)->magic); - } - -diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c -deleted file mode 100644 -index 1079b5380e1..00000000000 ---- a/grub-core/lib/arm64/backtrace.c -+++ /dev/null -@@ -1,62 +0,0 @@ --/* -- * GRUB -- GRand Unified Bootloader -- * Copyright (C) 2009 Free Software Foundation, Inc. -- * -- * GRUB is free software: you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation, either version 3 of the License, or -- * (at your option) any later version. -- * -- * GRUB is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with GRUB. If not, see . -- */ -- --#include --#include --#include --#include --#include --#include --#include -- --#define MAX_STACK_FRAME 102400 -- --void --grub_backtrace_pointer (int frame) --{ -- while (1) -- { -- void *lp = __builtin_return_address (frame); -- if (!lp) -- break; -- -- lp = __builtin_extract_return_addr (lp); -- -- grub_printf ("%p: ", lp); -- grub_backtrace_print_address (lp); -- grub_printf (" ("); -- for (i = 0; i < 2; i++) -- grub_printf ("%p,", ((void **)ptr) [i + 2]); -- grub_printf ("%p)\n", ((void **)ptr) [i + 2]); -- nptr = *(void **)ptr; -- if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME -- || nptr == ptr) -- { -- grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); -- break; -- } -- ptr = nptr; -- } --} -- --void --grub_backtrace (void) --{ -- grub_backtrace_pointer (1); --} -- -diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c -deleted file mode 100644 -index c67273db3ae..00000000000 ---- a/grub-core/lib/i386/backtrace.c -+++ /dev/null -@@ -1,78 +0,0 @@ --/* -- * GRUB -- GRand Unified Bootloader -- * Copyright (C) 2009 Free Software Foundation, Inc. -- * -- * GRUB is free software: you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation, either version 3 of the License, or -- * (at your option) any later version. -- * -- * GRUB is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with GRUB. If not, see . -- */ --#include --#ifdef GRUB_UTIL --#define REALLY_GRUB_UTIL GRUB_UTIL --#undef GRUB_UTIL --#endif -- --#include --#include -- --#ifdef REALLY_GRUB_UTIL --#define GRUB_UTIL REALLY_GRUB_UTIL --#undef REALLY_GRUB_UTIL --#endif -- --#include --#include --#include --#include --#include --#include -- --#define MAX_STACK_FRAME 102400 -- --void --grub_backtrace_pointer (void *ebp) --{ -- void *ptr, *nptr; -- unsigned i; -- -- ptr = ebp; -- while (1) -- { -- grub_printf ("%p: ", ptr); -- grub_backtrace_print_address (((void **) ptr)[1]); -- grub_printf (" ("); -- for (i = 0; i < 2; i++) -- grub_printf ("%p,", ((void **)ptr) [i + 2]); -- grub_printf ("%p)\n", ((void **)ptr) [i + 2]); -- nptr = *(void **)ptr; -- if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME -- || nptr == ptr) -- { -- grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); -- break; -- } -- ptr = nptr; -- } --} -- --void --grub_backtrace (void) --{ --#ifdef __x86_64__ -- asm volatile ("movq %%rbp, %%rdi\n" -- "callq *%%rax": :"a"(grub_backtrace_pointer)); --#else -- asm volatile ("movl %%ebp, %%eax\n" -- "calll *%%ecx": :"c"(grub_backtrace_pointer)); --#endif --} -- -diff --git a/include/grub/backtrace.h b/include/grub/backtrace.h -index 395519762f0..275cf85e2d3 100644 ---- a/include/grub/backtrace.h -+++ b/include/grub/backtrace.h -@@ -19,8 +19,14 @@ - #ifndef GRUB_BACKTRACE_HEADER - #define GRUB_BACKTRACE_HEADER 1 - --void grub_backtrace (void); --void grub_backtrace_pointer (void *ptr); -+#include -+#include -+ -+void EXPORT_FUNC(grub_debug_backtrace) (const char * const debug, -+ unsigned int skip); -+void EXPORT_FUNC(grub_backtrace) (unsigned int skip); -+void grub_backtrace_arch (unsigned int skip); -+void grub_backtrace_pointer (void *ptr, unsigned int skip); - void grub_backtrace_print_address (void *addr); - - #endif -diff --git a/include/grub/dl.h b/include/grub/dl.h -index 91933b85f2c..2f76e6b0437 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -259,6 +259,8 @@ grub_dl_is_persistent (grub_dl_t mod) - - #endif - -+void * EXPORT_FUNC(grub_resolve_symbol) (const char *name); -+const char * EXPORT_FUNC(grub_get_symbol_by_addr) (const void *addr, int isfunc); - grub_err_t grub_dl_register_symbol (const char *name, void *addr, - int isfunc, grub_dl_t mod); - -diff --git a/include/grub/kernel.h b/include/grub/kernel.h -index abbca5ea335..300a9766cda 100644 ---- a/include/grub/kernel.h -+++ b/include/grub/kernel.h -@@ -111,6 +111,9 @@ grub_addr_t grub_modules_get_end (void); - - #endif - -+void EXPORT_FUNC(start) (void); -+void EXPORT_FUNC(_start) (void); -+ - /* The start point of the C code. */ - void grub_main (void) __attribute__ ((noreturn)); - -diff --git a/grub-core/kern/arm/efi/startup.S b/grub-core/kern/arm/efi/startup.S -index 9f8265315a9..f3bc41f9d0f 100644 ---- a/grub-core/kern/arm/efi/startup.S -+++ b/grub-core/kern/arm/efi/startup.S -@@ -23,6 +23,8 @@ - .file "startup.S" - .text - .arm -+ .globl start, _start -+FUNCTION(start) - FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in r1/r0. -diff --git a/grub-core/kern/arm/startup.S b/grub-core/kern/arm/startup.S -index 3946fe8e183..5679a1d00ad 100644 ---- a/grub-core/kern/arm/startup.S -+++ b/grub-core/kern/arm/startup.S -@@ -48,6 +48,8 @@ - - .text - .arm -+ .globl start, _start -+FUNCTION(start) - FUNCTION(_start) - b codestart - -diff --git a/grub-core/kern/arm64/efi/startup.S b/grub-core/kern/arm64/efi/startup.S -index 666a7ee3c92..41676bdb2b8 100644 ---- a/grub-core/kern/arm64/efi/startup.S -+++ b/grub-core/kern/arm64/efi/startup.S -@@ -19,7 +19,9 @@ - #include - - .file "startup.S" -+ .globl start, _start - .text -+FUNCTION(start) - FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in x1/x0. -diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S -index 0d89858d9b3..939f182fc74 100644 ---- a/grub-core/kern/i386/qemu/startup.S -+++ b/grub-core/kern/i386/qemu/startup.S -@@ -24,7 +24,8 @@ - - .text - .code32 -- .globl _start -+ .globl start, _start -+start: - _start: - jmp codestart - -diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S -index d75c6d7cc74..8f2a593e529 100644 ---- a/grub-core/kern/ia64/efi/startup.S -+++ b/grub-core/kern/ia64/efi/startup.S -@@ -24,8 +24,9 @@ - .psr lsb - .lsb - -- .global _start -+ .global start, _start - .proc _start -+start: - _start: - alloc loc0=ar.pfs,2,4,0,0 - mov loc1=rp -diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S -index 03b916f0534..701bf63abcf 100644 ---- a/grub-core/kern/sparc64/ieee1275/crt0.S -+++ b/grub-core/kern/sparc64/ieee1275/crt0.S -@@ -22,7 +22,8 @@ - - .text - .align 4 -- .globl _start -+ .globl start, _start -+start: - _start: - ba codestart - mov %o4, %o0 -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index 80e7a83edf9..f512573c0da 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -66,6 +66,7 @@ CLEANFILES += grub_script.yy.c grub_script.yy.h - - include $(srcdir)/Makefile.core.am - -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/backtrace.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h diff --git a/0066-normal-don-t-draw-our-startup-message-if-debug-is-se.patch b/0066-normal-don-t-draw-our-startup-message-if-debug-is-se.patch deleted file mode 100644 index 9ebfc7a..0000000 --- a/0066-normal-don-t-draw-our-startup-message-if-debug-is-se.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 9 Nov 2017 15:58:52 -0500 -Subject: [PATCH] normal: don't draw our startup message if debug is set - ---- - grub-core/normal/main.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index d5df4f815b0..1970e4816a8 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -430,6 +430,9 @@ grub_normal_reader_init (int nested) - const char *msg_esc = _("ESC at any time exits."); - char *msg_formatted; - -+ if (grub_env_get ("debug") != NULL) -+ return 0; -+ - msg_formatted = grub_xasprintf (_("Minimal BASH-like line editing is supported. For " - "the first word, TAB lists possible command completions. Anywhere " - "else TAB lists possible device or file completions. %s"), diff --git a/0067-Work-around-some-minor-include-path-weirdnesses.patch b/0067-Work-around-some-minor-include-path-weirdnesses.patch deleted file mode 100644 index 460d792..0000000 --- a/0067-Work-around-some-minor-include-path-weirdnesses.patch +++ /dev/null @@ -1,137 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 16 Mar 2018 13:28:57 -0400 -Subject: [PATCH] Work around some minor include path weirdnesses - -Signed-off-by: Peter Jones ---- - include/grub/arm/efi/console.h | 24 ++++++++++++++++++++++++ - include/grub/arm64/efi/console.h | 24 ++++++++++++++++++++++++ - include/grub/i386/efi/console.h | 24 ++++++++++++++++++++++++ - include/grub/x86_64/efi/console.h | 24 ++++++++++++++++++++++++ - 4 files changed, 96 insertions(+) - create mode 100644 include/grub/arm/efi/console.h - create mode 100644 include/grub/arm64/efi/console.h - create mode 100644 include/grub/i386/efi/console.h - create mode 100644 include/grub/x86_64/efi/console.h - -diff --git a/include/grub/arm/efi/console.h b/include/grub/arm/efi/console.h -new file mode 100644 -index 00000000000..1592f6f76b5 ---- /dev/null -+++ b/include/grub/arm/efi/console.h -@@ -0,0 +1,24 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_ARM_EFI_CONSOLE_H -+#define GRUB_ARM_EFI_CONSOLE_H -+ -+#include -+ -+#endif /* ! GRUB_ARM_EFI_CONSOLE_H */ -diff --git a/include/grub/arm64/efi/console.h b/include/grub/arm64/efi/console.h -new file mode 100644 -index 00000000000..95689339384 ---- /dev/null -+++ b/include/grub/arm64/efi/console.h -@@ -0,0 +1,24 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_ARM64_EFI_CONSOLE_H -+#define GRUB_ARM64_EFI_CONSOLE_H -+ -+#include -+ -+#endif /* ! GRUB_ARM64_EFI_CONSOLE_H */ -diff --git a/include/grub/i386/efi/console.h b/include/grub/i386/efi/console.h -new file mode 100644 -index 00000000000..9231375cb07 ---- /dev/null -+++ b/include/grub/i386/efi/console.h -@@ -0,0 +1,24 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_I386_EFI_CONSOLE_H -+#define GRUB_I386_EFI_CONSOLE_H -+ -+#include -+ -+#endif /* ! GRUB_I386_EFI_CONSOLE_H */ -diff --git a/include/grub/x86_64/efi/console.h b/include/grub/x86_64/efi/console.h -new file mode 100644 -index 00000000000..dba9d8678d0 ---- /dev/null -+++ b/include/grub/x86_64/efi/console.h -@@ -0,0 +1,24 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_X86_64_EFI_CONSOLE_H -+#define GRUB_X86_64_EFI_CONSOLE_H -+ -+#include -+ -+#endif /* ! GRUB_X86_64_EFI_CONSOLE_H */ diff --git a/0068-Make-it-possible-to-enabled-build-id-sha1.patch b/0068-Make-it-possible-to-enabled-build-id-sha1.patch deleted file mode 100644 index f68fc58..0000000 --- a/0068-Make-it-possible-to-enabled-build-id-sha1.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 25 Jun 2015 15:41:06 -0400 -Subject: [PATCH] Make it possible to enabled --build-id=sha1 - -Signed-off-by: Peter Jones ---- - configure.ac | 8 ++++++++ - acinclude.m4 | 19 +++++++++++++++++++ - 2 files changed, 27 insertions(+) - -diff --git a/configure.ac b/configure.ac -index a0030632220..b50fb2e9897 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1470,7 +1470,15 @@ grub_PROG_TARGET_CC - if test "x$TARGET_APPLE_LINKER" != x1 ; then - grub_PROG_OBJCOPY_ABSOLUTE - fi -+ -+AC_ARG_ENABLE([build-id], -+ [AS_HELP_STRING([--enable-build-id], -+ [ask the linker to supply build-id notes (default=no)])]) -+if test x$enable_build_id = xyes; then -+grub_PROG_LD_BUILD_ID_SHA1 -+else - grub_PROG_LD_BUILD_ID_NONE -+fi - if test "x$target_cpu" = xi386; then - if test "$platform" != emu && test "x$TARGET_APPLE_LINKER" != x1 ; then - if test ! -z "$TARGET_IMG_LDSCRIPT"; then -diff --git a/acinclude.m4 b/acinclude.m4 -index 6e14bb553c6..21238fcfd03 100644 ---- a/acinclude.m4 -+++ b/acinclude.m4 -@@ -136,6 +136,25 @@ if test "x$grub_cv_prog_ld_build_id_none" = xyes; then - fi - ]) - -+dnl Supply --build-id=sha1 to ld if building modules. -+dnl This suppresses warnings from ld on some systems -+AC_DEFUN([grub_PROG_LD_BUILD_ID_SHA1], -+[AC_MSG_CHECKING([whether linker accepts --build-id=sha1]) -+AC_CACHE_VAL(grub_cv_prog_ld_build_id_sha1, -+[save_LDFLAGS="$LDFLAGS" -+LDFLAGS="$LDFLAGS -Wl,--build-id=sha1" -+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], -+ [grub_cv_prog_ld_build_id_sha1=yes], -+ [grub_cv_prog_ld_build_id_sha1=no]) -+LDFLAGS="$save_LDFLAGS" -+]) -+AC_MSG_RESULT([$grub_cv_prog_ld_build_id_sha1]) -+ -+if test "x$grub_cv_prog_ld_build_id_sha1" = xyes; then -+ TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,--build-id=sha1" -+fi -+]) -+ - dnl Check nm - AC_DEFUN([grub_PROG_NM_WORKS], - [AC_MSG_CHECKING([whether nm works]) diff --git a/0069-Add-grub_qdprintf-grub_dprintf-without-the-file-line.patch b/0069-Add-grub_qdprintf-grub_dprintf-without-the-file-line.patch deleted file mode 100644 index a8a757e..0000000 --- a/0069-Add-grub_qdprintf-grub_dprintf-without-the-file-line.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sun, 28 Jun 2015 13:09:58 -0400 -Subject: [PATCH] Add grub_qdprintf() - grub_dprintf() without the file+line - number. - -This just makes copy+paste of our debug loading info easier. - -Signed-off-by: Peter Jones ---- - grub-core/kern/misc.c | 18 ++++++++++++++++++ - include/grub/misc.h | 2 ++ - 2 files changed, 20 insertions(+) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index a432a6be54a..9a2fae6398e 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -191,6 +191,24 @@ grub_real_dprintf (const char *file, const int line, const char *condition, - } - } - -+void -+grub_qdprintf (const char *condition, const char *fmt, ...) -+{ -+ va_list args; -+ const char *debug = grub_env_get ("debug"); -+ -+ if (! debug) -+ return; -+ -+ if (grub_strword (debug, "all") || grub_strword (debug, condition)) -+ { -+ va_start (args, fmt); -+ grub_vprintf (fmt, args); -+ va_end (args); -+ grub_refresh (); -+ } -+} -+ - #define PREALLOC_SIZE 255 - - int -diff --git a/include/grub/misc.h b/include/grub/misc.h -index fd18e6320b8..3adc4036e3b 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -345,6 +345,8 @@ void EXPORT_FUNC(grub_real_dprintf) (const char *file, - const int line, - const char *condition, - const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5))); -+void EXPORT_FUNC(grub_qdprintf) (const char *condition, -+ const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 2, 3))); - int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args); - int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) - __attribute__ ((format (GNU_PRINTF, 3, 4))); diff --git a/0070-Make-a-gdb-dprintf-that-tells-us-load-addresses.patch b/0070-Make-a-gdb-dprintf-that-tells-us-load-addresses.patch deleted file mode 100644 index 75de764..0000000 --- a/0070-Make-a-gdb-dprintf-that-tells-us-load-addresses.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 25 Jun 2015 15:11:36 -0400 -Subject: [PATCH] Make a "gdb" dprintf that tells us load addresses. - -This makes a grub_dprintf() call during platform init and during module -loading that tells us the virtual addresses of the .text and .data -sections of grub-core/kernel.exec and any modules it loads. - -Specifically, it displays them in the gdb "add-symbol-file" syntax, with -the presumption that there's a variable $grubdir that reflects the path -to any such binaries. - -Signed-off-by: Peter Jones ---- - grub-core/kern/dl.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ - grub-core/kern/efi/efi.c | 4 ++-- - grub-core/kern/efi/init.c | 26 +++++++++++++++++++++++- - include/grub/efi/efi.h | 2 +- - 4 files changed, 78 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 88d2077709e..9557254035e 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -501,6 +501,23 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name) - return s; - return NULL; - } -+static long -+grub_dl_find_section_index (Elf_Ehdr *e, const char *name) -+{ -+ Elf_Shdr *s; -+ const char *str; -+ unsigned i; -+ -+ s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); -+ str = (char *) e + s->sh_offset; -+ -+ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); -+ i < e->e_shnum; -+ i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) -+ if (grub_strcmp (str + s->sh_name, name) == 0) -+ return (long)i; -+ return -1; -+} - - /* Me, Vladimir Serbinenko, hereby I add this module check as per new - GNU module policy. Note that this license check is informative only. -@@ -653,6 +670,37 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) - - return GRUB_ERR_NONE; - } -+static void -+grub_dl_print_gdb_info (grub_dl_t mod, Elf_Ehdr *e) -+{ -+ void *text, *data = NULL; -+ long idx; -+ -+ idx = grub_dl_find_section_index (e, ".text"); -+ if (idx < 0) -+ return; -+ -+ text = grub_dl_get_section_addr (mod, idx); -+ if (!text) -+ return; -+ -+ idx = grub_dl_find_section_index (e, ".data"); -+ if (idx >= 0) -+ data = grub_dl_get_section_addr (mod, idx); -+ -+ if (data) -+ grub_qdprintf ("gdb", "add-symbol-file \\\n" -+ "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug " -+ "\\\n %p -s .data %p\n", -+ GRUB_TARGET_CPU, GRUB_PLATFORM, -+ mod->name, text, data); -+ else -+ grub_qdprintf ("gdb", "add-symbol-file \\\n" -+ "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug " -+ "\\\n%p\n", -+ GRUB_TARGET_CPU, GRUB_PLATFORM, -+ mod->name, text); -+} - - /* Load a module from core memory. */ - grub_dl_t -@@ -712,6 +760,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) - grub_dprintf ("modules", "module name: %s\n", mod->name); - grub_dprintf ("modules", "init function: %p\n", mod->init); - -+ grub_dl_print_gdb_info (mod, e); -+ - if (grub_dl_add (mod)) - { - grub_dl_unload (mod); -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index ae9885edb84..d6a2fb57789 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -296,7 +296,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, - /* Search the mods section from the PE32/PE32+ image. This code uses - a PE32 header, but should work with PE32+ as well. */ - grub_addr_t --grub_efi_modules_addr (void) -+grub_efi_section_addr (const char *section_name) - { - grub_efi_loaded_image_t *image; - struct grub_pe32_header *header; -@@ -321,7 +321,7 @@ grub_efi_modules_addr (void) - i < coff_header->num_sections; - i++, section++) - { -- if (grub_strcmp (section->name, "mods") == 0) -+ if (grub_strcmp (section->name, section_name) == 0) - break; - } - -diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c -index 6d39bd3ad29..2d12e6188fd 100644 ---- a/grub-core/kern/efi/init.c -+++ b/grub-core/kern/efi/init.c -@@ -115,10 +115,33 @@ grub_efi_env_init (void) - grub_free (envblk_s.buf); - } - -+static void -+grub_efi_print_gdb_info (void) -+{ -+ grub_addr_t text; -+ grub_addr_t data; -+ -+ text = grub_efi_section_addr (".text"); -+ if (!text) -+ return; -+ -+ data = grub_efi_section_addr (".data"); -+ if (data) -+ grub_qdprintf ("gdb", -+ "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/" -+ "kernel.exec %p -s .data %p\n", -+ GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text, (void *)data); -+ else -+ grub_qdprintf ("gdb", -+ "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/" -+ "kernel.exec %p\n", -+ GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text); -+} -+ - void - grub_efi_init (void) - { -- grub_modbase = grub_efi_modules_addr (); -+ grub_modbase = grub_efi_section_addr ("mods"); - /* First of all, initialize the console so that GRUB can display - messages. */ - grub_console_init (); -@@ -142,6 +165,7 @@ grub_efi_init (void) - 0, 0, 0, NULL); - - grub_efi_env_init (); -+ grub_efi_print_gdb_info (); - grub_efidisk_init (); - } - -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 03f9a9d0118..2e0691454b1 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -138,7 +138,7 @@ grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); - grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args); - #endif - --grub_addr_t grub_efi_modules_addr (void); -+grub_addr_t grub_efi_section_addr (const char *section); - - void grub_efi_mm_init (void); - void grub_efi_mm_fini (void); diff --git a/0071-Fixup-for-newer-compiler.patch b/0071-Fixup-for-newer-compiler.patch deleted file mode 100644 index 12dd193..0000000 --- a/0071-Fixup-for-newer-compiler.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 10 May 2018 13:40:19 -0400 -Subject: [PATCH] Fixup for newer compiler - ---- - grub-core/fs/btrfs.c | 2 +- - include/grub/gpt_partition.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 2b21cbaa67e..4cc86e9b79e 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -218,7 +218,7 @@ struct grub_btrfs_inode - grub_uint64_t size; - grub_uint8_t dummy2[0x70]; - struct grub_btrfs_time mtime; --} GRUB_PACKED; -+} GRUB_PACKED __attribute__ ((aligned(8))); - - struct grub_btrfs_extent_data - { -diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h -index 7a93f43291c..8212697bf6b 100644 ---- a/include/grub/gpt_partition.h -+++ b/include/grub/gpt_partition.h -@@ -76,7 +76,7 @@ struct grub_gpt_partentry - grub_uint64_t end; - grub_uint64_t attrib; - char name[72]; --} GRUB_PACKED; -+} GRUB_PACKED __attribute__ ((aligned(8))); - - grub_err_t - grub_gpt_partition_map_iterate (grub_disk_t disk, diff --git a/0072-Don-t-attempt-to-export-the-start-and-_start-symbols.patch b/0072-Don-t-attempt-to-export-the-start-and-_start-symbols.patch deleted file mode 100644 index 0e925ee..0000000 --- a/0072-Don-t-attempt-to-export-the-start-and-_start-symbols.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Sat, 12 May 2018 11:29:07 +0200 -Subject: [PATCH] Don't attempt to export the start and _start symbols for - grub-emu - -Commit 318ee04aadc ("make better backtraces") reworked the backtrace logic -but the changes lead to the following build error on the grub-emu platform: - -grub_emu_lite-symlist.o:(.data+0xf08): undefined reference to `start' -collect2: error: ld returned 1 exit status -make[3]: *** [Makefile:25959: grub-emu-lite] Error 1 -make[3]: *** Waiting for unfinished jobs.... -cat kernel_syms.input | grep -v '^#' | sed -n \ - -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '""'\1/;p;}' \ - -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '""'\1/;p;}' \ - | sort -u >kernel_syms.lst - -The problem is that start and _start symbols are exported unconditionally, -but these aren't defined for grub-emu since is an emultaed platform so it -doesn't have a startup logic. Don't attempt to export those for grub-emu. - -Signed-off-by: Javier Martinez Canillas ---- - include/grub/kernel.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/include/grub/kernel.h b/include/grub/kernel.h -index 300a9766cda..55849777eaa 100644 ---- a/include/grub/kernel.h -+++ b/include/grub/kernel.h -@@ -111,8 +111,10 @@ grub_addr_t grub_modules_get_end (void); - - #endif - -+#if !defined(GRUB_MACHINE_EMU) - void EXPORT_FUNC(start) (void); - void EXPORT_FUNC(_start) (void); -+#endif - - /* The start point of the C code. */ - void grub_main (void) __attribute__ ((noreturn)); diff --git a/0073-Fixup-for-newer-compiler.patch b/0073-Fixup-for-newer-compiler.patch deleted file mode 100644 index 11ed6e5..0000000 --- a/0073-Fixup-for-newer-compiler.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 10 May 2018 13:40:19 -0400 -Subject: [PATCH] Fixup for newer compiler - ---- - conf/Makefile.common | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 191b1a70c6b..5f0ef969857 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -38,7 +38,7 @@ CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding - LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) - CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 - CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) --STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -+STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -R .note.gnu.property -R .gnu.build.attributes - - CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding - LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d diff --git a/0074-Add-support-for-non-Ethernet-network-cards.patch b/0074-Add-support-for-non-Ethernet-network-cards.patch deleted file mode 100644 index 02fb951..0000000 --- a/0074-Add-support-for-non-Ethernet-network-cards.patch +++ /dev/null @@ -1,766 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Andrzej Kacprowski -Date: Wed, 10 Jul 2019 15:22:29 +0200 -Subject: [PATCH] Add support for non-Ethernet network cards - -This patch replaces fixed 6-byte link layer address with -up to 32-byte variable sized address. -This allows supporting Infiniband and Omni-Path fabric -which use 20-byte address, but other network card types -can also take advantage of this change. -The network card driver is responsible for replacing L2 -header provided by grub2 if needed. -This approach is compatible with UEFI network stack which -also allows up to 32-byte variable size link address. - -The BOOTP/DHCP packet format is limited to 16 byte client -hardware address, if link address is more that 16-bytes -then chaddr field in BOOTP it will be set to 0 as per rfc4390. - -Resolves: rhbz#1370642 - -Signed-off-by: Andrzej Kacprowski -[msalter: Fix max string calculation in grub_net_hwaddr_to_str] -Signed-off-by: Mark Salter ---- - grub-core/net/arp.c | 155 ++++++++++++++++++++++----------- - grub-core/net/bootp.c | 15 ++-- - grub-core/net/drivers/efi/efinet.c | 8 +- - grub-core/net/drivers/emu/emunet.c | 1 + - grub-core/net/drivers/i386/pc/pxe.c | 13 +-- - grub-core/net/drivers/ieee1275/ofnet.c | 2 + - grub-core/net/drivers/uboot/ubootnet.c | 1 + - grub-core/net/ethernet.c | 88 +++++++++---------- - grub-core/net/icmp6.c | 15 ++-- - grub-core/net/ip.c | 4 +- - grub-core/net/net.c | 50 ++++++----- - include/grub/net.h | 19 ++-- - 12 files changed, 219 insertions(+), 152 deletions(-) - -diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c -index 54306e3b16d..67b409a8acc 100644 ---- a/grub-core/net/arp.c -+++ b/grub-core/net/arp.c -@@ -31,22 +31,12 @@ enum - ARP_REPLY = 2 - }; - --enum -- { -- /* IANA ARP constant to define hardware type as ethernet. */ -- GRUB_NET_ARPHRD_ETHERNET = 1 -- }; -- --struct arppkt { -+struct arphdr { - grub_uint16_t hrd; - grub_uint16_t pro; - grub_uint8_t hln; - grub_uint8_t pln; - grub_uint16_t op; -- grub_uint8_t sender_mac[6]; -- grub_uint32_t sender_ip; -- grub_uint8_t recv_mac[6]; -- grub_uint32_t recv_ip; - } GRUB_PACKED; - - static int have_pending; -@@ -57,12 +47,16 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr) - { - struct grub_net_buff nb; -- struct arppkt *arp_packet; -+ struct arphdr *arp_header; - grub_net_link_level_address_t target_mac_addr; - grub_err_t err; - int i; - grub_uint8_t *nbd; - grub_uint8_t arp_data[128]; -+ grub_uint8_t hln; -+ grub_uint8_t pln; -+ grub_uint8_t arp_packet_len; -+ grub_uint8_t *tmp_ptr; - - if (proto_addr->type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4) - return grub_error (GRUB_ERR_BUG, "unsupported address family"); -@@ -73,23 +67,39 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf, - grub_netbuff_clear (&nb); - grub_netbuff_reserve (&nb, 128); - -- err = grub_netbuff_push (&nb, sizeof (*arp_packet)); -+ hln = inf->card->default_address.len; -+ pln = sizeof (proto_addr->ipv4); -+ arp_packet_len = sizeof (*arp_header) + 2 * (hln + pln); -+ -+ err = grub_netbuff_push (&nb, arp_packet_len); - if (err) - return err; - -- arp_packet = (struct arppkt *) nb.data; -- arp_packet->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET); -- arp_packet->hln = 6; -- arp_packet->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); -- arp_packet->pln = 4; -- arp_packet->op = grub_cpu_to_be16_compile_time (ARP_REQUEST); -- /* Sender hardware address. */ -- grub_memcpy (arp_packet->sender_mac, &inf->hwaddress.mac, 6); -- arp_packet->sender_ip = inf->address.ipv4; -- grub_memset (arp_packet->recv_mac, 0, 6); -- arp_packet->recv_ip = proto_addr->ipv4; -- /* Target protocol address */ -- grub_memset (&target_mac_addr.mac, 0xff, 6); -+ arp_header = (struct arphdr *) nb.data; -+ arp_header->hrd = grub_cpu_to_be16 (inf->card->default_address.type); -+ arp_header->hln = hln; -+ arp_header->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); -+ arp_header->pln = pln; -+ arp_header->op = grub_cpu_to_be16_compile_time (ARP_REQUEST); -+ tmp_ptr = nb.data + sizeof (*arp_header); -+ -+ /* The source hardware address. */ -+ grub_memcpy (tmp_ptr, inf->hwaddress.mac, hln); -+ tmp_ptr += hln; -+ -+ /* The source protocol address. */ -+ grub_memcpy (tmp_ptr, &inf->address.ipv4, pln); -+ tmp_ptr += pln; -+ -+ /* The target hardware address. */ -+ grub_memset (tmp_ptr, 0, hln); -+ tmp_ptr += hln; -+ -+ /* The target protocol address */ -+ grub_memcpy (tmp_ptr, &proto_addr->ipv4, pln); -+ tmp_ptr += pln; -+ -+ grub_memset (&target_mac_addr.mac, 0xff, hln); - - nbd = nb.data; - send_ethernet_packet (inf, &nb, target_mac_addr, GRUB_NET_ETHERTYPE_ARP); -@@ -114,28 +124,53 @@ grub_err_t - grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, - grub_uint16_t *vlantag) - { -- struct arppkt *arp_packet = (struct arppkt *) nb->data; -+ struct arphdr *arp_header = (struct arphdr *) nb->data; - grub_net_network_level_address_t sender_addr, target_addr; - grub_net_link_level_address_t sender_mac_addr; - struct grub_net_network_level_interface *inf; -+ grub_uint16_t hw_type; -+ grub_uint8_t hln; -+ grub_uint8_t pln; -+ grub_uint8_t arp_packet_len; -+ grub_uint8_t *tmp_ptr; - -- if (arp_packet->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP) -- || arp_packet->pln != 4 || arp_packet->hln != 6 -- || nb->tail - nb->data < (int) sizeof (*arp_packet)) -+ hw_type = card->default_address.type; -+ hln = card->default_address.len; -+ pln = sizeof(sender_addr.ipv4); -+ arp_packet_len = sizeof (*arp_header) + 2 * (pln + hln); -+ -+ if (arp_header->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP) -+ || arp_header->hrd != grub_cpu_to_be16 (hw_type) -+ || arp_header->hln != hln || arp_header->pln != pln -+ || nb->tail - nb->data < (int) arp_packet_len) { - return GRUB_ERR_NONE; -+ } - -+ tmp_ptr = nb->data + sizeof (*arp_header); -+ -+ /* The source hardware address. */ -+ sender_mac_addr.type = hw_type; -+ sender_mac_addr.len = hln; -+ grub_memcpy (sender_mac_addr.mac, tmp_ptr, hln); -+ tmp_ptr += hln; -+ -+ /* The source protocol address. */ - sender_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; -+ grub_memcpy(&sender_addr.ipv4, tmp_ptr, pln); -+ tmp_ptr += pln; -+ -+ grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1); -+ -+ /* The target hardware address. */ -+ tmp_ptr += hln; -+ -+ /* The target protocol address. */ - target_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; -- sender_addr.ipv4 = arp_packet->sender_ip; -- target_addr.ipv4 = arp_packet->recv_ip; -- if (arp_packet->sender_ip == pending_req) -+ grub_memcpy(&target_addr.ipv4, tmp_ptr, pln); -+ -+ if (sender_addr.ipv4 == pending_req) - have_pending = 1; - -- sender_mac_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (sender_mac_addr.mac, arp_packet->sender_mac, -- sizeof (sender_mac_addr.mac)); -- grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1); -- - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - /* Verify vlantag id */ -@@ -148,11 +183,11 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, - - /* Am I the protocol address target? */ - if (grub_net_addr_cmp (&inf->address, &target_addr) == 0 -- && arp_packet->op == grub_cpu_to_be16_compile_time (ARP_REQUEST)) -+ && arp_header->op == grub_cpu_to_be16_compile_time (ARP_REQUEST)) - { - grub_net_link_level_address_t target; - struct grub_net_buff nb_reply; -- struct arppkt *arp_reply; -+ struct arphdr *arp_reply; - grub_uint8_t arp_data[128]; - grub_err_t err; - -@@ -161,25 +196,39 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, - grub_netbuff_clear (&nb_reply); - grub_netbuff_reserve (&nb_reply, 128); - -- err = grub_netbuff_push (&nb_reply, sizeof (*arp_packet)); -+ err = grub_netbuff_push (&nb_reply, arp_packet_len); - if (err) - return err; - -- arp_reply = (struct arppkt *) nb_reply.data; -+ arp_reply = (struct arphdr *) nb_reply.data; - -- arp_reply->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET); -+ arp_reply->hrd = grub_cpu_to_be16 (hw_type); - arp_reply->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); -- arp_reply->pln = 4; -- arp_reply->hln = 6; -+ arp_reply->pln = pln; -+ arp_reply->hln = hln; - arp_reply->op = grub_cpu_to_be16_compile_time (ARP_REPLY); -- arp_reply->sender_ip = arp_packet->recv_ip; -- arp_reply->recv_ip = arp_packet->sender_ip; -- arp_reply->hln = 6; -- -- target.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (target.mac, arp_packet->sender_mac, 6); -- grub_memcpy (arp_reply->sender_mac, inf->hwaddress.mac, 6); -- grub_memcpy (arp_reply->recv_mac, arp_packet->sender_mac, 6); -+ -+ tmp_ptr = nb_reply.data + sizeof (*arp_reply); -+ -+ /* The source hardware address. */ -+ grub_memcpy (tmp_ptr, inf->hwaddress.mac, hln); -+ tmp_ptr += hln; -+ -+ /* The source protocol address. */ -+ grub_memcpy (tmp_ptr, &target_addr.ipv4, pln); -+ tmp_ptr += pln; -+ -+ /* The target hardware address. */ -+ grub_memcpy (tmp_ptr, sender_mac_addr.mac, hln); -+ tmp_ptr += hln; -+ -+ /* The target protocol address */ -+ grub_memcpy (tmp_ptr, &sender_addr.ipv4, pln); -+ tmp_ptr += pln; -+ -+ target.type = hw_type; -+ target.len = hln; -+ grub_memcpy (target.mac, sender_mac_addr.mac, hln); - - /* Change operation to REPLY and send packet */ - send_ethernet_packet (inf, &nb_reply, target, GRUB_NET_ETHERTYPE_ARP); -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index e28fb6a09f9..08b6b2b5d6c 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -233,7 +233,6 @@ grub_net_configure_by_dhcp_ack (const char *name, - int is_def, char **device, char **path) - { - grub_net_network_level_address_t addr; -- grub_net_link_level_address_t hwaddr; - struct grub_net_network_level_interface *inter; - int mask = -1; - char server_ip[sizeof ("xxx.xxx.xxx.xxx")]; -@@ -250,12 +249,8 @@ grub_net_configure_by_dhcp_ack (const char *name, - if (path) - *path = 0; - -- grub_memcpy (hwaddr.mac, bp->mac_addr, -- bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len -- : sizeof (hwaddr.mac)); -- hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- -- inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags); -+ grub_dprintf("dhcp", "configuring dhcp for %s\n", name); -+ inter = grub_net_add_addr (name, card, &addr, &card->default_address, flags); - if (!inter) - return 0; - -@@ -567,7 +562,9 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) - grub_memset (pack, 0, sizeof (*pack)); - pack->opcode = 1; - pack->hw_type = 1; -- pack->hw_len = 6; -+ pack->hw_len = iface->hwaddress.len > 16 ? 0 -+ : iface->hwaddress.len; -+ - err = grub_get_datetime (&date); - if (err || !grub_datetime2unixtime (&date, &t)) - { -@@ -580,7 +577,7 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) - else - pack->ident = iface->xid; - -- grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6); -+ grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, pack->hw_len); - - grub_netbuff_push (nb, sizeof (*udph)); - -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 173fb63153c..a673bea807a 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -279,6 +279,9 @@ grub_efinet_findcards (void) - /* This should not happen... Why? */ - continue; - -+ if (net->mode->hwaddr_size > GRUB_NET_MAX_LINK_ADDRESS_SIZE) -+ continue; -+ - if (net->mode->state == GRUB_EFI_NETWORK_STOPPED - && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) - continue; -@@ -315,10 +318,11 @@ grub_efinet_findcards (void) - card->name = grub_xasprintf ("efinet%d", i++); - card->driver = &efidriver; - card->flags = 0; -- card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ card->default_address.type = net->mode->if_type; -+ card->default_address.len = net->mode->hwaddr_size; - grub_memcpy (card->default_address.mac, - net->mode->current_address, -- sizeof (card->default_address.mac)); -+ net->mode->hwaddr_size); - card->efi_net = net; - card->efi_handle = *handle; - -diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c -index b194920861f..5b6c5e16a6d 100644 ---- a/grub-core/net/drivers/emu/emunet.c -+++ b/grub-core/net/drivers/emu/emunet.c -@@ -46,6 +46,7 @@ static struct grub_net_card emucard = - .mtu = 1500, - .default_address = { - .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, -+ . len = 6, - {.mac = {0, 1, 2, 3, 4, 5}} - }, - .flags = 0 -diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c -index 3f4152d036c..9f8fb4b6d2b 100644 ---- a/grub-core/net/drivers/i386/pc/pxe.c -+++ b/grub-core/net/drivers/i386/pc/pxe.c -@@ -386,20 +386,21 @@ GRUB_MOD_INIT(pxe) - grub_memset (ui, 0, sizeof (*ui)); - grub_pxe_call (GRUB_PXENV_UNDI_GET_INFORMATION, ui, pxe_rm_entry); - -+ grub_pxe_card.default_address.len = 6; - grub_memcpy (grub_pxe_card.default_address.mac, ui->current_addr, -- sizeof (grub_pxe_card.default_address.mac)); -- for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) -+ grub_pxe_card.default_address.len); -+ for (i = 0; i < grub_pxe_card.default_address.len; i++) - if (grub_pxe_card.default_address.mac[i] != 0) - break; -- if (i != sizeof (grub_pxe_card.default_address.mac)) -+ if (i != grub_pxe_card.default_address.len) - { -- for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) -+ for (i = 0; i < grub_pxe_card.default_address.len; i++) - if (grub_pxe_card.default_address.mac[i] != 0xff) - break; - } -- if (i == sizeof (grub_pxe_card.default_address.mac)) -+ if (i == grub_pxe_card.default_address.len) - grub_memcpy (grub_pxe_card.default_address.mac, ui->permanent_addr, -- sizeof (grub_pxe_card.default_address.mac)); -+ grub_pxe_card.default_address.len); - grub_pxe_card.mtu = ui->mtu; - - grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c -index 3860b6f78d8..bcb3f9ea02d 100644 ---- a/grub-core/net/drivers/ieee1275/ofnet.c -+++ b/grub-core/net/drivers/ieee1275/ofnet.c -@@ -160,6 +160,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, - grub_uint16_t vlantag = 0; - - hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ hw_addr.len = 6; - - args = bootpath + grub_strlen (devpath) + 1; - do -@@ -503,6 +504,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias) - grub_memcpy (&lla.mac, pprop, 6); - - lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ lla.len = 6; - card->default_address = lla; - - card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; -diff --git a/grub-core/net/drivers/uboot/ubootnet.c b/grub-core/net/drivers/uboot/ubootnet.c -index 056052e40d5..22ebcbf211e 100644 ---- a/grub-core/net/drivers/uboot/ubootnet.c -+++ b/grub-core/net/drivers/uboot/ubootnet.c -@@ -131,6 +131,7 @@ GRUB_MOD_INIT (ubootnet) - - grub_memcpy (&(card->default_address.mac), &devinfo->di_net.hwaddr, 6); - card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ card->default_address.len = 6; - - card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; - card->txbuf = grub_zalloc (card->txbufsize); -diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c -index 4d7ceed6f93..9aae83a5eb4 100644 ---- a/grub-core/net/ethernet.c -+++ b/grub-core/net/ethernet.c -@@ -29,13 +29,6 @@ - - #define LLCADDRMASK 0x7f - --struct etherhdr --{ -- grub_uint8_t dst[6]; -- grub_uint8_t src[6]; -- grub_uint16_t type; --} GRUB_PACKED; -- - struct llchdr - { - grub_uint8_t dsap; -@@ -55,13 +48,15 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, - grub_net_link_level_address_t target_addr, - grub_net_ethertype_t ethertype) - { -- struct etherhdr *eth; -+ grub_uint8_t *eth; - grub_err_t err; -- grub_uint8_t etherhdr_size; -- grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER; -+ grub_uint32_t vlantag = 0; -+ grub_uint8_t hw_addr_len = inf->card->default_address.len; -+ grub_uint8_t etherhdr_size = 2 * hw_addr_len + 2; - -- etherhdr_size = sizeof (*eth); -- COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); -+ /* Source and destination link addresses + ethertype + vlan tag */ -+ COMPILE_TIME_ASSERT ((GRUB_NET_MAX_LINK_ADDRESS_SIZE * 2 + 2 + 4) < -+ GRUB_NET_MAX_LINK_HEADER_SIZE); - - /* Increase ethernet header in case of vlantag */ - if (inf->vlantag != 0) -@@ -70,11 +65,22 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, - err = grub_netbuff_push (nb, etherhdr_size); - if (err) - return err; -- eth = (struct etherhdr *) nb->data; -- grub_memcpy (eth->dst, target_addr.mac, 6); -- grub_memcpy (eth->src, inf->hwaddress.mac, 6); -+ eth = nb->data; -+ grub_memcpy (eth, target_addr.mac, hw_addr_len); -+ eth += hw_addr_len; -+ grub_memcpy (eth, inf->hwaddress.mac, hw_addr_len); -+ eth += hw_addr_len; -+ -+ /* Check if a vlan-tag is present. */ -+ if (vlantag != 0) -+ { -+ *((grub_uint32_t *)eth) = grub_cpu_to_be32 (vlantag); -+ eth += sizeof (vlantag); -+ } -+ -+ /* Write ethertype */ -+ *((grub_uint16_t*) eth) = grub_cpu_to_be16 (ethertype); - -- eth->type = grub_cpu_to_be16 (ethertype); - if (!inf->card->opened) - { - err = GRUB_ERR_NONE; -@@ -85,18 +91,6 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, - inf->card->opened = 1; - } - -- /* Check and add a vlan-tag if needed. */ -- if (inf->vlantag != 0) -- { -- /* Move eth type to the right */ -- grub_memcpy ((char *) nb->data + etherhdr_size - 2, -- (char *) nb->data + etherhdr_size - 6, 2); -- -- /* Add the tag in the middle */ -- grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2); -- grub_memcpy ((char *) nb->data + etherhdr_size - 4, (char *) &(inf->vlantag), 2); -- } -- - return inf->card->driver->send (inf->card, nb); - } - -@@ -104,31 +98,40 @@ grub_err_t - grub_net_recv_ethernet_packet (struct grub_net_buff *nb, - struct grub_net_card *card) - { -- struct etherhdr *eth; -+ grub_uint8_t *eth; - struct llchdr *llch; - struct snaphdr *snaph; - grub_net_ethertype_t type; - grub_net_link_level_address_t hwaddress; - grub_net_link_level_address_t src_hwaddress; - grub_err_t err; -- grub_uint8_t etherhdr_size = sizeof (*eth); -+ grub_uint8_t hw_addr_len = card->default_address.len; -+ grub_uint8_t etherhdr_size = 2 * hw_addr_len + 2; - grub_uint16_t vlantag = 0; - -+ eth = nb->data; - -- /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */ -- /* longer than the original one. The vlantag id is extracted and the header */ -- /* is reseted to the original size. */ -- if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == VLANTAG_IDENTIFIER) -+ hwaddress.type = card->default_address.type; -+ hwaddress.len = hw_addr_len; -+ grub_memcpy (hwaddress.mac, eth, hw_addr_len); -+ eth += hw_addr_len; -+ -+ src_hwaddress.type = card->default_address.type; -+ src_hwaddress.len = hw_addr_len; -+ grub_memcpy (src_hwaddress.mac, eth, hw_addr_len); -+ eth += hw_addr_len; -+ -+ type = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); -+ if (type == VLANTAG_IDENTIFIER) - { -- vlantag = grub_get_unaligned16 (nb->data + etherhdr_size); -+ /* Skip vlan tag */ -+ eth += 2; -+ vlantag = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); - etherhdr_size += 4; -- /* Move eth type to the original position */ -- grub_memcpy((char *) nb->data + etherhdr_size - 6, -- (char *) nb->data + etherhdr_size - 2, 2); -+ eth += 2; -+ type = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); - } - -- eth = (struct etherhdr *) nb->data; -- type = grub_be_to_cpu16 (eth->type); - err = grub_netbuff_pull (nb, etherhdr_size); - if (err) - return err; -@@ -148,11 +151,6 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, - } - } - -- hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac)); -- src_hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (src_hwaddress.mac, eth->src, sizeof (src_hwaddress.mac)); -- - switch (type) - { - /* ARP packet. */ -diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c -index 2cbd95dce25..56a3ec5c8e8 100644 ---- a/grub-core/net/icmp6.c -+++ b/grub-core/net/icmp6.c -@@ -231,8 +231,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; -- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); -+ ll_address.type = card->default_address.type; -+ ll_address.len = card->default_address.len; -+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - } -@@ -335,8 +336,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; -- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); -+ ll_address.type = card->default_address.type; -+ ll_address.len = card->default_address.len; -+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - } -@@ -384,8 +386,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; -- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); -+ ll_address.type = card->default_address.type; -+ ll_address.len = card->default_address.len; -+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - if (ohdr->type == OPTION_PREFIX && ohdr->len == 4) -diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c -index ea5edf8f1f6..a5896f6dc26 100644 ---- a/grub-core/net/ip.c -+++ b/grub-core/net/ip.c -@@ -276,8 +276,8 @@ handle_dgram (struct grub_net_buff *nb, - if (inf->card == card - && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV - && inf->hwaddress.type == GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET -- && grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr, -- sizeof (inf->hwaddress.mac)) == 0) -+ && (grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr, -+ bootp->hw_len) == 0 || bootp->hw_len == 0)) - { - grub_net_process_dhcp (nb, inf); - grub_netbuff_free (nb); -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 22f2689aaeb..a46f82362ed 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -133,8 +133,9 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, - << 48) - && proto_addr->ipv6[1] == (grub_be_to_cpu64_compile_time (1)))) - { -- hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memset (hw_addr->mac, -1, 6); -+ hw_addr->type = inf->card->default_address.type; -+ hw_addr->len = inf->card->default_address.len; -+ grub_memset (hw_addr->mac, -1, hw_addr->len); - return GRUB_ERR_NONE; - } - -@@ -142,6 +143,7 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, - && ((grub_be_to_cpu64 (proto_addr->ipv6[0]) >> 56) == 0xff)) - { - hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ hw_addr->len = inf->card->default_address.len; - hw_addr->mac[0] = 0x33; - hw_addr->mac[1] = 0x33; - hw_addr->mac[2] = ((grub_be_to_cpu64 (proto_addr->ipv6[1]) >> 24) & 0xff); -@@ -762,23 +764,23 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) - void - grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) - { -- str[0] = 0; -- switch (addr->type) -+ char *ptr; -+ unsigned i; -+ int maxstr; -+ -+ if (addr->len > GRUB_NET_MAX_LINK_ADDRESS_SIZE) - { -- case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: -- { -- char *ptr; -- unsigned i; -- for (ptr = str, i = 0; i < ARRAY_SIZE (addr->mac); i++) -- { -- grub_snprintf (ptr, GRUB_NET_MAX_STR_HWADDR_LEN - (ptr - str), -- "%02x:", addr->mac[i] & 0xff); -- ptr += (sizeof ("XX:") - 1); -- } -- return; -- } -+ str[0] = 0; -+ grub_printf (_("Unsupported hw address type %d len %d\n"), -+ addr->type, addr->len); -+ return; -+ } -+ maxstr = addr->len * grub_strlen ("XX:"); -+ for (ptr = str, i = 0; i < addr->len; i++) -+ { -+ ptr += grub_snprintf (ptr, maxstr - (ptr - str), -+ "%02x:", addr->mac[i] & 0xff); - } -- grub_printf (_("Unsupported hw address type %d\n"), addr->type); - } - - int -@@ -789,13 +791,17 @@ grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, - return -1; - if (a->type > b->type) - return +1; -- switch (a->type) -+ if (a->len < b->len) -+ return -1; -+ if (a->len > b->len) -+ return +1; -+ if (a->len > GRUB_NET_MAX_LINK_ADDRESS_SIZE) - { -- case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: -- return grub_memcmp (a->mac, b->mac, sizeof (a->mac)); -+ grub_printf (_("Unsupported hw address type %d len %d\n"), -+ a->type, a->len); -+ return + 1; - } -- grub_printf (_("Unsupported hw address type %d\n"), a->type); -- return 1; -+ return grub_memcmp (a->mac, b->mac, a->len); - } - - int -diff --git a/include/grub/net.h b/include/grub/net.h -index 8a05ec4fe7a..af0404db7e3 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -29,7 +29,8 @@ - - enum - { -- GRUB_NET_MAX_LINK_HEADER_SIZE = 64, -+ GRUB_NET_MAX_LINK_HEADER_SIZE = 96, -+ GRUB_NET_MAX_LINK_ADDRESS_SIZE = 32, - GRUB_NET_UDP_HEADER_SIZE = 8, - GRUB_NET_TCP_HEADER_SIZE = 20, - GRUB_NET_OUR_IPV4_HEADER_SIZE = 20, -@@ -42,15 +43,17 @@ enum - - typedef enum grub_link_level_protocol_id - { -- GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET -+ /* IANA ARP constant to define hardware type. */ -+ GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET = 1, - } grub_link_level_protocol_id_t; - - typedef struct grub_net_link_level_address - { - grub_link_level_protocol_id_t type; -+ grub_uint8_t len; - union - { -- grub_uint8_t mac[6]; -+ grub_uint8_t mac[GRUB_NET_MAX_LINK_ADDRESS_SIZE]; - }; - } grub_net_link_level_address_t; - -@@ -566,11 +569,13 @@ grub_net_addr_cmp (const grub_net_network_level_address_t *a, - #define GRUB_NET_MAX_STR_ADDR_LEN sizeof ("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX") - - /* -- Currently suppoerted adresses: -- ethernet: XX:XX:XX:XX:XX:XX -+ Up to 32 byte hardware address supported, see GRUB_NET_MAX_LINK_ADDRESS_SIZE - */ -- --#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX")) -+#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof (\ -+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ -+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ -+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ -+ "XX:XX:XX:XX:XX:XX:XX:XX")) - - void - grub_net_addr_to_str (const grub_net_network_level_address_t *target, diff --git a/0075-net-read-bracketed-ipv6-addrs-and-port-numbers.patch b/0075-net-read-bracketed-ipv6-addrs-and-port-numbers.patch deleted file mode 100644 index 834b96e..0000000 --- a/0075-net-read-bracketed-ipv6-addrs-and-port-numbers.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aaron Miller -Date: Fri, 29 Jul 2016 17:41:38 +0800 -Subject: [PATCH] net: read bracketed ipv6 addrs and port numbers - -Allow specifying port numbers for http and tftp paths, and allow ipv6 addresses -to be recognized with brackets around them, which is required to specify a port -number - -Signed-off-by: Aaron Miller -[pjones: various bug fixes] -Signed-off-by: Peter Jones ---- - grub-core/net/http.c | 25 ++++++++++++--- - grub-core/net/net.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++--- - grub-core/net/tftp.c | 8 +++-- - include/grub/net.h | 1 + - 4 files changed, 109 insertions(+), 12 deletions(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index b616cf40b1e..12a2632ea55 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -289,7 +289,9 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), - nb2 = grub_netbuff_alloc (data->chunk_rem); - if (!nb2) - return grub_errno; -- grub_netbuff_put (nb2, data->chunk_rem); -+ err = grub_netbuff_put (nb2, data->chunk_rem); -+ if (err) -+ return grub_errno; - grub_memcpy (nb2->data, nb->data, data->chunk_rem); - if (file->device->net->packs.count >= 20) - { -@@ -312,12 +314,14 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - int i; - struct grub_net_buff *nb; - grub_err_t err; -+ char* server = file->device->net->server; -+ int port = file->device->net->port; - - nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE - + sizeof ("GET ") - 1 - + grub_strlen (data->filename) - + sizeof (" HTTP/1.1\r\nHost: ") - 1 -- + grub_strlen (file->device->net->server) -+ + grub_strlen (server) + sizeof (":XXXXXXXXXX") - + sizeof ("\r\nUser-Agent: " PACKAGE_STRING - "\r\n") - 1 - + sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX" -@@ -356,7 +360,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - sizeof (" HTTP/1.1\r\nHost: ") - 1); - - ptr = nb->tail; -- err = grub_netbuff_put (nb, grub_strlen (file->device->net->server)); -+ err = grub_netbuff_put (nb, grub_strlen (server)); - if (err) - { - grub_netbuff_free (nb); -@@ -365,6 +369,15 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - grub_memcpy (ptr, file->device->net->server, - grub_strlen (file->device->net->server)); - -+ if (port) -+ { -+ ptr = nb->tail; -+ grub_snprintf ((char *) ptr, -+ sizeof (":XXXXXXXXXX"), -+ ":%d", -+ port); -+ } -+ - ptr = nb->tail; - err = grub_netbuff_put (nb, - sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") -@@ -390,8 +403,10 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - grub_netbuff_put (nb, 2); - grub_memcpy (ptr, "\r\n", 2); - -- data->sock = grub_net_tcp_open (file->device->net->server, -- HTTP_PORT, http_receive, -+ grub_dprintf ("http", "opening path %s on host %s TCP port %d\n", -+ data->filename, server, port ? port : HTTP_PORT); -+ data->sock = grub_net_tcp_open (server, -+ port ? port : HTTP_PORT, http_receive, - http_err, NULL, - file); - if (!data->sock) -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index a46f82362ed..0ce5e675ed7 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -444,6 +444,13 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) - grub_uint16_t newip[8]; - const char *ptr = val; - int word, quaddot = -1; -+ int bracketed = 0; -+ -+ if (ptr[0] == '[') -+ { -+ bracketed = 1; -+ ptr++; -+ } - - if (ptr[0] == ':' && ptr[1] != ':') - return 0; -@@ -482,6 +489,8 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) - grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0])); - } - grub_memcpy (ip, newip, 16); -+ if (bracketed && *ptr == ']') -+ ptr++; - if (rest) - *rest = ptr; - return 1; -@@ -1343,8 +1352,10 @@ grub_net_open_real (const char *name) - { - grub_net_app_level_t proto; - const char *protname, *server; -+ char *host; - grub_size_t protnamelen; - int try; -+ int port = 0; - - if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) - { -@@ -1382,6 +1393,72 @@ grub_net_open_real (const char *name) - return NULL; - } - -+ char* port_start; -+ /* ipv6 or port specified? */ -+ if ((port_start = grub_strchr (server, ':'))) -+ { -+ char* ipv6_begin; -+ if((ipv6_begin = grub_strchr (server, '['))) -+ { -+ char* ipv6_end = grub_strchr (server, ']'); -+ if(!ipv6_end) -+ { -+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, -+ N_("mismatched [ in address")); -+ return NULL; -+ } -+ /* port number after bracketed ipv6 addr */ -+ if(ipv6_end[1] == ':') -+ { -+ port = grub_strtoul (ipv6_end + 2, NULL, 10); -+ if(port > 65535) -+ { -+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, -+ N_("bad port number")); -+ return NULL; -+ } -+ } -+ host = grub_strndup (ipv6_begin, (ipv6_end - ipv6_begin) + 1); -+ } -+ else -+ { -+ if (grub_strchr (port_start + 1, ':')) -+ { -+ int iplen = grub_strlen (server); -+ /* bracket bare ipv6 addrs */ -+ host = grub_malloc (iplen + 3); -+ if(!host) -+ { -+ return NULL; -+ } -+ host[0] = '['; -+ grub_memcpy (host + 1, server, iplen); -+ host[iplen + 1] = ']'; -+ host[iplen + 2] = '\0'; -+ } -+ else -+ { -+ /* hostname:port or ipv4:port */ -+ port = grub_strtol (port_start + 1, NULL, 10); -+ if(port > 65535) -+ { -+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, -+ N_("bad port number")); -+ return NULL; -+ } -+ host = grub_strndup (server, port_start - server); -+ } -+ } -+ } -+ else -+ { -+ host = grub_strdup (server); -+ } -+ if (!host) -+ { -+ return NULL; -+ } -+ - for (try = 0; try < 2; try++) - { - FOR_NET_APP_LEVEL (proto) -@@ -1391,14 +1468,13 @@ grub_net_open_real (const char *name) - { - grub_net_t ret = grub_zalloc (sizeof (*ret)); - if (!ret) -- return NULL; -- ret->protocol = proto; -- ret->server = grub_strdup (server); -- if (!ret->server) - { -- grub_free (ret); -+ grub_free (host); - return NULL; - } -+ ret->protocol = proto; -+ ret->port = port; -+ ret->server = host; - ret->fs = &grub_net_fs; - return ret; - } -@@ -1473,6 +1549,7 @@ grub_net_open_real (const char *name) - grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), - name); - -+ grub_free (host); - return NULL; - } - -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index 4ab2f5c7357..d54b13f09ff 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -295,6 +295,7 @@ tftp_open (struct grub_file *file, const char *filename) - grub_err_t err; - grub_uint8_t *nbd; - grub_net_network_level_address_t addr; -+ int port = file->device->net->port; - - data = grub_zalloc (sizeof (*data)); - if (!data) -@@ -362,14 +363,17 @@ tftp_open (struct grub_file *file, const char *filename) - err = grub_net_resolve_address (file->device->net->server, &addr); - if (err) - { -- grub_dprintf("tftp", "Address resolution failed: %d\n", err); -+ grub_dprintf ("tftp", "Address resolution failed: %d\n", err); -+ grub_dprintf ("tftp", "file_size is %llu, block_size is %llu\n", -+ (unsigned long long)data->file_size, -+ (unsigned long long)data->block_size); - grub_free (data); - return err; - } - - grub_dprintf("tftp", "opening connection\n"); - data->sock = grub_net_udp_open (addr, -- TFTP_SERVER_PORT, tftp_receive, -+ port ? port : TFTP_SERVER_PORT, tftp_receive, - file); - if (!data->sock) - { -diff --git a/include/grub/net.h b/include/grub/net.h -index af0404db7e3..d55d505a03a 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -273,6 +273,7 @@ typedef struct grub_net - { - char *server; - char *name; -+ int port; - grub_net_app_level_t protocol; - grub_net_packets_t packs; - grub_off_t offset; diff --git a/0076-bootp-New-net_bootp6-command.patch b/0076-bootp-New-net_bootp6-command.patch deleted file mode 100644 index 21b3871..0000000 --- a/0076-bootp-New-net_bootp6-command.patch +++ /dev/null @@ -1,1368 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Wed, 10 Jul 2019 15:42:36 +0200 -Subject: [PATCH] bootp: New net_bootp6 command - -Implement new net_bootp6 command for IPv6 network auto configuration via the -DHCPv6 protocol (RFC3315). - -Signed-off-by: Michael Chang -Signed-off-by: Ken Lin -[pjones: Put back our code to add a local route] -Signed-off-by: Peter Jones ---- - grub-core/net/bootp.c | 1059 ++++++++++++++++++++++++++++++------ - grub-core/net/drivers/efi/efinet.c | 20 +- - grub-core/net/ip.c | 39 ++ - include/grub/efi/api.h | 2 +- - include/grub/net.h | 91 ++-- - 5 files changed, 1002 insertions(+), 209 deletions(-) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index 08b6b2b5d6c..fe93b80f1cf 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -24,6 +24,98 @@ - #include - #include - #include -+#include -+#include -+ -+static int -+dissect_url (const char *url, char **proto, char **host, char **path) -+{ -+ const char *p, *ps; -+ grub_size_t l; -+ -+ *proto = *host = *path = NULL; -+ ps = p = url; -+ -+ while ((p = grub_strchr (p, ':'))) -+ { -+ if (grub_strlen (p) < sizeof ("://") - 1) -+ break; -+ if (grub_memcmp (p, "://", sizeof ("://") - 1) == 0) -+ { -+ l = p - ps; -+ *proto = grub_malloc (l + 1); -+ if (!*proto) -+ { -+ grub_print_error (); -+ return 0; -+ } -+ -+ grub_memcpy (*proto, ps, l); -+ (*proto)[l] = '\0'; -+ p += sizeof ("://") - 1; -+ break; -+ } -+ ++p; -+ } -+ -+ if (!*proto) -+ { -+ grub_dprintf ("bootp", "url: %s is not valid, protocol not found\n", url); -+ return 0; -+ } -+ -+ ps = p; -+ p = grub_strchr (p, '/'); -+ -+ if (!p) -+ { -+ grub_dprintf ("bootp", "url: %s is not valid, host/path not found\n", url); -+ grub_free (*proto); -+ *proto = NULL; -+ return 0; -+ } -+ -+ l = p - ps; -+ -+ if (l > 2 && ps[0] == '[' && ps[l - 1] == ']') -+ { -+ *host = grub_malloc (l - 1); -+ if (!*host) -+ { -+ grub_print_error (); -+ grub_free (*proto); -+ *proto = NULL; -+ return 0; -+ } -+ grub_memcpy (*host, ps + 1, l - 2); -+ (*host)[l - 2] = 0; -+ } -+ else -+ { -+ *host = grub_malloc (l + 1); -+ if (!*host) -+ { -+ grub_print_error (); -+ grub_free (*proto); -+ *proto = NULL; -+ return 0; -+ } -+ grub_memcpy (*host, ps, l); -+ (*host)[l] = 0; -+ } -+ -+ *path = grub_strdup (p); -+ if (!*path) -+ { -+ grub_print_error (); -+ grub_free (*host); -+ grub_free (*proto); -+ *host = NULL; -+ *proto = NULL; -+ return 0; -+ } -+ return 1; -+} - - struct grub_dhcp_discover_options - { -@@ -604,6 +696,584 @@ out: - return err; - } - -+/* The default netbuff size for sending DHCPv6 packets which should be -+ large enough to hold the information */ -+#define GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE 512 -+ -+struct grub_dhcp6_options -+{ -+ grub_uint8_t *client_duid; -+ grub_uint16_t client_duid_len; -+ grub_uint8_t *server_duid; -+ grub_uint16_t server_duid_len; -+ grub_uint32_t iaid; -+ grub_uint32_t t1; -+ grub_uint32_t t2; -+ grub_net_network_level_address_t *ia_addr; -+ grub_uint32_t preferred_lifetime; -+ grub_uint32_t valid_lifetime; -+ grub_net_network_level_address_t *dns_server_addrs; -+ grub_uint16_t num_dns_server; -+ char *boot_file_proto; -+ char *boot_file_server_ip; -+ char *boot_file_path; -+}; -+ -+typedef struct grub_dhcp6_options *grub_dhcp6_options_t; -+ -+struct grub_dhcp6_session -+{ -+ struct grub_dhcp6_session *next; -+ struct grub_dhcp6_session **prev; -+ grub_uint32_t iaid; -+ grub_uint32_t transaction_id:24; -+ grub_uint64_t start_time; -+ struct grub_net_dhcp6_option_duid_ll duid; -+ struct grub_net_network_level_interface *iface; -+ -+ /* The associated dhcpv6 options */ -+ grub_dhcp6_options_t adv; -+ grub_dhcp6_options_t reply; -+}; -+ -+typedef struct grub_dhcp6_session *grub_dhcp6_session_t; -+ -+typedef void (*dhcp6_option_hook_fn) (const struct grub_net_dhcp6_option *opt, void *data); -+ -+static void -+foreach_dhcp6_option (const struct grub_net_dhcp6_option *opt, grub_size_t size, -+ dhcp6_option_hook_fn hook, void *hook_data); -+ -+static void -+parse_dhcp6_iaaddr (const struct grub_net_dhcp6_option *opt, void *data) -+{ -+ grub_dhcp6_options_t dhcp6 = (grub_dhcp6_options_t )data; -+ -+ grub_uint16_t code = grub_be_to_cpu16 (opt->code); -+ grub_uint16_t len = grub_be_to_cpu16 (opt->len); -+ -+ if (code == GRUB_NET_DHCP6_OPTION_IAADDR) -+ { -+ const struct grub_net_dhcp6_option_iaaddr *iaaddr; -+ iaaddr = (const struct grub_net_dhcp6_option_iaaddr *)opt->data; -+ -+ if (len < sizeof (*iaaddr)) -+ { -+ grub_dprintf ("bootp", "DHCPv6: code %u with insufficient length %u\n", code, len); -+ return; -+ } -+ if (!dhcp6->ia_addr) -+ { -+ dhcp6->ia_addr = grub_malloc (sizeof(*dhcp6->ia_addr)); -+ dhcp6->ia_addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ dhcp6->ia_addr->ipv6[0] = grub_get_unaligned64 (iaaddr->addr); -+ dhcp6->ia_addr->ipv6[1] = grub_get_unaligned64 (iaaddr->addr + 8); -+ dhcp6->preferred_lifetime = grub_be_to_cpu32 (iaaddr->preferred_lifetime); -+ dhcp6->valid_lifetime = grub_be_to_cpu32 (iaaddr->valid_lifetime); -+ } -+ } -+} -+ -+static void -+parse_dhcp6_option (const struct grub_net_dhcp6_option *opt, void *data) -+{ -+ grub_dhcp6_options_t dhcp6 = (grub_dhcp6_options_t)data; -+ grub_uint16_t code = grub_be_to_cpu16 (opt->code); -+ grub_uint16_t len = grub_be_to_cpu16 (opt->len); -+ -+ switch (code) -+ { -+ case GRUB_NET_DHCP6_OPTION_CLIENTID: -+ -+ if (dhcp6->client_duid || !len) -+ { -+ grub_dprintf ("bootp", "Skipped DHCPv6 CLIENTID with length %u\n", len); -+ break; -+ } -+ dhcp6->client_duid = grub_malloc (len); -+ grub_memcpy (dhcp6->client_duid, opt->data, len); -+ dhcp6->client_duid_len = len; -+ break; -+ -+ case GRUB_NET_DHCP6_OPTION_SERVERID: -+ -+ if (dhcp6->server_duid || !len) -+ { -+ grub_dprintf ("bootp", "Skipped DHCPv6 SERVERID with length %u\n", len); -+ break; -+ } -+ dhcp6->server_duid = grub_malloc (len); -+ grub_memcpy (dhcp6->server_duid, opt->data, len); -+ dhcp6->server_duid_len = len; -+ break; -+ -+ case GRUB_NET_DHCP6_OPTION_IA_NA: -+ { -+ const struct grub_net_dhcp6_option_iana *ia_na; -+ grub_uint16_t data_len; -+ -+ if (dhcp6->iaid || len < sizeof (*ia_na)) -+ { -+ grub_dprintf ("bootp", "Skipped DHCPv6 IA_NA with length %u\n", len); -+ break; -+ } -+ ia_na = (const struct grub_net_dhcp6_option_iana *)opt->data; -+ dhcp6->iaid = grub_be_to_cpu32 (ia_na->iaid); -+ dhcp6->t1 = grub_be_to_cpu32 (ia_na->t1); -+ dhcp6->t2 = grub_be_to_cpu32 (ia_na->t2); -+ -+ data_len = len - sizeof (*ia_na); -+ if (data_len) -+ foreach_dhcp6_option ((const struct grub_net_dhcp6_option *)ia_na->data, data_len, parse_dhcp6_iaaddr, dhcp6); -+ } -+ break; -+ -+ case GRUB_NET_DHCP6_OPTION_DNS_SERVERS: -+ { -+ const grub_uint8_t *po; -+ grub_uint16_t ln; -+ grub_net_network_level_address_t *la; -+ -+ if (!len || len & 0xf) -+ { -+ grub_dprintf ("bootp", "Skip invalid length DHCPv6 DNS_SERVERS \n"); -+ break; -+ } -+ dhcp6->num_dns_server = ln = len >> 4; -+ dhcp6->dns_server_addrs = la = grub_zalloc (ln * sizeof (*la)); -+ -+ for (po = opt->data; ln > 0; po += 0x10, la++, ln--) -+ { -+ la->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ la->ipv6[0] = grub_get_unaligned64 (po); -+ la->ipv6[1] = grub_get_unaligned64 (po + 8); -+ la->option = DNS_OPTION_PREFER_IPV6; -+ } -+ } -+ break; -+ -+ case GRUB_NET_DHCP6_OPTION_BOOTFILE_URL: -+ dissect_url ((const char *)opt->data, -+ &dhcp6->boot_file_proto, -+ &dhcp6->boot_file_server_ip, -+ &dhcp6->boot_file_path); -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+static void -+foreach_dhcp6_option (const struct grub_net_dhcp6_option *opt, grub_size_t size, dhcp6_option_hook_fn hook, void *hook_data) -+{ -+ while (size) -+ { -+ grub_uint16_t code, len; -+ -+ if (size < sizeof (*opt)) -+ { -+ grub_dprintf ("bootp", "DHCPv6: Options stopped with remaining size %" PRIxGRUB_SIZE "\n", size); -+ break; -+ } -+ size -= sizeof (*opt); -+ len = grub_be_to_cpu16 (opt->len); -+ code = grub_be_to_cpu16 (opt->code); -+ if (size < len) -+ { -+ grub_dprintf ("bootp", "DHCPv6: Options stopped at out of bound length %u for option %u\n", len, code); -+ break; -+ } -+ if (!len) -+ { -+ grub_dprintf ("bootp", "DHCPv6: Options stopped at zero length option %u\n", code); -+ break; -+ } -+ else -+ { -+ if (hook) -+ hook (opt, hook_data); -+ size -= len; -+ opt = (const struct grub_net_dhcp6_option *)((grub_uint8_t *)opt + len + sizeof (*opt)); -+ } -+ } -+} -+ -+static grub_dhcp6_options_t -+grub_dhcp6_options_get (const struct grub_net_dhcp6_packet *v6h, -+ grub_size_t size) -+{ -+ grub_dhcp6_options_t options; -+ -+ if (size < sizeof (*v6h)) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("DHCPv6 packet size too small")); -+ return NULL; -+ } -+ -+ options = grub_zalloc (sizeof(*options)); -+ if (!options) -+ return NULL; -+ -+ foreach_dhcp6_option ((const struct grub_net_dhcp6_option *)v6h->dhcp_options, -+ size - sizeof (*v6h), parse_dhcp6_option, options); -+ -+ return options; -+} -+ -+static void -+grub_dhcp6_options_free (grub_dhcp6_options_t options) -+{ -+ if (options->client_duid) -+ grub_free (options->client_duid); -+ if (options->server_duid) -+ grub_free (options->server_duid); -+ if (options->ia_addr) -+ grub_free (options->ia_addr); -+ if (options->dns_server_addrs) -+ grub_free (options->dns_server_addrs); -+ if (options->boot_file_proto) -+ grub_free (options->boot_file_proto); -+ if (options->boot_file_server_ip) -+ grub_free (options->boot_file_server_ip); -+ if (options->boot_file_path) -+ grub_free (options->boot_file_path); -+ -+ grub_free (options); -+} -+ -+static grub_dhcp6_session_t grub_dhcp6_sessions; -+#define FOR_DHCP6_SESSIONS_SAFE(var, next) FOR_LIST_ELEMENTS_SAFE (var, next, grub_dhcp6_sessions) -+#define FOR_DHCP6_SESSIONS(var) FOR_LIST_ELEMENTS (var, grub_dhcp6_sessions) -+ -+static void -+grub_net_configure_by_dhcp6_info (const char *name, -+ struct grub_net_card *card, -+ grub_dhcp6_options_t dhcp6, -+ int is_def, -+ int flags, -+ struct grub_net_network_level_interface **ret_inf) -+{ -+ grub_net_network_level_netaddress_t netaddr; -+ struct grub_net_network_level_interface *inf; -+ -+ if (dhcp6->ia_addr) -+ { -+ inf = grub_net_add_addr (name, card, dhcp6->ia_addr, &card->default_address, flags); -+ -+ netaddr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ netaddr.ipv6.base[0] = dhcp6->ia_addr->ipv6[0]; -+ netaddr.ipv6.base[1] = 0; -+ netaddr.ipv6.masksize = 64; -+ grub_net_add_route (name, netaddr, inf); -+ -+ if (ret_inf) -+ *ret_inf = inf; -+ } -+ -+ if (dhcp6->dns_server_addrs) -+ { -+ grub_uint16_t i; -+ -+ for (i = 0; i < dhcp6->num_dns_server; ++i) -+ grub_net_add_dns_server (dhcp6->dns_server_addrs + i); -+ } -+ -+ if (dhcp6->boot_file_path) -+ grub_env_set_net_property (name, "boot_file", dhcp6->boot_file_path, -+ grub_strlen (dhcp6->boot_file_path)); -+ -+ if (is_def && dhcp6->boot_file_server_ip) -+ { -+ grub_net_default_server = grub_strdup (dhcp6->boot_file_server_ip); -+ grub_env_set ("net_default_interface", name); -+ grub_env_export ("net_default_interface"); -+ } -+} -+ -+static void -+grub_dhcp6_session_add (struct grub_net_network_level_interface *iface, -+ grub_uint32_t iaid) -+{ -+ grub_dhcp6_session_t se; -+ struct grub_datetime date; -+ grub_err_t err; -+ grub_int32_t t = 0; -+ -+ se = grub_malloc (sizeof (*se)); -+ -+ err = grub_get_datetime (&date); -+ if (err || !grub_datetime2unixtime (&date, &t)) -+ { -+ grub_errno = GRUB_ERR_NONE; -+ t = 0; -+ } -+ -+ se->iface = iface; -+ se->iaid = iaid; -+ se->transaction_id = t; -+ se->start_time = grub_get_time_ms (); -+ se->duid.type = grub_cpu_to_be16_compile_time (3) ; -+ se->duid.hw_type = grub_cpu_to_be16_compile_time (1); -+ grub_memcpy (&se->duid.hwaddr, &iface->hwaddress.mac, sizeof (se->duid.hwaddr)); -+ se->adv = NULL; -+ se->reply = NULL; -+ grub_list_push (GRUB_AS_LIST_P (&grub_dhcp6_sessions), GRUB_AS_LIST (se)); -+} -+ -+static void -+grub_dhcp6_session_remove (grub_dhcp6_session_t se) -+{ -+ grub_list_remove (GRUB_AS_LIST (se)); -+ if (se->adv) -+ grub_dhcp6_options_free (se->adv); -+ if (se->reply) -+ grub_dhcp6_options_free (se->reply); -+ grub_free (se); -+} -+ -+static void -+grub_dhcp6_session_remove_all (void) -+{ -+ grub_dhcp6_session_t se, next; -+ -+ FOR_DHCP6_SESSIONS_SAFE (se, next) -+ { -+ grub_dhcp6_session_remove (se); -+ } -+ grub_dhcp6_sessions = NULL; -+} -+ -+static grub_err_t -+grub_dhcp6_session_configure_network (grub_dhcp6_session_t se) -+{ -+ char *name; -+ -+ name = grub_xasprintf ("%s:dhcp6", se->iface->card->name); -+ if (!name) -+ return grub_errno; -+ -+ grub_net_configure_by_dhcp6_info (name, se->iface->card, se->reply, 1, 0, 0); -+ grub_free (name); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_dhcp6_session_send_request (grub_dhcp6_session_t se) -+{ -+ struct grub_net_buff *nb; -+ struct grub_net_dhcp6_option *opt; -+ struct grub_net_dhcp6_packet *v6h; -+ struct grub_net_dhcp6_option_iana *ia_na; -+ struct grub_net_dhcp6_option_iaaddr *iaaddr; -+ struct udphdr *udph; -+ grub_net_network_level_address_t multicast; -+ grub_net_link_level_address_t ll_multicast; -+ grub_uint64_t elapsed; -+ struct grub_net_network_level_interface *inf = se->iface; -+ grub_dhcp6_options_t dhcp6 = se->adv; -+ grub_err_t err = GRUB_ERR_NONE; -+ -+ multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ multicast.ipv6[0] = grub_cpu_to_be64_compile_time (0xff02ULL << 48); -+ multicast.ipv6[1] = grub_cpu_to_be64_compile_time (0x10002ULL); -+ -+ err = grub_net_link_layer_resolve (inf, &multicast, &ll_multicast); -+ if (err) -+ return err; -+ -+ nb = grub_netbuff_alloc (GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE); -+ -+ if (!nb) -+ return grub_errno; -+ -+ err = grub_netbuff_reserve (nb, GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ err = grub_netbuff_push (nb, dhcp6->client_duid_len + sizeof (*opt)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_CLIENTID); -+ opt->len = grub_cpu_to_be16 (dhcp6->client_duid_len); -+ grub_memcpy (opt->data, dhcp6->client_duid , dhcp6->client_duid_len); -+ -+ err = grub_netbuff_push (nb, dhcp6->server_duid_len + sizeof (*opt)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_SERVERID); -+ opt->len = grub_cpu_to_be16 (dhcp6->server_duid_len); -+ grub_memcpy (opt->data, dhcp6->server_duid , dhcp6->server_duid_len); -+ -+ err = grub_netbuff_push (nb, sizeof (*ia_na) + sizeof (*opt)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ if (dhcp6->ia_addr) -+ { -+ err = grub_netbuff_push (nb, sizeof(*iaaddr) + sizeof (*opt)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ } -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA); -+ opt->len = grub_cpu_to_be16 (sizeof (*ia_na)); -+ if (dhcp6->ia_addr) -+ opt->len += grub_cpu_to_be16 (sizeof(*iaaddr) + sizeof (*opt)); -+ -+ ia_na = (struct grub_net_dhcp6_option_iana *)opt->data; -+ ia_na->iaid = grub_cpu_to_be32 (dhcp6->iaid); -+ -+ ia_na->t1 = grub_cpu_to_be32 (dhcp6->t1); -+ ia_na->t2 = grub_cpu_to_be32 (dhcp6->t2); -+ -+ if (dhcp6->ia_addr) -+ { -+ opt = (struct grub_net_dhcp6_option *)ia_na->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IAADDR); -+ opt->len = grub_cpu_to_be16 (sizeof (*iaaddr)); -+ iaaddr = (struct grub_net_dhcp6_option_iaaddr *)opt->data; -+ grub_set_unaligned64 (iaaddr->addr, dhcp6->ia_addr->ipv6[0]); -+ grub_set_unaligned64 (iaaddr->addr + 8, dhcp6->ia_addr->ipv6[1]); -+ -+ iaaddr->preferred_lifetime = grub_cpu_to_be32 (dhcp6->preferred_lifetime); -+ iaaddr->valid_lifetime = grub_cpu_to_be32 (dhcp6->valid_lifetime); -+ } -+ -+ err = grub_netbuff_push (nb, sizeof (*opt) + 2 * sizeof (grub_uint16_t)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ opt = (struct grub_net_dhcp6_option*) nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_ORO); -+ opt->len = grub_cpu_to_be16_compile_time (2 * sizeof (grub_uint16_t)); -+ grub_set_unaligned16 (opt->data, grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_BOOTFILE_URL)); -+ grub_set_unaligned16 (opt->data + 2, grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_DNS_SERVERS)); -+ -+ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (grub_uint16_t)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ opt = (struct grub_net_dhcp6_option*) nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_ELAPSED_TIME); -+ opt->len = grub_cpu_to_be16_compile_time (sizeof (grub_uint16_t)); -+ -+ /* the time is expressed in hundredths of a second */ -+ elapsed = grub_divmod64 (grub_get_time_ms () - se->start_time, 10, 0); -+ -+ if (elapsed > 0xffff) -+ elapsed = 0xffff; -+ -+ grub_set_unaligned16 (opt->data, grub_cpu_to_be16 ((grub_uint16_t)elapsed)); -+ -+ err = grub_netbuff_push (nb, sizeof (*v6h)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ v6h = (struct grub_net_dhcp6_packet *) nb->data; -+ v6h->message_type = GRUB_NET_DHCP6_REQUEST; -+ v6h->transaction_id = se->transaction_id; -+ -+ err = grub_netbuff_push (nb, sizeof (*udph)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ udph = (struct udphdr *) nb->data; -+ udph->src = grub_cpu_to_be16_compile_time (DHCP6_CLIENT_PORT); -+ udph->dst = grub_cpu_to_be16_compile_time (DHCP6_SERVER_PORT); -+ udph->chksum = 0; -+ udph->len = grub_cpu_to_be16 (nb->tail - nb->data); -+ -+ udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, -+ &inf->address, -+ &multicast); -+ err = grub_net_send_ip_packet (inf, &multicast, &ll_multicast, nb, -+ GRUB_NET_IP_UDP); -+ -+ grub_netbuff_free (nb); -+ -+ return err; -+} -+ -+struct grub_net_network_level_interface * -+grub_net_configure_by_dhcpv6_reply (const char *name, -+ struct grub_net_card *card, -+ grub_net_interface_flags_t flags, -+ const struct grub_net_dhcp6_packet *v6h, -+ grub_size_t size, -+ int is_def, -+ char **device, char **path) -+{ -+ struct grub_net_network_level_interface *inf; -+ grub_dhcp6_options_t dhcp6; -+ int mask = -1; -+ -+ dhcp6 = grub_dhcp6_options_get (v6h, size); -+ if (!dhcp6) -+ { -+ grub_print_error (); -+ return NULL; -+ } -+ -+ grub_net_configure_by_dhcp6_info (name, card, dhcp6, is_def, flags, &inf); -+ -+ if (device && dhcp6->boot_file_proto && dhcp6->boot_file_server_ip) -+ { -+ *device = grub_xasprintf ("%s,%s", dhcp6->boot_file_proto, dhcp6->boot_file_server_ip); -+ grub_print_error (); -+ } -+ if (path && dhcp6->boot_file_path) -+ { -+ *path = grub_strdup (dhcp6->boot_file_path); -+ grub_print_error (); -+ if (*path) -+ { -+ char *slash; -+ slash = grub_strrchr (*path, '/'); -+ if (slash) -+ *slash = 0; -+ else -+ **path = 0; -+ } -+ } -+ -+ grub_dhcp6_options_free (dhcp6); -+ -+ if (inf) -+ grub_net_add_ipv6_local (inf, mask); -+ -+ return inf; -+} -+ - /* - * This is called directly from net/ip.c:handle_dgram(), because those - * BOOTP/DHCP packets are a bit special due to their improper -@@ -672,6 +1342,77 @@ grub_net_process_dhcp (struct grub_net_buff *nb, - } - } - -+grub_err_t -+grub_net_process_dhcp6 (struct grub_net_buff *nb, -+ struct grub_net_card *card __attribute__ ((unused))) -+{ -+ const struct grub_net_dhcp6_packet *v6h; -+ grub_dhcp6_session_t se; -+ grub_size_t size; -+ grub_dhcp6_options_t options; -+ -+ v6h = (const struct grub_net_dhcp6_packet *) nb->data; -+ size = nb->tail - nb->data; -+ -+ options = grub_dhcp6_options_get (v6h, size); -+ if (!options) -+ return grub_errno; -+ -+ if (!options->client_duid || !options->server_duid || !options->ia_addr) -+ { -+ grub_dhcp6_options_free (options); -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Bad DHCPv6 Packet"); -+ } -+ -+ FOR_DHCP6_SESSIONS (se) -+ { -+ if (se->transaction_id == v6h->transaction_id && -+ grub_memcmp (options->client_duid, &se->duid, sizeof (se->duid)) == 0 && -+ se->iaid == options->iaid) -+ break; -+ } -+ -+ if (!se) -+ { -+ grub_dprintf ("bootp", "DHCPv6 session not found\n"); -+ grub_dhcp6_options_free (options); -+ return GRUB_ERR_NONE; -+ } -+ -+ if (v6h->message_type == GRUB_NET_DHCP6_ADVERTISE) -+ { -+ if (se->adv) -+ { -+ grub_dprintf ("bootp", "Skipped DHCPv6 Advertised .. \n"); -+ grub_dhcp6_options_free (options); -+ return GRUB_ERR_NONE; -+ } -+ -+ se->adv = options; -+ return grub_dhcp6_session_send_request (se); -+ } -+ else if (v6h->message_type == GRUB_NET_DHCP6_REPLY) -+ { -+ if (!se->adv) -+ { -+ grub_dprintf ("bootp", "Skipped DHCPv6 Reply .. \n"); -+ grub_dhcp6_options_free (options); -+ return GRUB_ERR_NONE; -+ } -+ -+ se->reply = options; -+ grub_dhcp6_session_configure_network (se); -+ grub_dhcp6_session_remove (se); -+ return GRUB_ERR_NONE; -+ } -+ else -+ { -+ grub_dhcp6_options_free (options); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ - static grub_err_t - grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -@@ -897,180 +1638,174 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), - return err; - } - --static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp; -- --struct grub_net_network_level_interface * --grub_net_configure_by_dhcpv6_ack (const char *name, -- struct grub_net_card *card, -- grub_net_interface_flags_t flags -- __attribute__((__unused__)), -- const grub_net_link_level_address_t *hwaddr, -- const struct grub_net_dhcpv6_packet *packet, -- int is_def, char **device, char **path) -+static grub_err_t -+grub_cmd_bootp6 (struct grub_command *cmd __attribute__ ((unused)), -+ int argc, char **args) - { -- struct grub_net_network_level_interface *inter = NULL; -- struct grub_net_network_level_address addr; -- int mask = -1; -+ struct grub_net_card *card; -+ grub_uint32_t iaid = 0; -+ int interval; -+ grub_err_t err; -+ grub_dhcp6_session_t se; - -- if (!device || !path) -- return NULL; -+ err = GRUB_ERR_NONE; - -- *device = 0; -- *path = 0; -+ FOR_NET_CARDS (card) -+ { -+ struct grub_net_network_level_interface *iface; - -- grub_dprintf ("net", "mac address is %02x:%02x:%02x:%02x:%02x:%02x\n", -- hwaddr->mac[0], hwaddr->mac[1], hwaddr->mac[2], -- hwaddr->mac[3], hwaddr->mac[4], hwaddr->mac[5]); -+ if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) -+ continue; - -- if (is_def) -- grub_net_default_server = 0; -+ iface = grub_net_ipv6_get_link_local (card, &card->default_address); -+ if (!iface) -+ { -+ grub_dhcp6_session_remove_all (); -+ return grub_errno; -+ } - -- if (is_def && !grub_net_default_server && packet) -+ grub_dhcp6_session_add (iface, iaid++); -+ } -+ -+ for (interval = 200; interval < 10000; interval *= 2) - { -- const grub_uint8_t *options = packet->dhcp_options; -- unsigned int option_max = 1024 - OFFSET_OF (dhcp_options, packet); -- unsigned int i; -- -- for (i = 0; i < option_max - sizeof (grub_net_dhcpv6_option_t); ) -- { -- grub_uint16_t num, len; -- grub_net_dhcpv6_option_t *opt = -- (grub_net_dhcpv6_option_t *)(options + i); -- -- num = grub_be_to_cpu16(opt->option_num); -- len = grub_be_to_cpu16(opt->option_len); -- -- grub_dprintf ("net", "got dhcpv6 option %d len %d\n", num, len); -- -- if (len == 0) -- break; -- -- if (len + i > 1024) -- break; -- -- if (num == GRUB_NET_DHCP6_BOOTFILE_URL) -- { -- char *scheme, *userinfo, *host, *file; -- char *tmp; -- int hostlen; -- int port; -- int rc = extract_url_info ((const char *)opt->option_data, -- (grub_size_t)len, -- &scheme, &userinfo, &host, &port, -- &file); -- if (rc < 0) -- continue; -- -- /* right now this only handles tftp. */ -- if (grub_strcmp("tftp", scheme)) -- { -- grub_free (scheme); -- grub_free (userinfo); -- grub_free (host); -- grub_free (file); -- continue; -- } -- grub_free (userinfo); -- -- hostlen = grub_strlen (host); -- if (hostlen > 2 && host[0] == '[' && host[hostlen-1] == ']') -- { -- tmp = host+1; -- host[hostlen-1] = '\0'; -- } -- else -- tmp = host; -- -- *device = grub_xasprintf ("%s,%s", scheme, tmp); -- grub_free (scheme); -- grub_free (host); -- -- if (file && *file) -- { -- tmp = grub_strrchr (file, '/'); -- if (tmp) -- *(tmp+1) = '\0'; -- else -- file[0] = '\0'; -- } -- else if (!file) -- file = grub_strdup (""); -- -- if (file[0] == '/') -- { -- *path = grub_strdup (file+1); -- grub_free (file); -- } -- else -- *path = file; -- } -- else if (num == GRUB_NET_DHCP6_IA_NA) -- { -- const grub_net_dhcpv6_option_t *ia_na_opt; -- const grub_net_dhcpv6_opt_ia_na_t *ia_na = -- (const grub_net_dhcpv6_opt_ia_na_t *)opt; -- unsigned int left = len - OFFSET_OF (options, ia_na); -- unsigned int j; -- -- if ((grub_uint8_t *)ia_na + left > -- (grub_uint8_t *)options + option_max) -- left -= ((grub_uint8_t *)ia_na + left) -- - ((grub_uint8_t *)options + option_max); -- -- if (len < OFFSET_OF (option_data, opt) -- + sizeof (grub_net_dhcpv6_option_t)) -- { -- grub_dprintf ("net", -- "found dhcpv6 ia_na option with no address\n"); -- continue; -- } -- -- for (j = 0; left > sizeof (grub_net_dhcpv6_option_t); ) -- { -- ia_na_opt = (const grub_net_dhcpv6_option_t *) -- (ia_na->options + j); -- grub_uint16_t ia_na_opt_num, ia_na_opt_len; -- -- ia_na_opt_num = grub_be_to_cpu16 (ia_na_opt->option_num); -- ia_na_opt_len = grub_be_to_cpu16 (ia_na_opt->option_len); -- if (ia_na_opt_len == 0) -- break; -- if (j + ia_na_opt_len > left) -- break; -- if (ia_na_opt_num == GRUB_NET_DHCP6_IA_ADDRESS) -- { -- const grub_net_dhcpv6_opt_ia_address_t *ia_addr; -- -- ia_addr = (const grub_net_dhcpv6_opt_ia_address_t *) -- ia_na_opt; -- addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -- grub_memcpy(addr.ipv6, ia_addr->ipv6_address, -- sizeof (ia_addr->ipv6_address)); -- inter = grub_net_add_addr (name, card, &addr, hwaddr, 0); -- } -- -- j += ia_na_opt_len; -- left -= ia_na_opt_len; -- } -- } -- -- i += len + 4; -- } -- -- grub_print_error (); -+ int done = 1; -+ -+ FOR_DHCP6_SESSIONS (se) -+ { -+ struct grub_net_buff *nb; -+ struct grub_net_dhcp6_option *opt; -+ struct grub_net_dhcp6_packet *v6h; -+ struct grub_net_dhcp6_option_duid_ll *duid; -+ struct grub_net_dhcp6_option_iana *ia_na; -+ grub_net_network_level_address_t multicast; -+ grub_net_link_level_address_t ll_multicast; -+ struct udphdr *udph; -+ -+ multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ multicast.ipv6[0] = grub_cpu_to_be64_compile_time (0xff02ULL << 48); -+ multicast.ipv6[1] = grub_cpu_to_be64_compile_time (0x10002ULL); -+ -+ err = grub_net_link_layer_resolve (se->iface, -+ &multicast, &ll_multicast); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ return err; -+ } -+ -+ nb = grub_netbuff_alloc (GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE); -+ -+ if (!nb) -+ { -+ grub_dhcp6_session_remove_all (); -+ return grub_errno; -+ } -+ -+ err = grub_netbuff_reserve (nb, GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (grub_uint16_t)); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_ELAPSED_TIME); -+ opt->len = grub_cpu_to_be16_compile_time (sizeof (grub_uint16_t)); -+ grub_set_unaligned16 (opt->data, 0); -+ -+ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (*duid)); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_CLIENTID); -+ opt->len = grub_cpu_to_be16 (sizeof (*duid)); -+ -+ duid = (struct grub_net_dhcp6_option_duid_ll *) opt->data; -+ grub_memcpy (duid, &se->duid, sizeof (*duid)); -+ -+ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (*ia_na)); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA); -+ opt->len = grub_cpu_to_be16 (sizeof (*ia_na)); -+ ia_na = (struct grub_net_dhcp6_option_iana *)opt->data; -+ ia_na->iaid = grub_cpu_to_be32 (se->iaid); -+ ia_na->t1 = 0; -+ ia_na->t2 = 0; -+ -+ err = grub_netbuff_push (nb, sizeof (*v6h)); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ v6h = (struct grub_net_dhcp6_packet *)nb->data; -+ v6h->message_type = GRUB_NET_DHCP6_SOLICIT; -+ v6h->transaction_id = se->transaction_id; -+ -+ grub_netbuff_push (nb, sizeof (*udph)); -+ -+ udph = (struct udphdr *) nb->data; -+ udph->src = grub_cpu_to_be16_compile_time (DHCP6_CLIENT_PORT); -+ udph->dst = grub_cpu_to_be16_compile_time (DHCP6_SERVER_PORT); -+ udph->chksum = 0; -+ udph->len = grub_cpu_to_be16 (nb->tail - nb->data); -+ -+ udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, -+ &se->iface->address, &multicast); -+ -+ err = grub_net_send_ip_packet (se->iface, &multicast, -+ &ll_multicast, nb, GRUB_NET_IP_UDP); -+ done = 0; -+ grub_netbuff_free (nb); -+ -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ return err; -+ } -+ } -+ if (!done) -+ grub_net_poll_cards (interval, 0); - } - -- if (is_def) -+ FOR_DHCP6_SESSIONS (se) - { -- grub_env_set ("net_default_interface", name); -- grub_env_export ("net_default_interface"); -+ grub_error_push (); -+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, -+ N_("couldn't autoconfigure %s"), -+ se->iface->card->name); - } - -- if (inter) -- grub_net_add_ipv6_local (inter, mask); -- return inter; -+ grub_dhcp6_session_remove_all (); -+ -+ return err; - } - -+static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp, cmd_bootp6; - - void - grub_bootp_init (void) -@@ -1084,11 +1819,15 @@ grub_bootp_init (void) - cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, - N_("VAR INTERFACE NUMBER DESCRIPTION"), - N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); -+ cmd_bootp6 = grub_register_command ("net_bootp6", grub_cmd_bootp6, -+ N_("[CARD]"), -+ N_("perform a DHCPv6 autoconfiguration")); - } - - void - grub_bootp_fini (void) - { -+ grub_unregister_command (cmd_bootp6); - grub_unregister_command (cmd_getdhcp); - grub_unregister_command (cmd_bootp); - grub_unregister_command (cmd_dhcp); -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index a673bea807a..8e25680db0c 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -393,9 +393,6 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - pxe_mode = pxe->mode; - if (pxe_mode->using_ipv6) - { -- grub_net_link_level_address_t hwaddr; -- struct grub_net_network_level_interface *intf; -- - grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); - grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", - pxe_mode->dhcp_ack_received ? "yes" : "no", -@@ -403,15 +400,14 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - if (!pxe_mode->dhcp_ack_received) - continue; - -- hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (hwaddr.mac, -- card->efi_net->mode->current_address, -- sizeof (hwaddr.mac)); -- -- intf = grub_net_configure_by_dhcpv6_ack (card->name, card, 0, &hwaddr, -- (const struct grub_net_dhcpv6_packet *)&pxe_mode->dhcp_ack.dhcpv6, -- 1, device, path); -- if (intf && device && path) -+ grub_net_configure_by_dhcpv6_reply (card->name, card, 0, -+ (struct grub_net_dhcp6_packet *) -+ &pxe_mode->dhcp_ack, -+ sizeof (pxe_mode->dhcp_ack), -+ 1, device, path); -+ if (grub_errno) -+ grub_print_error (); -+ if (device && path) - grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); - } - else -diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c -index a5896f6dc26..ce6bdc75c6d 100644 ---- a/grub-core/net/ip.c -+++ b/grub-core/net/ip.c -@@ -239,6 +239,45 @@ handle_dgram (struct grub_net_buff *nb, - { - struct udphdr *udph; - udph = (struct udphdr *) nb->data; -+ -+ if (proto == GRUB_NET_IP_UDP && udph->dst == grub_cpu_to_be16_compile_time (DHCP6_CLIENT_PORT)) -+ { -+ if (udph->chksum) -+ { -+ grub_uint16_t chk, expected; -+ chk = udph->chksum; -+ udph->chksum = 0; -+ expected = grub_net_ip_transport_checksum (nb, -+ GRUB_NET_IP_UDP, -+ source, -+ dest); -+ if (expected != chk) -+ { -+ grub_dprintf ("net", "Invalid UDP checksum. " -+ "Expected %x, got %x\n", -+ grub_be_to_cpu16 (expected), -+ grub_be_to_cpu16 (chk)); -+ grub_netbuff_free (nb); -+ return GRUB_ERR_NONE; -+ } -+ udph->chksum = chk; -+ } -+ -+ err = grub_netbuff_pull (nb, sizeof (*udph)); -+ if (err) -+ { -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ err = grub_net_process_dhcp6 (nb, card); -+ if (err) -+ grub_print_error (); -+ -+ grub_netbuff_free (nb); -+ return GRUB_ERR_NONE; -+ } -+ - if (proto == GRUB_NET_IP_UDP && grub_be_to_cpu16 (udph->dst) == 68) - { - const struct grub_net_bootp_packet *bootp; -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 99628801478..7614b58dca8 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -1532,7 +1532,7 @@ typedef struct grub_efi_pxe_ip_filter - { - grub_efi_uint8_t filters; - grub_efi_uint8_t ip_count; -- grub_efi_uint8_t reserved; -+ grub_efi_uint16_t reserved; - grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; - } grub_efi_pxe_ip_filter_t; - -diff --git a/include/grub/net.h b/include/grub/net.h -index d55d505a03a..543251f7273 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -451,50 +451,65 @@ struct grub_net_bootp_packet - grub_uint8_t vendor[0]; - } GRUB_PACKED; - --enum -- { -- GRUB_NET_DHCP6_IA_NA = 3, -- GRUB_NET_DHCP6_IA_ADDRESS = 5, -- GRUB_NET_DHCP6_BOOTFILE_URL = 59, -- }; -- --struct grub_net_dhcpv6_option -+struct grub_net_dhcp6_packet - { -- grub_uint16_t option_num; -- grub_uint16_t option_len; -- grub_uint8_t option_data[]; -+ grub_uint32_t message_type:8; -+ grub_uint32_t transaction_id:24; -+ grub_uint8_t dhcp_options[0]; - } GRUB_PACKED; --typedef struct grub_net_dhcpv6_option grub_net_dhcpv6_option_t; - --struct grub_net_dhcpv6_opt_ia_na --{ -- grub_uint16_t option_num; -- grub_uint16_t option_len; -+struct grub_net_dhcp6_option { -+ grub_uint16_t code; -+ grub_uint16_t len; -+ grub_uint8_t data[0]; -+} GRUB_PACKED; -+ -+struct grub_net_dhcp6_option_iana { - grub_uint32_t iaid; - grub_uint32_t t1; - grub_uint32_t t2; -- grub_uint8_t options[]; -+ grub_uint8_t data[0]; - } GRUB_PACKED; --typedef struct grub_net_dhcpv6_opt_ia_na grub_net_dhcpv6_opt_ia_na_t; - --struct grub_net_dhcpv6_opt_ia_address --{ -- grub_uint16_t option_num; -- grub_uint16_t option_len; -- grub_uint64_t ipv6_address[2]; -+struct grub_net_dhcp6_option_iaaddr { -+ grub_uint8_t addr[16]; - grub_uint32_t preferred_lifetime; - grub_uint32_t valid_lifetime; -- grub_uint8_t options[]; -+ grub_uint8_t data[0]; - } GRUB_PACKED; --typedef struct grub_net_dhcpv6_opt_ia_address grub_net_dhcpv6_opt_ia_address_t; - --struct grub_net_dhcpv6_packet -+struct grub_net_dhcp6_option_duid_ll - { -- grub_uint32_t message_type:8; -- grub_uint32_t transaction_id:24; -- grub_uint8_t dhcp_options[1024]; -+ grub_uint16_t type; -+ grub_uint16_t hw_type; -+ grub_uint8_t hwaddr[6]; - } GRUB_PACKED; --typedef struct grub_net_dhcpv6_packet grub_net_dhcpv6_packet_t; -+ -+enum -+ { -+ GRUB_NET_DHCP6_SOLICIT = 1, -+ GRUB_NET_DHCP6_ADVERTISE = 2, -+ GRUB_NET_DHCP6_REQUEST = 3, -+ GRUB_NET_DHCP6_REPLY = 7 -+ }; -+ -+enum -+ { -+ DHCP6_CLIENT_PORT = 546, -+ DHCP6_SERVER_PORT = 547 -+ }; -+ -+enum -+ { -+ GRUB_NET_DHCP6_OPTION_CLIENTID = 1, -+ GRUB_NET_DHCP6_OPTION_SERVERID = 2, -+ GRUB_NET_DHCP6_OPTION_IA_NA = 3, -+ GRUB_NET_DHCP6_OPTION_IAADDR = 5, -+ GRUB_NET_DHCP6_OPTION_ORO = 6, -+ GRUB_NET_DHCP6_OPTION_ELAPSED_TIME = 8, -+ GRUB_NET_DHCP6_OPTION_DNS_SERVERS = 23, -+ GRUB_NET_DHCP6_OPTION_BOOTFILE_URL = 59 -+ }; - - #define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 - #define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 -@@ -532,12 +547,12 @@ grub_net_configure_by_dhcp_ack (const char *name, - int is_def, char **device, char **path); - - struct grub_net_network_level_interface * --grub_net_configure_by_dhcpv6_ack (const char *name, -- struct grub_net_card *card, -- grub_net_interface_flags_t flags, -- const grub_net_link_level_address_t *hwaddr, -- const struct grub_net_dhcpv6_packet *packet, -- int is_def, char **device, char **path); -+grub_net_configure_by_dhcpv6_reply (const char *name, -+ struct grub_net_card *card, -+ grub_net_interface_flags_t flags, -+ const struct grub_net_dhcp6_packet *v6, -+ grub_size_t size, -+ int is_def, char **device, char **path); - - int - grub_ipv6_get_masksize(grub_uint16_t *mask); -@@ -554,6 +569,10 @@ void - grub_net_process_dhcp (struct grub_net_buff *nb, - struct grub_net_network_level_interface *iface); - -+grub_err_t -+grub_net_process_dhcp6 (struct grub_net_buff *nb, -+ struct grub_net_card *card); -+ - int - grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, - const grub_net_link_level_address_t *b); diff --git a/0077-efinet-UEFI-IPv6-PXE-support.patch b/0077-efinet-UEFI-IPv6-PXE-support.patch deleted file mode 100644 index d8b22b8..0000000 --- a/0077-efinet-UEFI-IPv6-PXE-support.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Wed, 15 Apr 2015 14:48:30 +0800 -Subject: [PATCH] efinet: UEFI IPv6 PXE support - -When grub2 image is booted from UEFI IPv6 PXE, the DHCPv6 Reply packet is -cached in firmware buffer which can be obtained by PXE Base Code protocol. The -network interface can be setup through the parameters in that obtained packet. - -Signed-off-by: Michael Chang -Signed-off-by: Ken Lin ---- - grub-core/net/drivers/efi/efinet.c | 2 ++ - include/grub/efi/api.h | 71 +++++++++++++++++++++++--------------- - 2 files changed, 46 insertions(+), 27 deletions(-) - -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 8e25680db0c..014e5bf9802 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -409,6 +409,8 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - grub_print_error (); - if (device && path) - grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); -+ if (grub_errno) -+ grub_print_error (); - } - else - { -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 7614b58dca8..91ab528e4d0 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -1524,31 +1524,6 @@ typedef union - grub_efi_pxe_dhcpv6_packet_t dhcpv6; - } grub_efi_pxe_packet_t; - --#define GRUB_EFI_PXE_MAX_IPCNT 8 --#define GRUB_EFI_PXE_MAX_ARP_ENTRIES 8 --#define GRUB_EFI_PXE_MAX_ROUTE_ENTRIES 8 -- --typedef struct grub_efi_pxe_ip_filter --{ -- grub_efi_uint8_t filters; -- grub_efi_uint8_t ip_count; -- grub_efi_uint16_t reserved; -- grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; --} grub_efi_pxe_ip_filter_t; -- --typedef struct grub_efi_pxe_arp_entry --{ -- grub_efi_ip_address_t ip_addr; -- grub_efi_mac_address_t mac_addr; --} grub_efi_pxe_arp_entry_t; -- --typedef struct grub_efi_pxe_route_entry --{ -- grub_efi_ip_address_t ip_addr; -- grub_efi_ip_address_t subnet_mask; -- grub_efi_ip_address_t gateway_addr; --} grub_efi_pxe_route_entry_t; -- - typedef struct grub_efi_pxe_icmp_error - { - grub_efi_uint8_t type; -@@ -1574,6 +1549,48 @@ typedef struct grub_efi_pxe_tftp_error - grub_efi_char8_t error_string[127]; - } grub_efi_pxe_tftp_error_t; - -+typedef struct { -+ grub_uint8_t addr[4]; -+} grub_efi_pxe_ipv4_address_t; -+ -+typedef struct { -+ grub_uint8_t addr[16]; -+} grub_efi_pxe_ipv6_address_t; -+ -+typedef struct { -+ grub_uint8_t addr[32]; -+} grub_efi_pxe_mac_address_t; -+ -+typedef union { -+ grub_uint32_t addr[4]; -+ grub_efi_pxe_ipv4_address_t v4; -+ grub_efi_pxe_ipv6_address_t v6; -+} grub_efi_pxe_ip_address_t; -+ -+#define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8 -+typedef struct grub_efi_pxe_ip_filter -+{ -+ grub_efi_uint8_t filters; -+ grub_efi_uint8_t ip_count; -+ grub_efi_uint16_t reserved; -+ grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT]; -+} grub_efi_pxe_ip_filter_t; -+ -+typedef struct { -+ grub_efi_pxe_ip_address_t ip_addr; -+ grub_efi_pxe_mac_address_t mac_addr; -+} grub_efi_pxe_arp_entry_t; -+ -+typedef struct { -+ grub_efi_pxe_ip_address_t ip_addr; -+ grub_efi_pxe_ip_address_t subnet_mask; -+ grub_efi_pxe_ip_address_t gw_addr; -+} grub_efi_pxe_route_entry_t; -+ -+ -+#define GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8 -+#define GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8 -+ - typedef struct grub_efi_pxe_mode - { - grub_efi_boolean_t started; -@@ -1605,9 +1622,9 @@ typedef struct grub_efi_pxe_mode - grub_efi_pxe_packet_t pxe_bis_reply; - grub_efi_pxe_ip_filter_t ip_filter; - grub_efi_uint32_t arp_cache_entries; -- grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_MAX_ARP_ENTRIES]; -+ grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES]; - grub_efi_uint32_t route_table_entries; -- grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_MAX_ROUTE_ENTRIES]; -+ grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES]; - grub_efi_pxe_icmp_error_t icmp_error; - grub_efi_pxe_tftp_error_t tftp_error; - } grub_efi_pxe_mode_t; diff --git a/0078-grub.texi-Add-net_bootp6-doument.patch b/0078-grub.texi-Add-net_bootp6-doument.patch deleted file mode 100644 index 3f8ec97..0000000 --- a/0078-grub.texi-Add-net_bootp6-doument.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Tue, 5 May 2015 14:19:24 +0800 -Subject: [PATCH] grub.texi: Add net_bootp6 doument - -Update grub documentation for net_bootp6 command. - -Signed-off-by: Michael Chang -Signed-off-by: Ken Lin ---- - docs/grub.texi | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/docs/grub.texi b/docs/grub.texi -index 0615d0ed97e..04ed6ac1f07 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -5487,6 +5487,7 @@ This command is only available on AArch64 systems. - * net_add_dns:: Add a DNS server - * net_add_route:: Add routing entry - * net_bootp:: Perform a bootp/DHCP autoconfiguration -+* net_bootp6:: Perform a DHCPv6 autoconfiguration - * net_del_addr:: Remove IP address from interface - * net_del_dns:: Remove a DNS server - * net_del_route:: Remove a route entry -@@ -5611,6 +5612,22 @@ Sets environment variable @samp{net_}@var{}@samp{_boot_file} - - @end deffn - -+@node net_bootp6 -+@subsection net_bootp6 -+ -+@deffn Command net_bootp6 [@var{card}] -+Perform configuration of @var{card} using DHCPv6 protocol. If no card name is -+specified, try to configure all existing cards. If configuration was -+successful, interface with name @var{card}@samp{:dhcp6} and configured address -+is added to @var{card}. -+ -+@table @samp -+@item 1 (Domain Name Server) -+Adds all servers from option value to the list of servers used during name -+resolution. -+@end table -+ -+@end deffn - - @node net_get_dhcp_option - @subsection net_get_dhcp_option diff --git a/0079-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch b/0079-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch deleted file mode 100644 index e800dd2..0000000 --- a/0079-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Wed, 10 Jul 2019 23:58:28 +0200 -Subject: [PATCH] bootp: Add processing DHCPACK packet from HTTP Boot - -The vendor class identifier with the string "HTTPClient" is used to denote the -packet as responding to HTTP boot request. In DHCP4 config, the filename for -HTTP boot is the URL of the boot file while for PXE boot it is the path to the -boot file. As a consequence, the next-server becomes obseleted because the HTTP -URL already contains the server address for the boot file. For DHCP6 config, -there's no difference definition in existing config as dhcp6.bootfile-url can -be used to specify URL for both HTTP and PXE boot file. - -This patch adds processing for "HTTPClient" vendor class identifier in DHCPACK -packet by treating it as HTTP format, not as the PXE format. - -Signed-off-by: Michael Chang -Signed-off-by: Ken Lin ---- - grub-core/net/bootp.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ - include/grub/net.h | 1 + - 2 files changed, 56 insertions(+) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index fe93b80f1cf..8fb8918ae7e 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -500,6 +501,60 @@ grub_net_configure_by_dhcp_ack (const char *name, - if (opt && opt_len) - grub_env_set_net_property (name, "rootpath", (const char *) opt, opt_len); - -+ opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER, &opt_len); -+ if (opt && opt_len) -+ { -+ grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len); -+ if (opt && grub_strcmp (opt, "HTTPClient") == 0) -+ { -+ char *proto, *ip, *pa; -+ -+ if (!dissect_url (bp->boot_file, &proto, &ip, &pa)) -+ return inter; -+ -+ grub_env_set_net_property (name, "boot_file", pa, grub_strlen (pa)); -+ if (is_def) -+ { -+ grub_net_default_server = grub_strdup (ip); -+ grub_env_set ("net_default_interface", name); -+ grub_env_export ("net_default_interface"); -+ } -+ if (device && !*device) -+ { -+ *device = grub_xasprintf ("%s,%s", proto, ip); -+ grub_print_error (); -+ } -+ if (path) -+ { -+ *path = grub_strdup (pa); -+ grub_print_error (); -+ if (*path) -+ { -+ char *slash; -+ slash = grub_strrchr (*path, '/'); -+ if (slash) -+ *slash = 0; -+ else -+ **path = 0; -+ } -+ } -+ grub_net_add_ipv4_local (inter, mask); -+ inter->dhcp_ack = grub_malloc (size); -+ if (inter->dhcp_ack) -+ { -+ grub_memcpy (inter->dhcp_ack, bp, size); -+ inter->dhcp_acklen = size; -+ } -+ else -+ grub_errno = GRUB_ERR_NONE; -+ -+ grub_free (proto); -+ grub_free (ip); -+ grub_free (pa); -+ return inter; -+ } -+ } -+ - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_EXTENSIONS_PATH, &opt_len); - if (opt && opt_len) - grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len); -diff --git a/include/grub/net.h b/include/grub/net.h -index 543251f7273..42af7de250a 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -531,6 +531,7 @@ enum - GRUB_NET_DHCP_MESSAGE_TYPE = 53, - GRUB_NET_DHCP_SERVER_IDENTIFIER = 54, - GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55, -+ GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 60, - GRUB_NET_BOOTP_CLIENT_ID = 61, - GRUB_NET_DHCP_TFTP_SERVER_NAME = 66, - GRUB_NET_DHCP_BOOTFILE_NAME = 67, diff --git a/0080-efinet-Setting-network-from-UEFI-device-path.patch b/0080-efinet-Setting-network-from-UEFI-device-path.patch deleted file mode 100644 index 11b2a72..0000000 --- a/0080-efinet-Setting-network-from-UEFI-device-path.patch +++ /dev/null @@ -1,405 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Sun, 10 Jul 2016 23:46:31 +0800 -Subject: [PATCH] efinet: Setting network from UEFI device path - -The PXE Base Code protocol used to obtain cached PXE DHCPACK packet is no -longer provided for HTTP Boot. Instead, we have to get the HTTP boot -information from the device path nodes defined in following UEFI Specification -sections. - - 9.3.5.12 IPv4 Device Path - 9.3.5.13 IPv6 Device Path - 9.3.5.23 Uniform Resource Identifiers (URI) Device Path - -This patch basically does: - -include/grub/efi/api.h: -Add new structure of Uniform Resource Identifiers (URI) Device Path - -grub-core/net/drivers/efi/efinet.c: -Check if PXE Base Code is available, if not it will try to obtain the netboot -information from the device path where the image booted from. The DHCPACK -packet is recoverd from the information in device patch and feed into the same -DHCP packet processing functions to ensure the network interface is setting up -the same way it used to be. - -Signed-off-by: Michael Chang -Signed-off-by: Ken Lin ---- - grub-core/net/drivers/efi/efinet.c | 284 +++++++++++++++++++++++++++++++++++-- - include/grub/efi/api.h | 11 ++ - 2 files changed, 280 insertions(+), 15 deletions(-) - -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 014e5bf9802..8171ecaa5e4 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -331,6 +332,227 @@ grub_efinet_findcards (void) - grub_free (handles); - } - -+static struct grub_net_buff * -+grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6) -+{ -+ grub_efi_uint16_t uri_len; -+ grub_efi_device_path_t *ldp, *ddp; -+ grub_efi_uri_device_path_t *uri_dp; -+ struct grub_net_buff *nb; -+ grub_err_t err; -+ -+ ddp = grub_efi_duplicate_device_path (dp); -+ if (!ddp) -+ return NULL; -+ -+ ldp = grub_efi_find_last_device_path (ddp); -+ -+ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE -+ || GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE) -+ { -+ grub_free (ddp); -+ return NULL; -+ } -+ -+ uri_len = GRUB_EFI_DEVICE_PATH_LENGTH (ldp) > 4 ? GRUB_EFI_DEVICE_PATH_LENGTH (ldp) - 4 : 0; -+ -+ if (!uri_len) -+ { -+ grub_free (ddp); -+ return NULL; -+ } -+ -+ uri_dp = (grub_efi_uri_device_path_t *) ldp; -+ -+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ ldp->length = sizeof (*ldp); -+ -+ ldp = grub_efi_find_last_device_path (ddp); -+ -+ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE -+ || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE -+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) -+ { -+ grub_free (ddp); -+ return NULL; -+ } -+ -+ nb = grub_netbuff_alloc (512); -+ if (!nb) -+ { -+ grub_free (ddp); -+ return NULL; -+ } -+ -+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE) -+ { -+ grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp; -+ struct grub_net_bootp_packet *bp; -+ grub_uint8_t *ptr; -+ -+ bp = (struct grub_net_bootp_packet *) nb->tail; -+ err = grub_netbuff_put (nb, sizeof (*bp) + 4); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ -+ if (sizeof(bp->boot_file) < uri_len) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ grub_memcpy (bp->boot_file, uri_dp->uri, uri_len); -+ grub_memcpy (&bp->your_ip, ipv4->local_ip_address, sizeof (bp->your_ip)); -+ grub_memcpy (&bp->server_ip, ipv4->remote_ip_address, sizeof (bp->server_ip)); -+ -+ bp->vendor[0] = GRUB_NET_BOOTP_RFC1048_MAGIC_0; -+ bp->vendor[1] = GRUB_NET_BOOTP_RFC1048_MAGIC_1; -+ bp->vendor[2] = GRUB_NET_BOOTP_RFC1048_MAGIC_2; -+ bp->vendor[3] = GRUB_NET_BOOTP_RFC1048_MAGIC_3; -+ -+ ptr = nb->tail; -+ err = grub_netbuff_put (nb, sizeof (ipv4->subnet_mask) + 2); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ *ptr++ = GRUB_NET_BOOTP_NETMASK; -+ *ptr++ = sizeof (ipv4->subnet_mask); -+ grub_memcpy (ptr, ipv4->subnet_mask, sizeof (ipv4->subnet_mask)); -+ -+ ptr = nb->tail; -+ err = grub_netbuff_put (nb, sizeof (ipv4->gateway_ip_address) + 2); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ *ptr++ = GRUB_NET_BOOTP_ROUTER; -+ *ptr++ = sizeof (ipv4->gateway_ip_address); -+ grub_memcpy (ptr, ipv4->gateway_ip_address, sizeof (ipv4->gateway_ip_address)); -+ -+ ptr = nb->tail; -+ err = grub_netbuff_put (nb, sizeof ("HTTPClient") + 1); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ *ptr++ = GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER; -+ *ptr++ = sizeof ("HTTPClient") - 1; -+ grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1); -+ -+ ptr = nb->tail; -+ err = grub_netbuff_put (nb, 1); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ *ptr = GRUB_NET_BOOTP_END; -+ *use_ipv6 = 0; -+ -+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ ldp->length = sizeof (*ldp); -+ ldp = grub_efi_find_last_device_path (ddp); -+ -+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE) -+ { -+ grub_efi_mac_address_device_path_t *mac = (grub_efi_mac_address_device_path_t *) ldp; -+ bp->hw_type = mac->if_type; -+ bp->hw_len = sizeof (bp->mac_addr); -+ grub_memcpy (bp->mac_addr, mac->mac_address, bp->hw_len); -+ } -+ } -+ else -+ { -+ grub_efi_ipv6_device_path_t *ipv6 = (grub_efi_ipv6_device_path_t *) ldp; -+ -+ struct grub_net_dhcp6_packet *d6p; -+ struct grub_net_dhcp6_option *opt; -+ struct grub_net_dhcp6_option_iana *iana; -+ struct grub_net_dhcp6_option_iaaddr *iaaddr; -+ -+ d6p = (struct grub_net_dhcp6_packet *)nb->tail; -+ err = grub_netbuff_put (nb, sizeof(*d6p)); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ d6p->message_type = GRUB_NET_DHCP6_REPLY; -+ -+ opt = (struct grub_net_dhcp6_option *)nb->tail; -+ err = grub_netbuff_put (nb, sizeof(*opt)); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA); -+ opt->len = grub_cpu_to_be16_compile_time (sizeof(*iana) + sizeof(*opt) + sizeof(*iaaddr)); -+ -+ err = grub_netbuff_put (nb, sizeof(*iana)); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ -+ opt = (struct grub_net_dhcp6_option *)nb->tail; -+ err = grub_netbuff_put (nb, sizeof(*opt)); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IAADDR); -+ opt->len = grub_cpu_to_be16_compile_time (sizeof (*iaaddr)); -+ -+ iaaddr = (struct grub_net_dhcp6_option_iaaddr *)nb->tail; -+ err = grub_netbuff_put (nb, sizeof(*iaaddr)); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ grub_memcpy (iaaddr->addr, ipv6->local_ip_address, sizeof(ipv6->local_ip_address)); -+ -+ opt = (struct grub_net_dhcp6_option *)nb->tail; -+ err = grub_netbuff_put (nb, sizeof(*opt) + uri_len); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_BOOTFILE_URL); -+ opt->len = grub_cpu_to_be16 (uri_len); -+ grub_memcpy (opt->data, uri_dp->uri, uri_len); -+ -+ *use_ipv6 = 1; -+ } -+ -+ grub_free (ddp); -+ return nb; -+} -+ - static void - grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - char **path) -@@ -346,7 +568,11 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - { - grub_efi_device_path_t *cdp; - struct grub_efi_pxe *pxe; -- struct grub_efi_pxe_mode *pxe_mode; -+ struct grub_efi_pxe_mode *pxe_mode = NULL; -+ grub_uint8_t *packet_buf; -+ grub_size_t packet_bufsz ; -+ int ipv6; -+ struct grub_net_buff *nb = NULL; - - if (card->driver != &efidriver) - continue; -@@ -370,11 +596,21 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - */ - if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE - || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE -- && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) -+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE -+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) - continue; - dup_dp = grub_efi_duplicate_device_path (dp); - if (!dup_dp) - continue; -+ -+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE) -+ { -+ dup_ldp = grub_efi_find_last_device_path (dup_dp); -+ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ dup_ldp->length = sizeof (*dup_ldp); -+ } -+ - dup_ldp = grub_efi_find_last_device_path (dup_dp); - dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -@@ -387,23 +623,37 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - - pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -- if (! pxe) -- continue; -+ if (!pxe) -+ { -+ nb = grub_efinet_create_dhcp_ack_from_device_path (dp, &ipv6); -+ if (!nb) -+ { -+ grub_print_error (); -+ continue; -+ } -+ packet_buf = nb->head; -+ packet_bufsz = nb->tail - nb->head; -+ } -+ else -+ { -+ pxe_mode = pxe->mode; -+ packet_buf = (grub_uint8_t *) &pxe_mode->dhcp_ack; -+ packet_bufsz = sizeof (pxe_mode->dhcp_ack); -+ ipv6 = pxe_mode->using_ipv6; -+ } - -- pxe_mode = pxe->mode; -- if (pxe_mode->using_ipv6) -+ if (ipv6) - { - grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); -- grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", -- pxe_mode->dhcp_ack_received ? "yes" : "no", -- pxe_mode->dhcp_ack_received ? "" : " cannot continue"); -- if (!pxe_mode->dhcp_ack_received) -- continue; -+ if (pxe_mode) -+ grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", -+ pxe_mode->dhcp_ack_received ? "yes" : "no", -+ pxe_mode->dhcp_ack_received ? "" : " cannot continue"); - - grub_net_configure_by_dhcpv6_reply (card->name, card, 0, - (struct grub_net_dhcp6_packet *) -- &pxe_mode->dhcp_ack, -- sizeof (pxe_mode->dhcp_ack), -+ packet_buf, -+ packet_bufsz, - 1, device, path); - if (grub_errno) - grub_print_error (); -@@ -417,11 +667,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - grub_dprintf ("efinet", "using ipv4 and dhcp\n"); - grub_net_configure_by_dhcp_ack (card->name, card, 0, - (struct grub_net_bootp_packet *) -- &pxe_mode->dhcp_ack, -- sizeof (pxe_mode->dhcp_ack), -+ packet_buf, -+ packet_bufsz, - 1, device, path); - grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); - } -+ -+ if (nb) -+ grub_netbuff_free (nb); -+ - return; - } - } -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 91ab528e4d0..4a51667adb1 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -864,6 +864,8 @@ struct grub_efi_ipv4_device_path - grub_efi_uint16_t remote_port; - grub_efi_uint16_t protocol; - grub_efi_uint8_t static_ip_address; -+ grub_efi_ipv4_address_t gateway_ip_address; -+ grub_efi_ipv4_address_t subnet_mask; - } GRUB_PACKED; - typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; - -@@ -918,6 +920,15 @@ struct grub_efi_sata_device_path - } GRUB_PACKED; - typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; - -+#define GRUB_EFI_URI_DEVICE_PATH_SUBTYPE 24 -+ -+struct grub_efi_uri_device_path -+{ -+ grub_efi_device_path_t header; -+ grub_efi_uint8_t uri[0]; -+} GRUB_PACKED; -+typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t; -+ - #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 - - /* Media Device Path. */ diff --git a/0081-efinet-Setting-DNS-server-from-UEFI-protocol.patch b/0081-efinet-Setting-DNS-server-from-UEFI-protocol.patch deleted file mode 100644 index 1460c8a..0000000 --- a/0081-efinet-Setting-DNS-server-from-UEFI-protocol.patch +++ /dev/null @@ -1,336 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 14 Jul 2016 17:48:45 +0800 -Subject: [PATCH] efinet: Setting DNS server from UEFI protocol - -In the URI device path node, any name rahter than address can be used for -looking up the resources so that DNS service become needed to get answer of the -name's address. Unfortunately the DNS is not defined in any of the device path -nodes so that we use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL -to obtain it. - -These two protcols are defined the sections of UEFI specification. - - 27.5 EFI IPv4 Configuration II Protocol - 27.7 EFI IPv6 Configuration Protocol - -include/grub/efi/api.h: -Add new structure and protocol UUID of EFI_IP4_CONFIG2_PROTOCOL and -EFI_IP6_CONFIG_PROTOCOL. - -grub-core/net/drivers/efi/efinet.c: -Use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL to obtain the list -of DNS server address for IPv4 and IPv6 respectively. The address of DNS -servers is structured into DHCPACK packet and feed into the same DHCP packet -processing functions to ensure the network interface is setting up the same way -it used to be. - -Signed-off-by: Michael Chang -Signed-off-by: Ken Lin ---- - grub-core/net/drivers/efi/efinet.c | 163 +++++++++++++++++++++++++++++++++++++ - include/grub/efi/api.h | 75 +++++++++++++++++ - 2 files changed, 238 insertions(+) - -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 8171ecaa5e4..715a6168d77 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -33,6 +33,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); - /* GUID. */ - static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; - static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; -+static grub_efi_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID; -+static grub_efi_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID; - - static grub_err_t - send_card_buffer (struct grub_net_card *dev, -@@ -332,6 +334,125 @@ grub_efinet_findcards (void) - grub_free (handles); - } - -+static grub_efi_handle_t -+grub_efi_locate_device_path (grub_efi_guid_t *protocol, grub_efi_device_path_t *device_path, -+ grub_efi_device_path_t **r_device_path) -+{ -+ grub_efi_handle_t handle; -+ grub_efi_status_t status; -+ -+ status = efi_call_3 (grub_efi_system_table->boot_services->locate_device_path, -+ protocol, &device_path, &handle); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ -+ if (r_device_path) -+ *r_device_path = device_path; -+ -+ return handle; -+} -+ -+static grub_efi_ipv4_address_t * -+grub_dns_server_ip4_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns) -+{ -+ grub_efi_handle_t hnd; -+ grub_efi_status_t status; -+ grub_efi_ip4_config2_protocol_t *conf; -+ grub_efi_ipv4_address_t *addrs; -+ grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv4_address_t); -+ -+ hnd = grub_efi_locate_device_path (&ip4_config_guid, dp, NULL); -+ -+ if (!hnd) -+ return 0; -+ -+ conf = grub_efi_open_protocol (hnd, &ip4_config_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ -+ if (!conf) -+ return 0; -+ -+ addrs = grub_malloc (data_size); -+ if (!addrs) -+ return 0; -+ -+ status = efi_call_4 (conf->get_data, conf, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, -+ &data_size, addrs); -+ -+ if (status == GRUB_EFI_BUFFER_TOO_SMALL) -+ { -+ grub_free (addrs); -+ addrs = grub_malloc (data_size); -+ if (!addrs) -+ return 0; -+ -+ status = efi_call_4 (conf->get_data, conf, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, -+ &data_size, addrs); -+ } -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (addrs); -+ return 0; -+ } -+ -+ *num_dns = data_size / sizeof (grub_efi_ipv4_address_t); -+ return addrs; -+} -+ -+static grub_efi_ipv6_address_t * -+grub_dns_server_ip6_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns) -+{ -+ grub_efi_handle_t hnd; -+ grub_efi_status_t status; -+ grub_efi_ip6_config_protocol_t *conf; -+ grub_efi_ipv6_address_t *addrs; -+ grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv6_address_t); -+ -+ hnd = grub_efi_locate_device_path (&ip6_config_guid, dp, NULL); -+ -+ if (!hnd) -+ return 0; -+ -+ conf = grub_efi_open_protocol (hnd, &ip6_config_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ -+ if (!conf) -+ return 0; -+ -+ addrs = grub_malloc (data_size); -+ if (!addrs) -+ return 0; -+ -+ status = efi_call_4 (conf->get_data, conf, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, -+ &data_size, addrs); -+ -+ if (status == GRUB_EFI_BUFFER_TOO_SMALL) -+ { -+ grub_free (addrs); -+ addrs = grub_malloc (data_size); -+ if (!addrs) -+ return 0; -+ -+ status = efi_call_4 (conf->get_data, conf, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, -+ &data_size, addrs); -+ } -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (addrs); -+ return 0; -+ } -+ -+ *num_dns = data_size / sizeof (grub_efi_ipv6_address_t); -+ return addrs; -+} -+ - static struct grub_net_buff * - grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6) - { -@@ -390,6 +511,8 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u - grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp; - struct grub_net_bootp_packet *bp; - grub_uint8_t *ptr; -+ grub_efi_ipv4_address_t *dns; -+ grub_efi_uintn_t num_dns; - - bp = (struct grub_net_bootp_packet *) nb->tail; - err = grub_netbuff_put (nb, sizeof (*bp) + 4); -@@ -451,6 +574,25 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u - *ptr++ = sizeof ("HTTPClient") - 1; - grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1); - -+ dns = grub_dns_server_ip4_address (dp, &num_dns); -+ if (dns) -+ { -+ grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns; -+ -+ ptr = nb->tail; -+ err = grub_netbuff_put (nb, size_dns + 2); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ *ptr++ = GRUB_NET_BOOTP_DNS; -+ *ptr++ = size_dns; -+ grub_memcpy (ptr, dns, size_dns); -+ grub_free (dns); -+ } -+ - ptr = nb->tail; - err = grub_netbuff_put (nb, 1); - if (err) -@@ -483,6 +625,8 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u - struct grub_net_dhcp6_option *opt; - struct grub_net_dhcp6_option_iana *iana; - struct grub_net_dhcp6_option_iaaddr *iaaddr; -+ grub_efi_ipv6_address_t *dns; -+ grub_efi_uintn_t num_dns; - - d6p = (struct grub_net_dhcp6_packet *)nb->tail; - err = grub_netbuff_put (nb, sizeof(*d6p)); -@@ -546,6 +690,25 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u - opt->len = grub_cpu_to_be16 (uri_len); - grub_memcpy (opt->data, uri_dp->uri, uri_len); - -+ dns = grub_dns_server_ip6_address (dp, &num_dns); -+ if (dns) -+ { -+ grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns; -+ -+ opt = (struct grub_net_dhcp6_option *)nb->tail; -+ err = grub_netbuff_put (nb, sizeof(*opt) + size_dns); -+ if (err) -+ { -+ grub_free (ddp); -+ grub_netbuff_free (nb); -+ return NULL; -+ } -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_DNS_SERVERS); -+ opt->len = grub_cpu_to_be16 (size_dns); -+ grub_memcpy (opt->data, dns, size_dns); -+ grub_free (dns); -+ } -+ - *use_ipv6 = 1; - } - -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 4a51667adb1..0b490195ad9 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -352,6 +352,15 @@ - #define GRUB_EFI_RNG_PROTOCOL_GUID \ - { 0x3152bca5, 0xeade, 0x433d, \ - { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \ -+ -+#define GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID \ -+ { 0x5b446ed1, 0xe30b, 0x4faa, \ -+ { 0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \ -+ } -+ -+#define GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID \ -+ { 0x937fe521, 0x95ae, 0x4d1a, \ -+ { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ - } - - struct grub_efi_sal_system_table -@@ -1883,6 +1892,72 @@ struct grub_efi_rng_protocol - }; - typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t; - -+enum grub_efi_ip4_config2_data_type { -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_POLICY, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_GATEWAY, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MAXIMUM -+}; -+typedef enum grub_efi_ip4_config2_data_type grub_efi_ip4_config2_data_type_t; -+ -+struct grub_efi_ip4_config2_protocol -+{ -+ grub_efi_status_t (*set_data) (struct grub_efi_ip4_config2_protocol *this, -+ grub_efi_ip4_config2_data_type_t data_type, -+ grub_efi_uintn_t data_size, -+ void *data); -+ -+ grub_efi_status_t (*get_data) (struct grub_efi_ip4_config2_protocol *this, -+ grub_efi_ip4_config2_data_type_t data_type, -+ grub_efi_uintn_t *data_size, -+ void *data); -+ -+ grub_efi_status_t (*register_data_notify) (struct grub_efi_ip4_config2_protocol *this, -+ grub_efi_ip4_config2_data_type_t data_type, -+ grub_efi_event_t event); -+ -+ grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip4_config2_protocol *this, -+ grub_efi_ip4_config2_data_type_t data_type, -+ grub_efi_event_t event); -+}; -+typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t; -+ -+enum grub_efi_ip6_config_data_type { -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_POLICY, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DUP_ADDR_DETECT_TRANSMITS, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_GATEWAY, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MAXIMUM -+}; -+typedef enum grub_efi_ip6_config_data_type grub_efi_ip6_config_data_type_t; -+ -+struct grub_efi_ip6_config_protocol -+{ -+ grub_efi_status_t (*set_data) (struct grub_efi_ip6_config_protocol *this, -+ grub_efi_ip6_config_data_type_t data_type, -+ grub_efi_uintn_t data_size, -+ void *data); -+ -+ grub_efi_status_t (*get_data) (struct grub_efi_ip6_config_protocol *this, -+ grub_efi_ip6_config_data_type_t data_type, -+ grub_efi_uintn_t *data_size, -+ void *data); -+ -+ grub_efi_status_t (*register_data_notify) (struct grub_efi_ip6_config_protocol *this, -+ grub_efi_ip6_config_data_type_t data_type, -+ grub_efi_event_t event); -+ -+ grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip6_config_protocol *this, -+ grub_efi_ip6_config_data_type_t data_type, -+ grub_efi_event_t event); -+}; -+typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t; -+ - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ - || defined(__riscv) diff --git a/0082-Support-UEFI-networking-protocols.patch b/0082-Support-UEFI-networking-protocols.patch deleted file mode 100644 index fb14386..0000000 --- a/0082-Support-UEFI-networking-protocols.patch +++ /dev/null @@ -1,5053 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Wed, 22 Feb 2017 14:27:50 +0800 -Subject: [PATCH] Support UEFI networking protocols - -References: fate#320130, bsc#1015589, bsc#1076132 -Patch-Mainline: no - -V1: - * Add preliminary support of UEFI networking protocols - * Support UEFI HTTPS Boot - -V2: - * Workaround http data access in firmware - * Fix DNS device path parsing for efinet device - * Relaxed UEFI Protocol requirement - * Support Intel OPA (Omni-Path Architecture) PXE Boot - -V3: - * Fix bufio in calculating address of next_buf - * Check HTTP respond code - * Use HEAD request method to test before GET - * Finish HTTP transaction in one go - * Fix bsc#1076132 - -Signed-off-by: Michael Chang -[pjones: make efi_netfs not duplicate symbols from efinet] -Signed-off-by: Peter Jones ---- - grub-core/Makefile.core.def | 12 + - grub-core/io/bufio.c | 2 +- - grub-core/kern/efi/efi.c | 96 ++- - grub-core/net/drivers/efi/efinet.c | 27 + - grub-core/net/efi/dhcp.c | 397 ++++++++++ - grub-core/net/efi/efi_netfs.c | 57 ++ - grub-core/net/efi/http.c | 419 +++++++++++ - grub-core/net/efi/ip4_config.c | 398 ++++++++++ - grub-core/net/efi/ip6_config.c | 422 +++++++++++ - grub-core/net/efi/net.c | 1428 ++++++++++++++++++++++++++++++++++++ - grub-core/net/efi/pxe.c | 424 +++++++++++ - grub-core/net/net.c | 74 ++ - util/grub-mknetdir.c | 23 +- - include/grub/efi/api.h | 180 ++++- - include/grub/efi/dhcp.h | 343 +++++++++ - include/grub/efi/http.h | 215 ++++++ - include/grub/net/efi.h | 144 ++++ - 17 files changed, 4620 insertions(+), 41 deletions(-) - create mode 100644 grub-core/net/efi/dhcp.c - create mode 100644 grub-core/net/efi/efi_netfs.c - create mode 100644 grub-core/net/efi/http.c - create mode 100644 grub-core/net/efi/ip4_config.c - create mode 100644 grub-core/net/efi/ip6_config.c - create mode 100644 grub-core/net/efi/net.c - create mode 100644 grub-core/net/efi/pxe.c - create mode 100644 include/grub/efi/dhcp.h - create mode 100644 include/grub/efi/http.h - create mode 100644 include/grub/net/efi.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 4b7c45a7b06..c40170f2dd2 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2299,6 +2299,12 @@ module = { - common = hook/datehook.c; - }; - -+module = { -+ name = efi_netfs; -+ common = net/efi/efi_netfs.c; -+ enable = efi; -+}; -+ - module = { - name = net; - common = net/net.c; -@@ -2312,6 +2318,12 @@ module = { - common = net/ethernet.c; - common = net/arp.c; - common = net/netbuff.c; -+ efi = net/efi/net.c; -+ efi = net/efi/http.c; -+ efi = net/efi/pxe.c; -+ efi = net/efi/ip4_config.c; -+ efi = net/efi/ip6_config.c; -+ efi = net/efi/dhcp.c; - }; - - module = { -diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c -index a458c3aca78..1637731535e 100644 ---- a/grub-core/io/bufio.c -+++ b/grub-core/io/bufio.c -@@ -139,7 +139,7 @@ grub_bufio_read (grub_file_t file, char *buf, grub_size_t len) - return res; - - /* Need to read some more. */ -- next_buf = (file->offset + res + len - 1) & ~((grub_off_t) bufio->block_size - 1); -+ next_buf = (grub_divmod64 (file->offset + res + len - 1, bufio->block_size, NULL)) * bufio->block_size; - /* Now read between file->offset + res and bufio->buffer_at. */ - if (file->offset + res < next_buf) - { -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index d6a2fb57789..2a446f5031b 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -755,7 +755,7 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) - { - grub_efi_ipv4_device_path_t *ipv4 - = (grub_efi_ipv4_device_path_t *) dp; -- grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x)", -+ grub_printf ("/IPv4(%u.%u.%u.%u,%u.%u.%u.%u,%u,%u,%x,%x", - (unsigned) ipv4->local_ip_address[0], - (unsigned) ipv4->local_ip_address[1], - (unsigned) ipv4->local_ip_address[2], -@@ -768,33 +768,60 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) - (unsigned) ipv4->remote_port, - (unsigned) ipv4->protocol, - (unsigned) ipv4->static_ip_address); -+ if (len == sizeof (*ipv4)) -+ { -+ grub_printf (",%u.%u.%u.%u,%u.%u.%u.%u", -+ (unsigned) ipv4->gateway_ip_address[0], -+ (unsigned) ipv4->gateway_ip_address[1], -+ (unsigned) ipv4->gateway_ip_address[2], -+ (unsigned) ipv4->gateway_ip_address[3], -+ (unsigned) ipv4->subnet_mask[0], -+ (unsigned) ipv4->subnet_mask[1], -+ (unsigned) ipv4->subnet_mask[2], -+ (unsigned) ipv4->subnet_mask[3]); -+ } -+ grub_printf (")"); - } - break; - case GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE: - { - grub_efi_ipv6_device_path_t *ipv6 - = (grub_efi_ipv6_device_path_t *) dp; -- grub_printf ("/IPv6(%x:%x:%x:%x:%x:%x:%x:%x,%x:%x:%x:%x:%x:%x:%x:%x,%u,%u,%x,%x)", -- (unsigned) ipv6->local_ip_address[0], -- (unsigned) ipv6->local_ip_address[1], -- (unsigned) ipv6->local_ip_address[2], -- (unsigned) ipv6->local_ip_address[3], -- (unsigned) ipv6->local_ip_address[4], -- (unsigned) ipv6->local_ip_address[5], -- (unsigned) ipv6->local_ip_address[6], -- (unsigned) ipv6->local_ip_address[7], -- (unsigned) ipv6->remote_ip_address[0], -- (unsigned) ipv6->remote_ip_address[1], -- (unsigned) ipv6->remote_ip_address[2], -- (unsigned) ipv6->remote_ip_address[3], -- (unsigned) ipv6->remote_ip_address[4], -- (unsigned) ipv6->remote_ip_address[5], -- (unsigned) ipv6->remote_ip_address[6], -- (unsigned) ipv6->remote_ip_address[7], -+ grub_printf ("/IPv6(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x,%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x,%u,%u,%x,%x", -+ (unsigned) grub_be_to_cpu16 (ipv6->local_ip_address[0]), -+ (unsigned) grub_be_to_cpu16 (ipv6->local_ip_address[1]), -+ (unsigned) grub_be_to_cpu16 (ipv6->local_ip_address[2]), -+ (unsigned) grub_be_to_cpu16 (ipv6->local_ip_address[3]), -+ (unsigned) grub_be_to_cpu16 (ipv6->local_ip_address[4]), -+ (unsigned) grub_be_to_cpu16 (ipv6->local_ip_address[5]), -+ (unsigned) grub_be_to_cpu16 (ipv6->local_ip_address[6]), -+ (unsigned) grub_be_to_cpu16 (ipv6->local_ip_address[7]), -+ (unsigned) grub_be_to_cpu16 (ipv6->remote_ip_address[0]), -+ (unsigned) grub_be_to_cpu16 (ipv6->remote_ip_address[1]), -+ (unsigned) grub_be_to_cpu16 (ipv6->remote_ip_address[2]), -+ (unsigned) grub_be_to_cpu16 (ipv6->remote_ip_address[3]), -+ (unsigned) grub_be_to_cpu16 (ipv6->remote_ip_address[4]), -+ (unsigned) grub_be_to_cpu16 (ipv6->remote_ip_address[5]), -+ (unsigned) grub_be_to_cpu16 (ipv6->remote_ip_address[6]), -+ (unsigned) grub_be_to_cpu16 (ipv6->remote_ip_address[7]), - (unsigned) ipv6->local_port, - (unsigned) ipv6->remote_port, - (unsigned) ipv6->protocol, - (unsigned) ipv6->static_ip_address); -+ if (len == sizeof (*ipv6)) -+ { -+ grub_printf (",%u,%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", -+ (unsigned) ipv6->prefix_length, -+ (unsigned) grub_be_to_cpu16 (ipv6->gateway_ip_address[0]), -+ (unsigned) grub_be_to_cpu16 (ipv6->gateway_ip_address[1]), -+ (unsigned) grub_be_to_cpu16 (ipv6->gateway_ip_address[2]), -+ (unsigned) grub_be_to_cpu16 (ipv6->gateway_ip_address[3]), -+ (unsigned) grub_be_to_cpu16 (ipv6->gateway_ip_address[4]), -+ (unsigned) grub_be_to_cpu16 (ipv6->gateway_ip_address[5]), -+ (unsigned) grub_be_to_cpu16 (ipv6->gateway_ip_address[6]), -+ (unsigned) grub_be_to_cpu16 (ipv6->gateway_ip_address[7])); -+ } -+ grub_printf (")"); - } - break; - case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE: -@@ -834,6 +861,39 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) - dump_vendor_path ("Messaging", - (grub_efi_vendor_device_path_t *) dp); - break; -+ case GRUB_EFI_URI_DEVICE_PATH_SUBTYPE: -+ { -+ grub_efi_uri_device_path_t *uri -+ = (grub_efi_uri_device_path_t *) dp; -+ grub_printf ("/URI(%s)", uri->uri); -+ } -+ break; -+ case GRUB_EFI_DNS_DEVICE_PATH_SUBTYPE: -+ { -+ grub_efi_dns_device_path_t *dns -+ = (grub_efi_dns_device_path_t *) dp; -+ if (dns->is_ipv6) -+ { -+ grub_printf ("/DNS(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x)", -+ (grub_uint16_t)(grub_be_to_cpu32(dns->dns_server_ip[0].addr[0]) >> 16), -+ (grub_uint16_t)(grub_be_to_cpu32(dns->dns_server_ip[0].addr[0])), -+ (grub_uint16_t)(grub_be_to_cpu32(dns->dns_server_ip[0].addr[1]) >> 16), -+ (grub_uint16_t)(grub_be_to_cpu32(dns->dns_server_ip[0].addr[1])), -+ (grub_uint16_t)(grub_be_to_cpu32(dns->dns_server_ip[0].addr[2]) >> 16), -+ (grub_uint16_t)(grub_be_to_cpu32(dns->dns_server_ip[0].addr[2])), -+ (grub_uint16_t)(grub_be_to_cpu32(dns->dns_server_ip[0].addr[3]) >> 16), -+ (grub_uint16_t)(grub_be_to_cpu32(dns->dns_server_ip[0].addr[3]))); -+ } -+ else -+ { -+ grub_printf ("/DNS(%d.%d.%d.%d)", -+ dns->dns_server_ip[0].v4.addr[0], -+ dns->dns_server_ip[0].v4.addr[1], -+ dns->dns_server_ip[0].v4.addr[2], -+ dns->dns_server_ip[0].v4.addr[3]); -+ } -+ } -+ break; - default: - grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype); - break; -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 715a6168d77..e11d759f19a 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -491,6 +492,17 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u - - ldp = grub_efi_find_last_device_path (ddp); - -+ /* Skip the DNS Device */ -+ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE -+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_DNS_DEVICE_PATH_SUBTYPE) -+ { -+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ ldp->length = sizeof (*ldp); -+ -+ ldp = grub_efi_find_last_device_path (ddp); -+ } -+ - if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE - || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) -@@ -760,6 +772,7 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE - || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE -+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_DNS_DEVICE_PATH_SUBTYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) - continue; - dup_dp = grub_efi_duplicate_device_path (dp); -@@ -774,6 +787,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - dup_ldp->length = sizeof (*dup_ldp); - } - -+ dup_ldp = grub_efi_find_last_device_path (dup_dp); -+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_DNS_DEVICE_PATH_SUBTYPE) -+ { -+ dup_ldp = grub_efi_find_last_device_path (dup_dp); -+ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ dup_ldp->length = sizeof (*dup_ldp); -+ } -+ - dup_ldp = grub_efi_find_last_device_path (dup_dp); - dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; - dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -@@ -845,6 +867,9 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - - GRUB_MOD_INIT(efinet) - { -+ if (grub_efi_net_config) -+ return; -+ - grub_efinet_findcards (); - grub_efi_net_config = grub_efi_net_config_real; - } -@@ -856,5 +881,7 @@ GRUB_MOD_FINI(efinet) - FOR_NET_CARDS_SAFE (card, next) - if (card->driver == &efidriver) - grub_net_card_unregister (card); -+ -+ grub_efi_net_config = NULL; - } - -diff --git a/grub-core/net/efi/dhcp.c b/grub-core/net/efi/dhcp.c -new file mode 100644 -index 00000000000..dbef63d8c08 ---- /dev/null -+++ b/grub-core/net/efi/dhcp.c -@@ -0,0 +1,397 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef GRUB_EFI_NET_DEBUG -+static void -+dhcp4_mode_print (grub_efi_dhcp4_mode_data_t *mode) -+{ -+ switch (mode->state) -+ { -+ case GRUB_EFI_DHCP4_STOPPED: -+ grub_printf ("STATE: STOPPED\n"); -+ break; -+ case GRUB_EFI_DHCP4_INIT: -+ grub_printf ("STATE: INIT\n"); -+ break; -+ case GRUB_EFI_DHCP4_SELECTING: -+ grub_printf ("STATE: SELECTING\n"); -+ break; -+ case GRUB_EFI_DHCP4_REQUESTING: -+ grub_printf ("STATE: REQUESTING\n"); -+ break; -+ case GRUB_EFI_DHCP4_BOUND: -+ grub_printf ("STATE: BOUND\n"); -+ break; -+ case GRUB_EFI_DHCP4_RENEWING: -+ grub_printf ("STATE: RENEWING\n"); -+ break; -+ case GRUB_EFI_DHCP4_REBINDING: -+ grub_printf ("STATE: REBINDING\n"); -+ break; -+ case GRUB_EFI_DHCP4_INIT_REBOOT: -+ grub_printf ("STATE: INIT_REBOOT\n"); -+ break; -+ case GRUB_EFI_DHCP4_REBOOTING: -+ grub_printf ("STATE: REBOOTING\n"); -+ break; -+ default: -+ grub_printf ("STATE: UNKNOWN\n"); -+ break; -+ } -+ -+ grub_printf ("CLIENT_ADDRESS: %u.%u.%u.%u\n", -+ mode->client_address[0], -+ mode->client_address[1], -+ mode->client_address[2], -+ mode->client_address[3]); -+ grub_printf ("SERVER_ADDRESS: %u.%u.%u.%u\n", -+ mode->server_address[0], -+ mode->server_address[1], -+ mode->server_address[2], -+ mode->server_address[3]); -+ grub_printf ("SUBNET_MASK: %u.%u.%u.%u\n", -+ mode->subnet_mask[0], -+ mode->subnet_mask[1], -+ mode->subnet_mask[2], -+ mode->subnet_mask[3]); -+ grub_printf ("ROUTER_ADDRESS: %u.%u.%u.%u\n", -+ mode->router_address[0], -+ mode->router_address[1], -+ mode->router_address[2], -+ mode->router_address[3]); -+} -+#endif -+ -+static grub_efi_ipv4_address_t * -+grub_efi_dhcp4_parse_dns (grub_efi_dhcp4_protocol_t *dhcp4, grub_efi_dhcp4_packet_t *reply_packet) -+{ -+ grub_efi_dhcp4_packet_option_t **option_list; -+ grub_efi_status_t status; -+ grub_efi_uint32_t option_count = 0; -+ grub_efi_uint32_t i; -+ -+ status = efi_call_4 (dhcp4->parse, dhcp4, reply_packet, &option_count, NULL); -+ -+ if (status != GRUB_EFI_BUFFER_TOO_SMALL) -+ return NULL; -+ -+ option_list = grub_malloc (option_count * sizeof(*option_list)); -+ if (!option_list) -+ return NULL; -+ -+ status = efi_call_4 (dhcp4->parse, dhcp4, reply_packet, &option_count, option_list); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (option_list); -+ return NULL; -+ } -+ -+ for (i = 0; i < option_count; ++i) -+ { -+ if (option_list[i]->op_code == 6) -+ { -+ grub_efi_ipv4_address_t *dns_address; -+ -+ if (((option_list[i]->length & 0x3) != 0) || (option_list[i]->length == 0)) -+ continue; -+ -+ /* We only contact primary dns */ -+ dns_address = grub_malloc (sizeof (*dns_address)); -+ if (!dns_address) -+ { -+ grub_free (option_list); -+ return NULL; -+ } -+ grub_memcpy (dns_address, option_list[i]->data, sizeof (dns_address)); -+ grub_free (option_list); -+ return dns_address; -+ } -+ } -+ -+ grub_free (option_list); -+ return NULL; -+} -+ -+#if 0 -+/* Somehow this doesn't work ... */ -+static grub_err_t -+grub_cmd_efi_bootp (struct grub_command *cmd __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **args __attribute__ ((unused))) -+{ -+ struct grub_efi_net_device *dev; -+ for (dev = net_devices; dev; dev = dev->next) -+ { -+ grub_efi_pxe_t *pxe = dev->ip4_pxe; -+ grub_efi_pxe_mode_t *mode = pxe->mode; -+ grub_efi_status_t status; -+ -+ if (!mode->started) -+ { -+ status = efi_call_2 (pxe->start, pxe, 0); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ grub_printf ("Couldn't start PXE\n"); -+ } -+ -+ status = efi_call_2 (pxe->dhcp, pxe, 0); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("dhcp4 configure failed, %d\n", (int)status); -+ continue; -+ } -+ -+ dev->prefer_ip6 = 0; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+#endif -+ -+static grub_err_t -+grub_cmd_efi_bootp (struct grub_command *cmd __attribute__ ((unused)), -+ int argc, -+ char **args) -+{ -+ struct grub_efi_net_device *netdev; -+ -+ for (netdev = net_devices; netdev; netdev = netdev->next) -+ { -+ grub_efi_status_t status; -+ grub_efi_dhcp4_mode_data_t mode; -+ grub_efi_dhcp4_config_data_t config; -+ grub_efi_dhcp4_packet_option_t *options; -+ grub_efi_ipv4_address_t *dns_address; -+ grub_efi_net_ip_manual_address_t net_ip; -+ grub_efi_net_ip_address_t ip_addr; -+ grub_efi_net_interface_t *inf = NULL; -+ -+ if (argc > 0 && grub_strcmp (netdev->card_name, args[0]) != 0) -+ continue; -+ -+ grub_memset (&config, 0, sizeof(config)); -+ -+ config.option_count = 1; -+ options = grub_malloc (sizeof(*options) + 2); -+ /* Parameter request list */ -+ options->op_code = 55; -+ options->length = 3; -+ /* subnet mask */ -+ options->data[0] = 1; -+ /* router */ -+ options->data[1] = 3; -+ /* DNS */ -+ options->data[2] = 6; -+ config.option_list = &options; -+ -+ /* FIXME: What if the dhcp has bounded */ -+ status = efi_call_2 (netdev->dhcp4->configure, netdev->dhcp4, &config); -+ grub_free (options); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("dhcp4 configure failed, %d\n", (int)status); -+ continue; -+ } -+ -+ status = efi_call_2 (netdev->dhcp4->start, netdev->dhcp4, NULL); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("dhcp4 start failed, %d\n", (int)status); -+ continue; -+ } -+ -+ status = efi_call_2 (netdev->dhcp4->get_mode_data, netdev->dhcp4, &mode); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("dhcp4 get mode failed, %d\n", (int)status); -+ continue; -+ } -+ -+#ifdef GRUB_EFI_NET_DEBUG -+ dhcp4_mode_print (&mode); -+#endif -+ -+ for (inf = netdev->net_interfaces; inf; inf = inf->next) -+ if (inf->prefer_ip6 == 0) -+ break; -+ -+ grub_memcpy (net_ip.ip4.address, mode.client_address, sizeof (net_ip.ip4.address)); -+ grub_memcpy (net_ip.ip4.subnet_mask, mode.subnet_mask, sizeof (net_ip.ip4.subnet_mask)); -+ -+ if (!inf) -+ { -+ char *name = grub_xasprintf ("%s:dhcp", netdev->card_name); -+ -+ net_ip.is_ip6 = 0; -+ inf = grub_efi_net_create_interface (netdev, -+ name, -+ &net_ip, -+ 1); -+ grub_free (name); -+ } -+ else -+ { -+ efi_net_interface_set_address (inf, &net_ip, 1); -+ } -+ -+ grub_memcpy (ip_addr.ip4, mode.router_address, sizeof (ip_addr.ip4)); -+ efi_net_interface_set_gateway (inf, &ip_addr); -+ -+ dns_address = grub_efi_dhcp4_parse_dns (netdev->dhcp4, mode.reply_packet); -+ if (dns_address) -+ efi_net_interface_set_dns (inf, (grub_efi_net_ip_address_t *)&dns_address); -+ -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+ -+static grub_err_t -+grub_cmd_efi_bootp6 (struct grub_command *cmd __attribute__ ((unused)), -+ int argc, -+ char **args) -+{ -+ struct grub_efi_net_device *dev; -+ grub_efi_uint32_t ia_id; -+ -+ for (dev = net_devices, ia_id = 0; dev; dev = dev->next, ia_id++) -+ { -+ grub_efi_dhcp6_config_data_t config; -+ grub_efi_dhcp6_packet_option_t *option_list[1]; -+ grub_efi_dhcp6_packet_option_t *opt; -+ grub_efi_status_t status; -+ grub_efi_dhcp6_mode_data_t mode; -+ grub_efi_dhcp6_retransmission_t retrans; -+ grub_efi_net_ip_manual_address_t net_ip; -+ grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; -+ grub_efi_net_interface_t *inf = NULL; -+ -+ if (argc > 0 && grub_strcmp (dev->card_name, args[0]) != 0) -+ continue; -+ -+ opt = grub_malloc (sizeof(*opt) + 2 * sizeof (grub_efi_uint16_t)); -+ -+#define GRUB_EFI_DHCP6_OPT_ORO 6 -+ -+ opt->op_code = grub_cpu_to_be16_compile_time (GRUB_EFI_DHCP6_OPT_ORO); -+ opt->op_len = grub_cpu_to_be16_compile_time (2 * sizeof (grub_efi_uint16_t)); -+ -+#define GRUB_EFI_DHCP6_OPT_BOOT_FILE_URL 59 -+#define GRUB_EFI_DHCP6_OPT_DNS_SERVERS 23 -+ -+ grub_set_unaligned16 (opt->data, grub_cpu_to_be16_compile_time(GRUB_EFI_DHCP6_OPT_BOOT_FILE_URL)); -+ grub_set_unaligned16 (opt->data + 1 * sizeof (grub_efi_uint16_t), -+ grub_cpu_to_be16_compile_time(GRUB_EFI_DHCP6_OPT_DNS_SERVERS)); -+ -+ option_list[0] = opt; -+ retrans.irt = 4; -+ retrans.mrc = 4; -+ retrans.mrt = 32; -+ retrans.mrd = 60; -+ -+ config.dhcp6_callback = NULL; -+ config.callback_context = NULL; -+ config.option_count = 1; -+ config.option_list = option_list; -+ config.ia_descriptor.ia_id = ia_id; -+ config.ia_descriptor.type = GRUB_EFI_DHCP6_IA_TYPE_NA; -+ config.ia_info_event = NULL; -+ config.reconfigure_accept = 0; -+ config.rapid_commit = 0; -+ config.solicit_retransmission = &retrans; -+ -+ status = efi_call_2 (dev->dhcp6->configure, dev->dhcp6, &config); -+ grub_free (opt); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("dhcp6 configure failed, %d\n", (int)status); -+ continue; -+ } -+ status = efi_call_1 (dev->dhcp6->start, dev->dhcp6); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("dhcp6 start failed, %d\n", (int)status); -+ continue; -+ } -+ -+ status = efi_call_3 (dev->dhcp6->get_mode_data, dev->dhcp6, &mode, NULL); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("dhcp4 get mode failed, %d\n", (int)status); -+ continue; -+ } -+ -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ if (inf->prefer_ip6 == 1) -+ break; -+ -+ grub_memcpy (net_ip.ip6.address, mode.ia->ia_address[0].ip_address, sizeof (net_ip.ip6.address)); -+ net_ip.ip6.prefix_length = 64; -+ net_ip.ip6.is_anycast = 0; -+ net_ip.is_ip6 = 1; -+ -+ if (!inf) -+ { -+ char *name = grub_xasprintf ("%s:dhcp", dev->card_name); -+ -+ inf = grub_efi_net_create_interface (dev, -+ name, -+ &net_ip, -+ 1); -+ grub_free (name); -+ } -+ else -+ { -+ efi_net_interface_set_address (inf, &net_ip, 1); -+ } -+ -+ { -+ grub_efi_uint32_t count = 0; -+ grub_efi_dhcp6_packet_option_t **options = NULL; -+ grub_efi_uint32_t i; -+ -+ status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, NULL); -+ -+ if (status == GRUB_EFI_BUFFER_TOO_SMALL && count) -+ { -+ options = grub_malloc (count * sizeof(*options)); -+ status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options); -+ } -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ if (options) -+ grub_free (options); -+ continue; -+ } -+ -+ for (i = 0; i < count; ++i) -+ { -+ if (options[i]->op_code == grub_cpu_to_be16_compile_time(GRUB_EFI_DHCP6_OPT_DNS_SERVERS)) -+ { -+ grub_efi_net_ip_address_t dns; -+ grub_memcpy (dns.ip6, options[i]->data, sizeof(net_ip.ip6)); -+ efi_net_interface_set_dns (inf, &dns); -+ break; -+ } -+ } -+ -+ if (options) -+ grub_free (options); -+ } -+ -+ efi_call_1 (b->free_pool, mode.client_id); -+ efi_call_1 (b->free_pool, mode.ia); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_command_func_t grub_efi_net_bootp = grub_cmd_efi_bootp; -+grub_command_func_t grub_efi_net_bootp6 = grub_cmd_efi_bootp6; -diff --git a/grub-core/net/efi/efi_netfs.c b/grub-core/net/efi/efi_netfs.c -new file mode 100644 -index 00000000000..ef371d885ea ---- /dev/null -+++ b/grub-core/net/efi/efi_netfs.c -@@ -0,0 +1,57 @@ -+#include -+#include -+#define EFI_NET_CMD_PREFIX "net_efi" -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_command_t cmd_efi_lsroutes; -+static grub_command_t cmd_efi_lscards; -+static grub_command_t cmd_efi_lsaddrs; -+static grub_command_t cmd_efi_addaddr; -+static grub_command_t cmd_efi_bootp; -+static grub_command_t cmd_efi_bootp6; -+ -+static int initialized; -+ -+GRUB_MOD_INIT(efi_netfs) -+{ -+ if (grub_net_open) -+ return; -+ -+ if (grub_efi_net_fs_init ()) -+ { -+ cmd_efi_lsroutes = grub_register_command ("net_efi_ls_routes", grub_efi_net_list_routes, -+ "", N_("list network routes")); -+ cmd_efi_lscards = grub_register_command ("net_efi_ls_cards", grub_efi_net_list_cards, -+ "", N_("list network cards")); -+ cmd_efi_lsaddrs = grub_register_command ("net_efi_ls_addr", grub_efi_net_list_addrs, -+ "", N_("list network addresses")); -+ cmd_efi_addaddr = grub_register_command ("net_efi_add_addr", grub_efi_net_add_addr, -+ N_("SHORTNAME CARD ADDRESS [HWADDRESS]"), -+ N_("Add a network address.")); -+ cmd_efi_bootp = grub_register_command ("net_efi_bootp", grub_efi_net_bootp, -+ N_("[CARD]"), -+ N_("perform a bootp autoconfiguration")); -+ cmd_efi_bootp6 = grub_register_command ("net_efi_bootp6", grub_efi_net_bootp6, -+ N_("[CARD]"), -+ N_("perform a bootp autoconfiguration")); -+ initialized = 1; -+ } -+} -+ -+GRUB_MOD_FINI(efi_netfs) -+{ -+ if (initialized) -+ { -+ grub_unregister_command (cmd_efi_lsroutes); -+ grub_unregister_command (cmd_efi_lscards); -+ grub_unregister_command (cmd_efi_lsaddrs); -+ grub_unregister_command (cmd_efi_addaddr); -+ grub_unregister_command (cmd_efi_bootp); -+ grub_unregister_command (cmd_efi_bootp6); -+ grub_efi_net_fs_fini (); -+ initialized = 0; -+ return; -+ } -+} -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -new file mode 100644 -index 00000000000..3f61fd2fa5b ---- /dev/null -+++ b/grub-core/net/efi/http.c -@@ -0,0 +1,419 @@ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static void -+http_configure (struct grub_efi_net_device *dev, int prefer_ip6) -+{ -+ grub_efi_http_config_data_t http_config; -+ grub_efi_httpv4_access_point_t httpv4_node; -+ grub_efi_httpv6_access_point_t httpv6_node; -+ grub_efi_status_t status; -+ -+ grub_efi_http_t *http = dev->http; -+ -+ grub_memset (&http_config, 0, sizeof(http_config)); -+ http_config.http_version = GRUB_EFI_HTTPVERSION11; -+ http_config.timeout_millisec = 5000; -+ -+ if (prefer_ip6) -+ { -+ grub_efi_uintn_t sz; -+ grub_efi_ip6_config_manual_address_t manual_address; -+ -+ http_config.local_address_is_ipv6 = 1; -+ sz = sizeof (manual_address); -+ status = efi_call_4 (dev->ip6_config->get_data, dev->ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, -+ &sz, &manual_address); -+ -+ if (status == GRUB_EFI_NOT_FOUND) -+ { -+ grub_printf ("The MANUAL ADDRESS is not found\n"); -+ } -+ -+ /* FIXME: The manual interface would return BUFFER TOO SMALL !!! */ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("??? %d\n",(int) status); -+ return; -+ } -+ -+ grub_memcpy (httpv6_node.local_address, manual_address.address, sizeof (httpv6_node.local_address)); -+ httpv6_node.local_port = 0; -+ http_config.access_point.ipv6_node = &httpv6_node; -+ } -+ else -+ { -+ http_config.local_address_is_ipv6 = 0; -+ grub_memset (&httpv4_node, 0, sizeof(httpv4_node)); -+ httpv4_node.use_default_address = 1; -+ -+ /* Use random port here */ -+ /* See TcpBind() in edk2/NetworkPkg/TcpDxe/TcpDispatcher.c */ -+ httpv4_node.local_port = 0; -+ http_config.access_point.ipv4_node = &httpv4_node; -+ } -+ -+ status = efi_call_2 (http->configure, http, &http_config); -+ -+ if (status == GRUB_EFI_ALREADY_STARTED) -+ { -+ /* XXX: This hangs HTTPS boot */ -+#if 0 -+ if (efi_call_2 (http->configure, http, NULL) != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_IO, N_("couldn't reset http instance")); -+ grub_print_error (); -+ return; -+ } -+ status = efi_call_2 (http->configure, http, &http_config); -+#endif -+ return; -+ } -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_IO, N_("couldn't configure http protocol, reason: %d"), (int)status); -+ grub_print_error (); -+ return ; -+ } -+} -+ -+static grub_efi_boolean_t request_callback_done; -+static grub_efi_boolean_t response_callback_done; -+ -+static void -+grub_efi_http_request_callback (grub_efi_event_t event __attribute__ ((unused)), -+ void *context __attribute__ ((unused))) -+{ -+ request_callback_done = 1; -+} -+ -+static void -+grub_efi_http_response_callback (grub_efi_event_t event __attribute__ ((unused)), -+ void *context __attribute__ ((unused))) -+{ -+ response_callback_done = 1; -+} -+ -+static grub_err_t -+efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, int headeronly, grub_off_t *file_size) -+{ -+ grub_efi_http_request_data_t request_data; -+ grub_efi_http_message_t request_message; -+ grub_efi_http_token_t request_token; -+ grub_efi_http_response_data_t response_data; -+ grub_efi_http_message_t response_message; -+ grub_efi_http_token_t response_token; -+ grub_efi_http_header_t request_headers[3]; -+ -+ grub_efi_status_t status; -+ grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; -+ char *url = NULL; -+ -+ request_headers[0].field_name = (grub_efi_char8_t *)"Host"; -+ request_headers[0].field_value = (grub_efi_char8_t *)server; -+ request_headers[1].field_name = (grub_efi_char8_t *)"Accept"; -+ request_headers[1].field_value = (grub_efi_char8_t *)"*/*"; -+ request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent"; -+ request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0"; -+ -+ { -+ grub_efi_ipv6_address_t address; -+ const char *rest; -+ grub_efi_char16_t *ucs2_url; -+ grub_size_t url_len, ucs2_url_len; -+ const char *protocol = (use_https == 1) ? "https" : "http"; -+ -+ if (grub_efi_string_to_ip6_address (server, &address, &rest) && *rest == 0) -+ url = grub_xasprintf ("%s://[%s]%s", protocol, server, name); -+ else -+ url = grub_xasprintf ("%s://%s%s", protocol, server, name); -+ -+ if (!url) -+ { -+ return grub_errno; -+ } -+ -+ url_len = grub_strlen (url); -+ ucs2_url_len = url_len * GRUB_MAX_UTF16_PER_UTF8; -+ ucs2_url = grub_malloc ((ucs2_url_len + 1) * sizeof (ucs2_url[0])); -+ -+ if (!ucs2_url) -+ { -+ grub_free (url); -+ return grub_errno; -+ } -+ -+ ucs2_url_len = grub_utf8_to_utf16 (ucs2_url, ucs2_url_len, (grub_uint8_t *)url, url_len, NULL); /* convert string format from ascii to usc2 */ -+ ucs2_url[ucs2_url_len] = 0; -+ grub_free (url); -+ request_data.url = ucs2_url; -+ } -+ -+ request_data.method = (headeronly > 0) ? GRUB_EFI_HTTPMETHODHEAD : GRUB_EFI_HTTPMETHODGET; -+ -+ request_message.data.request = &request_data; -+ request_message.header_count = 3; -+ request_message.headers = request_headers; -+ request_message.body_length = 0; -+ request_message.body = NULL; -+ -+ /* request token */ -+ request_token.event = NULL; -+ request_token.status = GRUB_EFI_NOT_READY; -+ request_token.message = &request_message; -+ -+ request_callback_done = 0; -+ status = efi_call_5 (b->create_event, -+ GRUB_EFI_EVT_NOTIFY_SIGNAL, -+ GRUB_EFI_TPL_CALLBACK, -+ grub_efi_http_request_callback, -+ NULL, -+ &request_token.event); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (request_data.url); -+ return grub_error (GRUB_ERR_IO, "Fail to create an event! status=0x%x\n", status); -+ } -+ -+ status = efi_call_2 (http->request, http, &request_token); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ efi_call_1 (b->close_event, request_token.event); -+ grub_free (request_data.url); -+ return grub_error (GRUB_ERR_IO, "Fail to send a request! status=0x%x\n", status); -+ } -+ /* TODO: Add Timeout */ -+ while (!request_callback_done) -+ efi_call_1(http->poll, http); -+ -+ response_data.status_code = GRUB_EFI_HTTP_STATUS_UNSUPPORTED_STATUS; -+ response_message.data.response = &response_data; -+ /* herader_count will be updated by the HTTP driver on response */ -+ response_message.header_count = 0; -+ /* headers will be populated by the driver on response */ -+ response_message.headers = NULL; -+ /* use zero BodyLength to only receive the response headers */ -+ response_message.body_length = 0; -+ response_message.body = NULL; -+ response_token.event = NULL; -+ -+ status = efi_call_5 (b->create_event, -+ GRUB_EFI_EVT_NOTIFY_SIGNAL, -+ GRUB_EFI_TPL_CALLBACK, -+ grub_efi_http_response_callback, -+ NULL, -+ &response_token.event); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ efi_call_1 (b->close_event, request_token.event); -+ grub_free (request_data.url); -+ return grub_error (GRUB_ERR_IO, "Fail to create an event! status=0x%x\n", status); -+ } -+ -+ response_token.status = GRUB_EFI_SUCCESS; -+ response_token.message = &response_message; -+ -+ /* wait for HTTP response */ -+ response_callback_done = 0; -+ status = efi_call_2 (http->response, http, &response_token); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ efi_call_1 (b->close_event, response_token.event); -+ efi_call_1 (b->close_event, request_token.event); -+ grub_free (request_data.url); -+ return grub_error (GRUB_ERR_IO, "Fail to receive a response! status=%d\n", (int)status); -+ } -+ -+ /* TODO: Add Timeout */ -+ while (!response_callback_done) -+ efi_call_1 (http->poll, http); -+ -+ if (response_message.data.response->status_code != GRUB_EFI_HTTP_STATUS_200_OK) -+ { -+ grub_efi_http_status_code_t status_code = response_message.data.response->status_code; -+ -+ if (response_message.headers) -+ efi_call_1 (b->free_pool, response_message.headers); -+ efi_call_1 (b->close_event, response_token.event); -+ efi_call_1 (b->close_event, request_token.event); -+ grub_free (request_data.url); -+ if (status_code == GRUB_EFI_HTTP_STATUS_404_NOT_FOUND) -+ { -+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, _("file `%s' not found"), name); -+ } -+ else -+ { -+ return grub_error (GRUB_ERR_NET_UNKNOWN_ERROR, -+ _("unsupported uefi http status code 0x%x"), status_code); -+ } -+ } -+ -+ if (file_size) -+ { -+ int i; -+ /* parse the length of the file from the ContentLength header */ -+ for (*file_size = 0, i = 0; i < (int)response_message.header_count; ++i) -+ { -+ if (!grub_strcmp((const char*)response_message.headers[i].field_name, "Content-Length")) -+ { -+ *file_size = grub_strtoul((const char*)response_message.headers[i].field_value, 0, 10); -+ break; -+ } -+ } -+ } -+ -+ if (response_message.headers) -+ efi_call_1 (b->free_pool, response_message.headers); -+ efi_call_1 (b->close_event, response_token.event); -+ efi_call_1 (b->close_event, request_token.event); -+ grub_free (request_data.url); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_ssize_t -+efihttp_read (struct grub_efi_net_device *dev, -+ char *buf, -+ grub_size_t len) -+{ -+ grub_efi_http_message_t response_message; -+ grub_efi_http_token_t response_token; -+ -+ grub_efi_status_t status; -+ grub_size_t sum = 0; -+ grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; -+ grub_efi_http_t *http = dev->http; -+ -+ if (!len) -+ { -+ grub_error (GRUB_ERR_BUG, "Invalid arguments to EFI HTTP Read"); -+ return -1; -+ } -+ -+ efi_call_5 (b->create_event, -+ GRUB_EFI_EVT_NOTIFY_SIGNAL, -+ GRUB_EFI_TPL_CALLBACK, -+ grub_efi_http_response_callback, -+ NULL, -+ &response_token.event); -+ -+ while (len) -+ { -+ response_message.data.response = NULL; -+ response_message.header_count = 0; -+ response_message.headers = NULL; -+ response_message.body_length = len; -+ response_message.body = buf; -+ -+ response_token.message = &response_message; -+ response_token.status = GRUB_EFI_NOT_READY; -+ -+ response_callback_done = 0; -+ -+ status = efi_call_2 (http->response, http, &response_token); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ efi_call_1 (b->close_event, response_token.event); -+ grub_error (GRUB_ERR_IO, "Error! status=%d\n", (int)status); -+ return -1; -+ } -+ -+ while (!response_callback_done) -+ efi_call_1(http->poll, http); -+ -+ sum += response_message.body_length; -+ buf += response_message.body_length; -+ len -= response_message.body_length; -+ } -+ -+ efi_call_1 (b->close_event, response_token.event); -+ -+ return sum; -+} -+ -+static grub_err_t -+grub_efihttp_open (struct grub_efi_net_device *dev, -+ int prefer_ip6 __attribute__ ((unused)), -+ grub_file_t file, -+ const char *filename __attribute__ ((unused)), -+ int type) -+{ -+ grub_err_t err; -+ grub_off_t size; -+ char *buf; -+ -+ err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 1, 0); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ -+ err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 0, &size); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ -+ buf = grub_malloc (size); -+ efihttp_read (dev, buf, size); -+ -+ file->size = size; -+ file->data = buf; -+ file->not_easily_seekable = 0; -+ file->device->net->offset = 0; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_efihttp_close (struct grub_efi_net_device *dev __attribute__ ((unused)), -+ int prefer_ip6 __attribute__ ((unused)), -+ grub_file_t file) -+{ -+ if (file->data) -+ grub_free (file->data); -+ -+ file->data = 0; -+ file->offset = 0; -+ file->size = 0; -+ file->device->net->offset = 0; -+ return GRUB_ERR_NONE; -+} -+ -+static grub_ssize_t -+grub_efihttp_read (struct grub_efi_net_device *dev __attribute__((unused)), -+ int prefer_ip6 __attribute__((unused)), -+ grub_file_t file, -+ char *buf, -+ grub_size_t len) -+{ -+ grub_size_t r = len; -+ -+ if (!file->data || !buf || !len) -+ return 0; -+ -+ if ((file->device->net->offset + len) > file->size) -+ r = file->size - file->device->net->offset; -+ -+ if (r) -+ { -+ grub_memcpy (buf, (char *)file->data + file->device->net->offset, r); -+ file->device->net->offset += r; -+ } -+ -+ return r; -+} -+ -+struct grub_efi_net_io io_http = -+ { -+ .configure = http_configure, -+ .open = grub_efihttp_open, -+ .read = grub_efihttp_read, -+ .close = grub_efihttp_close -+ }; -diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c -new file mode 100644 -index 00000000000..b711a5d9457 ---- /dev/null -+++ b/grub-core/net/efi/ip4_config.c -@@ -0,0 +1,398 @@ -+ -+#include -+#include -+#include -+#include -+#include -+ -+char * -+grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_address_t hw_address) -+{ -+ char *hw_addr, *p; -+ int sz, s; -+ int i; -+ -+ sz = (int)hw_address_size * (sizeof ("XX:") - 1) + 1; -+ -+ hw_addr = grub_malloc (sz); -+ if (!hw_addr) -+ return NULL; -+ -+ p = hw_addr; -+ s = sz; -+ for (i = 0; i < (int)hw_address_size; i++) -+ { -+ grub_snprintf (p, sz, "%02x:", hw_address[i]); -+ p += sizeof ("XX:") - 1; -+ s -= sizeof ("XX:") - 1; -+ } -+ -+ hw_addr[sz - 2] = '\0'; -+ return hw_addr; -+} -+ -+char * -+grub_efi_ip4_address_to_string (grub_efi_ipv4_address_t *address) -+{ -+ char *addr; -+ -+ addr = grub_malloc (sizeof ("XXX.XXX.XXX.XXX")); -+ if (!addr) -+ return NULL; -+ -+ /* FIXME: Use grub_xasprintf ? */ -+ grub_snprintf (addr, -+ sizeof ("XXX.XXX.XXX.XXX"), -+ "%u.%u.%u.%u", -+ (*address)[0], -+ (*address)[1], -+ (*address)[2], -+ (*address)[3]); -+ -+ return addr; -+} -+ -+int -+grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *address, const char **rest) -+{ -+ grub_uint32_t newip = 0; -+ int i; -+ const char *ptr = val; -+ -+ for (i = 0; i < 4; i++) -+ { -+ unsigned long t; -+ t = grub_strtoul (ptr, (char **) &ptr, 0); -+ if (grub_errno) -+ { -+ grub_errno = GRUB_ERR_NONE; -+ return 0; -+ } -+ if (*ptr != '.' && i == 0) -+ { -+ /* XXX: t is in host byte order */ -+ newip = t; -+ break; -+ } -+ if (t & ~0xff) -+ return 0; -+ newip <<= 8; -+ newip |= t; -+ if (i != 3 && *ptr != '.') -+ return 0; -+ ptr++; -+ } -+ -+ newip = grub_cpu_to_be32 (newip); -+ -+ grub_memcpy (address, &newip, sizeof(*address)); -+ -+ if (rest) -+ *rest = (ptr - 1); -+ return 1; -+} -+ -+static grub_efi_ip4_config2_interface_info_t * -+efi_ip4_config_interface_info (grub_efi_ip4_config2_protocol_t *ip4_config) -+{ -+ grub_efi_uintn_t sz; -+ grub_efi_status_t status; -+ grub_efi_ip4_config2_interface_info_t *interface_info; -+ -+ sz = sizeof (*interface_info) + sizeof (*interface_info->route_table); -+ interface_info = grub_malloc (sz); -+ if (!interface_info) -+ return NULL; -+ -+ status = efi_call_4 (ip4_config->get_data, ip4_config, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, -+ &sz, interface_info); -+ -+ if (status == GRUB_EFI_BUFFER_TOO_SMALL) -+ { -+ grub_free (interface_info); -+ interface_info = grub_malloc (sz); -+ status = efi_call_4 (ip4_config->get_data, ip4_config, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, -+ &sz, interface_info); -+ } -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (interface_info); -+ return NULL; -+ } -+ -+ return interface_info; -+} -+ -+static grub_efi_ip4_config2_manual_address_t * -+efi_ip4_config_manual_address (grub_efi_ip4_config2_protocol_t *ip4_config) -+{ -+ grub_efi_uintn_t sz; -+ grub_efi_status_t status; -+ grub_efi_ip4_config2_manual_address_t *manual_address; -+ -+ sz = sizeof (*manual_address); -+ manual_address = grub_malloc (sz); -+ if (!manual_address) -+ return NULL; -+ -+ status = efi_call_4 (ip4_config->get_data, ip4_config, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, -+ &sz, manual_address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (manual_address); -+ return NULL; -+ } -+ -+ return manual_address; -+} -+ -+char * -+grub_efi_ip4_interface_name (struct grub_efi_net_device *dev) -+{ -+ grub_efi_ip4_config2_interface_info_t *interface_info; -+ char *name; -+ -+ interface_info = efi_ip4_config_interface_info (dev->ip4_config); -+ -+ if (!interface_info) -+ return NULL; -+ -+ name = grub_malloc (GRUB_EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE -+ * GRUB_MAX_UTF8_PER_UTF16 + 1); -+ *grub_utf16_to_utf8 ((grub_uint8_t *)name, interface_info->name, -+ GRUB_EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE) = 0; -+ grub_free (interface_info); -+ return name; -+} -+ -+static char * -+grub_efi_ip4_interface_hw_address (struct grub_efi_net_device *dev) -+{ -+ grub_efi_ip4_config2_interface_info_t *interface_info; -+ char *hw_addr; -+ -+ interface_info = efi_ip4_config_interface_info (dev->ip4_config); -+ -+ if (!interface_info) -+ return NULL; -+ -+ hw_addr = grub_efi_hw_address_to_string (interface_info->hw_address_size, interface_info->hw_address); -+ grub_free (interface_info); -+ -+ return hw_addr; -+} -+ -+static char * -+grub_efi_ip4_interface_address (struct grub_efi_net_device *dev) -+{ -+ grub_efi_ip4_config2_manual_address_t *manual_address; -+ char *addr; -+ -+ manual_address = efi_ip4_config_manual_address (dev->ip4_config); -+ -+ if (!manual_address) -+ return NULL; -+ -+ addr = grub_efi_ip4_address_to_string (&manual_address->address); -+ grub_free (manual_address); -+ return addr; -+} -+ -+ -+static int -+address_mask_size (grub_efi_ipv4_address_t *address) -+{ -+ grub_uint8_t i; -+ grub_uint32_t u32_addr = grub_be_to_cpu32 (grub_get_unaligned32 (address)); -+ -+ if (u32_addr == 0) -+ return 0; -+ -+ for (i = 0; i < 32 ; ++i) -+ { -+ if (u32_addr == ((0xffffffff >> i) << i)) -+ return (32 - i); -+ } -+ -+ return -1; -+} -+ -+static char ** -+grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev) -+{ -+ grub_efi_ip4_config2_interface_info_t *interface_info; -+ char **ret; -+ int i, id; -+ -+ interface_info = efi_ip4_config_interface_info (dev->ip4_config); -+ if (!interface_info) -+ return NULL; -+ -+ ret = grub_malloc (sizeof (*ret) * (interface_info->route_table_size + 1)); -+ -+ if (!ret) -+ { -+ grub_free (interface_info); -+ return NULL; -+ } -+ -+ id = 0; -+ for (i = 0; i < (int)interface_info->route_table_size; i++) -+ { -+ char *subnet, *gateway, *mask; -+ grub_uint32_t u32_subnet, u32_gateway; -+ int mask_size; -+ grub_efi_ip4_route_table_t *route_table = interface_info->route_table + i; -+ grub_efi_net_interface_t *inf; -+ char *interface_name = NULL; -+ -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ if (!inf->prefer_ip6) -+ interface_name = inf->name; -+ -+ u32_gateway = grub_get_unaligned32 (&route_table->gateway_address); -+ gateway = grub_efi_ip4_address_to_string (&route_table->gateway_address); -+ u32_subnet = grub_get_unaligned32 (&route_table->subnet_address); -+ subnet = grub_efi_ip4_address_to_string (&route_table->subnet_address); -+ mask_size = address_mask_size (&route_table->subnet_mask); -+ mask = grub_efi_ip4_address_to_string (&route_table->subnet_mask); -+ if (u32_subnet && !u32_gateway && interface_name) -+ ret[id++] = grub_xasprintf ("%s:local %s/%d %s", dev->card_name, subnet, mask_size, interface_name); -+ else if (u32_subnet && u32_gateway) -+ ret[id++] = grub_xasprintf ("%s:gw %s/%d gw %s", dev->card_name, subnet, mask_size, gateway); -+ else if (!u32_subnet && u32_gateway) -+ ret[id++] = grub_xasprintf ("%s:default %s/%d gw %s", dev->card_name, subnet, mask_size, gateway); -+ grub_free (subnet); -+ grub_free (gateway); -+ grub_free (mask); -+ } -+ -+ ret[id] = NULL; -+ grub_free (interface_info); -+ return ret; -+} -+ -+static grub_efi_net_interface_t * -+grub_efi_ip4_interface_match (struct grub_efi_net_device *dev, grub_efi_net_ip_address_t *ip_address) -+{ -+ grub_efi_ip4_config2_interface_info_t *interface_info; -+ grub_efi_net_interface_t *inf; -+ int i; -+ grub_efi_ipv4_address_t *address = &ip_address->ip4; -+ -+ interface_info = efi_ip4_config_interface_info (dev->ip4_config); -+ if (!interface_info) -+ return NULL; -+ -+ for (i = 0; i < (int)interface_info->route_table_size; i++) -+ { -+ grub_efi_ip4_route_table_t *route_table = interface_info->route_table + i; -+ grub_uint32_t u32_address, u32_mask, u32_subnet; -+ -+ u32_address = grub_get_unaligned32 (address); -+ u32_subnet = grub_get_unaligned32 (route_table->subnet_address); -+ u32_mask = grub_get_unaligned32 (route_table->subnet_mask); -+ -+ /* SKIP Default GATEWAY */ -+ if (!u32_subnet && !u32_mask) -+ continue; -+ -+ if ((u32_address & u32_mask) == u32_subnet) -+ { -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ if (!inf->prefer_ip6) -+ { -+ grub_free (interface_info); -+ return inf; -+ } -+ } -+ } -+ -+ grub_free (interface_info); -+ return NULL; -+} -+ -+static int -+grub_efi_ip4_interface_set_manual_address (struct grub_efi_net_device *dev, -+ grub_efi_net_ip_manual_address_t *net_ip, -+ int with_subnet) -+{ -+ grub_efi_status_t status; -+ grub_efi_ip4_config2_manual_address_t *address = &net_ip->ip4; -+ -+ if (!with_subnet) -+ { -+ grub_efi_ip4_config2_manual_address_t *manual_address = -+ efi_ip4_config_manual_address (dev->ip4_config); -+ -+ if (manual_address) -+ { -+ grub_memcpy (address->subnet_mask, manual_address->subnet_mask, sizeof(address->subnet_mask)); -+ grub_free (manual_address); -+ } -+ else -+ { -+ /* XXX: */ -+ address->subnet_mask[0] = 0xff; -+ address->subnet_mask[1] = 0xff; -+ address->subnet_mask[2] = 0xff; -+ address->subnet_mask[3] = 0; -+ } -+ } -+ -+ status = efi_call_4 (dev->ip4_config->set_data, dev->ip4_config, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, -+ sizeof(*address), address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ -+ return 1; -+} -+ -+static int -+grub_efi_ip4_interface_set_gateway (struct grub_efi_net_device *dev, -+ grub_efi_net_ip_address_t *address) -+{ -+ grub_efi_status_t status; -+ -+ status = efi_call_4 (dev->ip4_config->set_data, dev->ip4_config, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_GATEWAY, -+ sizeof (address->ip4), &address->ip4); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ return 1; -+} -+ -+/* FIXME: Multiple DNS */ -+static int -+grub_efi_ip4_interface_set_dns (struct grub_efi_net_device *dev, -+ grub_efi_net_ip_address_t *address) -+{ -+ grub_efi_status_t status; -+ -+ status = efi_call_4 (dev->ip4_config->set_data, dev->ip4_config, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, -+ sizeof (address->ip4), &address->ip4); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ return 1; -+} -+ -+grub_efi_net_ip_config_t *efi_net_ip4_config = &(grub_efi_net_ip_config_t) -+ { -+ .get_hw_address = grub_efi_ip4_interface_hw_address, -+ .get_address = grub_efi_ip4_interface_address, -+ .get_route_table = grub_efi_ip4_interface_route_table, -+ .best_interface = grub_efi_ip4_interface_match, -+ .set_address = grub_efi_ip4_interface_set_manual_address, -+ .set_gateway = grub_efi_ip4_interface_set_gateway, -+ .set_dns = grub_efi_ip4_interface_set_dns -+ }; -diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c -new file mode 100644 -index 00000000000..017c4d05bc7 ---- /dev/null -+++ b/grub-core/net/efi/ip6_config.c -@@ -0,0 +1,422 @@ -+#include -+#include -+#include -+#include -+#include -+ -+char * -+grub_efi_ip6_address_to_string (grub_efi_pxe_ipv6_address_t *address) -+{ -+ char *str = grub_malloc (sizeof ("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX")); -+ char *p; -+ int i; -+ int squash; -+ -+ if (!str) -+ return NULL; -+ -+ p = str; -+ squash = 0; -+ for (i = 0; i < 8; ++i) -+ { -+ grub_uint16_t addr; -+ -+ if (i == 7) -+ squash = 2; -+ -+ addr = grub_get_unaligned16 (address->addr + i * 2); -+ -+ if (grub_be_to_cpu16 (addr)) -+ { -+ char buf[sizeof ("XXXX")]; -+ if (i > 0) -+ *p++ = ':'; -+ grub_snprintf (buf, sizeof (buf), "%x", grub_be_to_cpu16 (addr)); -+ grub_strcpy (p, buf); -+ p += grub_strlen (buf); -+ -+ if (squash == 1) -+ squash = 2; -+ } -+ else -+ { -+ if (squash == 0) -+ { -+ *p++ = ':'; -+ squash = 1; -+ } -+ else if (squash == 2) -+ { -+ *p++ = ':'; -+ *p++ = '0'; -+ } -+ } -+ } -+ *p = '\0'; -+ return str; -+} -+ -+int -+grub_efi_string_to_ip6_address (const char *val, grub_efi_ipv6_address_t *address, const char **rest) -+{ -+ grub_uint16_t newip[8]; -+ const char *ptr = val; -+ int word, quaddot = -1; -+ int bracketed = 0; -+ -+ if (ptr[0] == '[') { -+ bracketed = 1; -+ ptr++; -+ } -+ -+ if (ptr[0] == ':' && ptr[1] != ':') -+ return 0; -+ if (ptr[0] == ':') -+ ptr++; -+ -+ for (word = 0; word < 8; word++) -+ { -+ unsigned long t; -+ if (*ptr == ':') -+ { -+ quaddot = word; -+ word--; -+ ptr++; -+ continue; -+ } -+ t = grub_strtoul (ptr, (char **) &ptr, 16); -+ if (grub_errno) -+ { -+ grub_errno = GRUB_ERR_NONE; -+ break; -+ } -+ if (t & ~0xffff) -+ return 0; -+ newip[word] = grub_cpu_to_be16 (t); -+ if (*ptr != ':') -+ break; -+ ptr++; -+ } -+ if (quaddot == -1 && word < 7) -+ return 0; -+ if (quaddot != -1) -+ { -+ grub_memmove (&newip[quaddot + 7 - word], &newip[quaddot], -+ (word - quaddot + 1) * sizeof (newip[0])); -+ grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0])); -+ } -+ grub_memcpy (address, newip, 16); -+ if (bracketed && *ptr == ']') { -+ ptr++; -+ } -+ if (rest) -+ *rest = ptr; -+ return 1; -+} -+ -+static grub_efi_ip6_config_interface_info_t * -+efi_ip6_config_interface_info (grub_efi_ip6_config_protocol_t *ip6_config) -+{ -+ grub_efi_uintn_t sz; -+ grub_efi_status_t status; -+ grub_efi_ip6_config_interface_info_t *interface_info; -+ -+ sz = sizeof (*interface_info) + sizeof (*interface_info->route_table); -+ interface_info = grub_malloc (sz); -+ -+ status = efi_call_4 (ip6_config->get_data, ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, -+ &sz, interface_info); -+ -+ if (status == GRUB_EFI_BUFFER_TOO_SMALL) -+ { -+ grub_free (interface_info); -+ interface_info = grub_malloc (sz); -+ status = efi_call_4 (ip6_config->get_data, ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, -+ &sz, interface_info); -+ } -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (interface_info); -+ return NULL; -+ } -+ -+ return interface_info; -+} -+ -+static grub_efi_ip6_config_manual_address_t * -+efi_ip6_config_manual_address (grub_efi_ip6_config_protocol_t *ip6_config) -+{ -+ grub_efi_uintn_t sz; -+ grub_efi_status_t status; -+ grub_efi_ip6_config_manual_address_t *manual_address; -+ -+ sz = sizeof (*manual_address); -+ manual_address = grub_malloc (sz); -+ if (!manual_address) -+ return NULL; -+ -+ status = efi_call_4 (ip6_config->get_data, ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, -+ &sz, manual_address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (manual_address); -+ return NULL; -+ } -+ -+ return manual_address; -+} -+ -+char * -+grub_efi_ip6_interface_name (struct grub_efi_net_device *dev) -+{ -+ grub_efi_ip6_config_interface_info_t *interface_info; -+ char *name; -+ -+ interface_info = efi_ip6_config_interface_info (dev->ip6_config); -+ -+ if (!interface_info) -+ return NULL; -+ -+ name = grub_malloc (GRUB_EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE -+ * GRUB_MAX_UTF8_PER_UTF16 + 1); -+ *grub_utf16_to_utf8 ((grub_uint8_t *)name, interface_info->name, -+ GRUB_EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE) = 0; -+ grub_free (interface_info); -+ return name; -+} -+ -+static char * -+grub_efi_ip6_interface_hw_address (struct grub_efi_net_device *dev) -+{ -+ grub_efi_ip6_config_interface_info_t *interface_info; -+ char *hw_addr; -+ -+ interface_info = efi_ip6_config_interface_info (dev->ip6_config); -+ -+ if (!interface_info) -+ return NULL; -+ -+ hw_addr = grub_efi_hw_address_to_string (interface_info->hw_address_size, interface_info->hw_address); -+ grub_free (interface_info); -+ -+ return hw_addr; -+} -+ -+static char * -+grub_efi_ip6_interface_address (struct grub_efi_net_device *dev) -+{ -+ grub_efi_ip6_config_manual_address_t *manual_address; -+ char *addr; -+ -+ manual_address = efi_ip6_config_manual_address (dev->ip6_config); -+ -+ if (!manual_address) -+ return NULL; -+ -+ addr = grub_efi_ip6_address_to_string ((grub_efi_pxe_ipv6_address_t *)&manual_address->address); -+ grub_free (manual_address); -+ return addr; -+} -+ -+static char ** -+grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev) -+{ -+ grub_efi_ip6_config_interface_info_t *interface_info; -+ char **ret; -+ int i, id; -+ -+ interface_info = efi_ip6_config_interface_info (dev->ip6_config); -+ if (!interface_info) -+ return NULL; -+ -+ ret = grub_malloc (sizeof (*ret) * (interface_info->route_count + 1)); -+ -+ if (!ret) -+ { -+ grub_free (interface_info); -+ return NULL; -+ } -+ -+ id = 0; -+ for (i = 0; i < (int)interface_info->route_count ; i++) -+ { -+ char *gateway, *destination; -+ grub_uint64_t u64_gateway[2]; -+ grub_uint64_t u64_destination[2]; -+ grub_efi_ip6_route_table_t *route_table = interface_info->route_table + i; -+ grub_efi_net_interface_t *inf; -+ char *interface_name = NULL; -+ -+ gateway = grub_efi_ip6_address_to_string (&route_table->gateway); -+ destination = grub_efi_ip6_address_to_string (&route_table->destination); -+ -+ u64_gateway[0] = grub_get_unaligned64 (route_table->gateway.addr); -+ u64_gateway[1] = grub_get_unaligned64 (route_table->gateway.addr + 8); -+ u64_destination[0] = grub_get_unaligned64 (route_table->destination.addr); -+ u64_destination[1] = grub_get_unaligned64 (route_table->destination.addr + 8); -+ -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ if (inf->prefer_ip6) -+ interface_name = inf->name; -+ -+ if ((!u64_gateway[0] && !u64_gateway[1]) -+ && (u64_destination[0] || u64_destination[1])) -+ { -+ if (interface_name) -+ { -+ if ((grub_be_to_cpu64 (u64_destination[0]) == 0xfe80000000000000ULL) -+ && (!u64_destination[1]) -+ && (route_table->prefix_length == 64)) -+ ret[id++] = grub_xasprintf ("%s:link %s/%d %s", dev->card_name, destination, route_table->prefix_length, interface_name); -+ else -+ ret[id++] = grub_xasprintf ("%s:local %s/%d %s", dev->card_name, destination, route_table->prefix_length, interface_name); -+ } -+ } -+ else if ((u64_gateway[0] || u64_gateway[1]) -+ && (u64_destination[0] || u64_destination[1])) -+ ret[id++] = grub_xasprintf ("%s:gw %s/%d gw %s", dev->card_name, destination, route_table->prefix_length, gateway); -+ else if ((u64_gateway[0] || u64_gateway[1]) -+ && (!u64_destination[0] && !u64_destination[1])) -+ ret[id++] = grub_xasprintf ("%s:default %s/%d gw %s", dev->card_name, destination, route_table->prefix_length, gateway); -+ -+ grub_free (gateway); -+ grub_free (destination); -+ } -+ -+ ret[id] = NULL; -+ grub_free (interface_info); -+ return ret; -+} -+ -+static grub_efi_net_interface_t * -+grub_efi_ip6_interface_match (struct grub_efi_net_device *dev, grub_efi_net_ip_address_t *ip_address) -+{ -+ grub_efi_ip6_config_interface_info_t *interface_info; -+ grub_efi_net_interface_t *inf; -+ int i; -+ grub_efi_ipv6_address_t *address = &ip_address->ip6; -+ -+ interface_info = efi_ip6_config_interface_info (dev->ip6_config); -+ if (!interface_info) -+ return NULL; -+ -+ for (i = 0; i < (int)interface_info->route_count ; i++) -+ { -+ grub_uint64_t u64_addr[2]; -+ grub_uint64_t u64_subnet[2]; -+ grub_uint64_t u64_mask[2]; -+ -+ grub_efi_ip6_route_table_t *route_table = interface_info->route_table + i; -+ -+ /* SKIP Default GATEWAY */ -+ if (route_table->prefix_length == 0) -+ continue; -+ -+ u64_addr[0] = grub_get_unaligned64 (address); -+ u64_addr[1] = grub_get_unaligned64 (address + 4); -+ u64_subnet[0] = grub_get_unaligned64 (route_table->destination.addr); -+ u64_subnet[1] = grub_get_unaligned64 (route_table->destination.addr + 8); -+ u64_mask[0] = (route_table->prefix_length <= 64) ? -+ 0xffffffffffffffffULL << (64 - route_table->prefix_length) : -+ 0xffffffffffffffffULL; -+ u64_mask[1] = (route_table->prefix_length <= 64) ? -+ 0 : -+ 0xffffffffffffffffULL << (128 - route_table->prefix_length); -+ -+ if (((u64_addr[0] & u64_mask[0]) == u64_subnet[0]) -+ && ((u64_addr[1] & u64_mask[1]) == u64_subnet[1])) -+ { -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ if (inf->prefer_ip6) -+ { -+ grub_free (interface_info); -+ return inf; -+ } -+ } -+ } -+ -+ grub_free (interface_info); -+ return NULL; -+} -+ -+static int -+grub_efi_ip6_interface_set_manual_address (struct grub_efi_net_device *dev, -+ grub_efi_net_ip_manual_address_t *net_ip, -+ int with_subnet) -+{ -+ grub_efi_status_t status; -+ grub_efi_ip6_config_manual_address_t *address = &net_ip->ip6; -+ -+ if (!with_subnet) -+ { -+ grub_efi_ip6_config_manual_address_t *manual_address = -+ efi_ip6_config_manual_address (dev->ip6_config); -+ -+ if (manual_address) -+ { -+ address->prefix_length = manual_address->prefix_length; -+ grub_free (manual_address); -+ } -+ else -+ { -+ /* XXX: */ -+ address->prefix_length = 64; -+ } -+ } -+ -+ status = efi_call_4 (dev->ip6_config->set_data, dev->ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, -+ sizeof(*address), address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ -+ return 1; -+} -+ -+static int -+grub_efi_ip6_interface_set_gateway (struct grub_efi_net_device *dev, -+ grub_efi_net_ip_address_t *address) -+{ -+ grub_efi_status_t status; -+ -+ status = efi_call_4 (dev->ip6_config->set_data, dev->ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_GATEWAY, -+ sizeof (address->ip6), &address->ip6); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ return 1; -+} -+ -+static int -+grub_efi_ip6_interface_set_dns (struct grub_efi_net_device *dev, -+ grub_efi_net_ip_address_t *address) -+{ -+ -+ grub_efi_status_t status; -+ -+ status = efi_call_4 (dev->ip6_config->set_data, dev->ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, -+ sizeof (address->ip6), &address->ip6); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ return 1; -+} -+ -+grub_efi_net_ip_config_t *efi_net_ip6_config = &(grub_efi_net_ip_config_t) -+ { -+ .get_hw_address = grub_efi_ip6_interface_hw_address, -+ .get_address = grub_efi_ip6_interface_address, -+ .get_route_table = grub_efi_ip6_interface_route_table, -+ .best_interface = grub_efi_ip6_interface_match, -+ .set_address = grub_efi_ip6_interface_set_manual_address, -+ .set_gateway = grub_efi_ip6_interface_set_gateway, -+ .set_dns = grub_efi_ip6_interface_set_dns -+ }; -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -new file mode 100644 -index 00000000000..86bce6535d3 ---- /dev/null -+++ b/grub-core/net/efi/net.c -@@ -0,0 +1,1428 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#define GRUB_EFI_IP6_PREFIX_LENGTH 64 -+ -+static grub_efi_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID; -+static grub_efi_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID; -+static grub_efi_guid_t http_service_binding_guid = GRUB_EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID; -+static grub_efi_guid_t http_guid = GRUB_EFI_HTTP_PROTOCOL_GUID; -+static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; -+static grub_efi_guid_t dhcp4_service_binding_guid = GRUB_EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID; -+static grub_efi_guid_t dhcp4_guid = GRUB_EFI_DHCP4_PROTOCOL_GUID; -+static grub_efi_guid_t dhcp6_service_binding_guid = GRUB_EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID; -+static grub_efi_guid_t dhcp6_guid = GRUB_EFI_DHCP6_PROTOCOL_GUID; -+ -+struct grub_efi_net_device *net_devices; -+ -+static char *default_server; -+static grub_efi_net_interface_t *net_interface; -+static grub_efi_net_interface_t *net_default_interface; -+ -+#define efi_net_interface_configure(inf) inf->io->configure (inf->dev, inf->prefer_ip6) -+#define efi_net_interface_open(inf, file, name) inf->io->open (inf->dev, inf->prefer_ip6, file, name, inf->io_type) -+#define efi_net_interface_read(inf, file, buf, sz) inf->io->read (inf->dev, inf->prefer_ip6, file, buf, sz) -+#define efi_net_interface_close(inf, file) inf->io->close (inf->dev, inf->prefer_ip6, file) -+#define efi_net_interface(m,...) efi_net_interface_ ## m (net_interface, ## __VA_ARGS__) -+ -+static grub_efi_handle_t -+grub_efi_locate_device_path (grub_efi_guid_t *protocol, grub_efi_device_path_t *device_path, -+ grub_efi_device_path_t **r_device_path) -+{ -+ grub_efi_handle_t handle; -+ grub_efi_status_t status; -+ -+ status = efi_call_3 (grub_efi_system_table->boot_services->locate_device_path, -+ protocol, &device_path, &handle); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ -+ if (r_device_path) -+ *r_device_path = device_path; -+ -+ return handle; -+} -+ -+static int -+url_parse_fields (const char *url, char **proto, char **host, char **path) -+{ -+ const char *p, *ps; -+ grub_size_t l; -+ -+ *proto = *host = *path = NULL; -+ ps = p = url; -+ -+ while ((p = grub_strchr (p, ':'))) -+ { -+ if (grub_strlen (p) < sizeof ("://") - 1) -+ break; -+ if (grub_memcmp (p, "://", sizeof ("://") - 1) == 0) -+ { -+ l = p - ps; -+ *proto = grub_malloc (l + 1); -+ if (!*proto) -+ { -+ grub_print_error (); -+ return 0; -+ } -+ -+ grub_memcpy (*proto, ps, l); -+ (*proto)[l] = '\0'; -+ p += sizeof ("://") - 1; -+ break; -+ } -+ ++p; -+ } -+ -+ if (!*proto) -+ { -+ grub_dprintf ("bootp", "url: %s is not valid, protocol not found\n", url); -+ return 0; -+ } -+ -+ ps = p; -+ p = grub_strchr (p, '/'); -+ -+ if (!p) -+ { -+ grub_dprintf ("bootp", "url: %s is not valid, host/path not found\n", url); -+ grub_free (*proto); -+ *proto = NULL; -+ return 0; -+ } -+ -+ l = p - ps; -+ -+ if (l > 2 && ps[0] == '[' && ps[l - 1] == ']') -+ { -+ *host = grub_malloc (l - 1); -+ if (!*host) -+ { -+ grub_print_error (); -+ grub_free (*proto); -+ *proto = NULL; -+ return 0; -+ } -+ grub_memcpy (*host, ps + 1, l - 2); -+ (*host)[l - 2] = 0; -+ } -+ else -+ { -+ *host = grub_malloc (l + 1); -+ if (!*host) -+ { -+ grub_print_error (); -+ grub_free (*proto); -+ *proto = NULL; -+ return 0; -+ } -+ grub_memcpy (*host, ps, l); -+ (*host)[l] = 0; -+ } -+ -+ *path = grub_strdup (p); -+ if (!*path) -+ { -+ grub_print_error (); -+ grub_free (*host); -+ grub_free (*proto); -+ *host = NULL; -+ *proto = NULL; -+ return 0; -+ } -+ return 1; -+} -+ -+static void -+url_get_boot_location (const char *url, char **device, char **path, int is_default) -+{ -+ char *protocol, *server, *file; -+ char *slash; -+ -+ if (!url_parse_fields (url, &protocol, &server, &file)) -+ return; -+ -+ if ((slash = grub_strrchr (file, '/'))) -+ *slash = 0; -+ else -+ *file = 0; -+ -+ *device = grub_xasprintf ("%s,%s", protocol, server); -+ *path = grub_strdup(file); -+ -+ if (is_default) -+ default_server = server; -+ else -+ grub_free (server); -+ -+ grub_free (protocol); -+ grub_free (file); -+} -+ -+static void -+pxe_get_boot_location (const struct grub_net_bootp_packet *bp, -+ char **device, -+ char **path, -+ int is_default) -+{ -+ char *server = grub_xasprintf ("%d.%d.%d.%d", -+ ((grub_uint8_t *) &bp->server_ip)[0], -+ ((grub_uint8_t *) &bp->server_ip)[1], -+ ((grub_uint8_t *) &bp->server_ip)[2], -+ ((grub_uint8_t *) &bp->server_ip)[3]); -+ -+ *device = grub_xasprintf ("tftp,%s", server); -+ -+ *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file)); -+ -+ if (*path) -+ { -+ char *slash; -+ slash = grub_strrchr (*path, '/'); -+ if (slash) -+ *slash = 0; -+ else -+ **path = 0; -+ } -+ -+ if (is_default) -+ default_server = server; -+ else -+ grub_free (server); -+} -+ -+static void -+pxe_get_boot_location_v6 (const struct grub_net_dhcp6_packet *dp, -+ grub_size_t dhcp_size, -+ char **device, -+ char **path) -+{ -+ -+ struct grub_net_dhcp6_option *dhcp_opt; -+ grub_size_t dhcp_remain_size; -+ *device = *path = 0; -+ -+ if (dhcp_size < sizeof (*dp)) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("DHCPv6 packet size too small")); -+ return; -+ } -+ -+ dhcp_remain_size = dhcp_size - sizeof (*dp); -+ dhcp_opt = (struct grub_net_dhcp6_option *)dp->dhcp_options; -+ -+ while (dhcp_remain_size) -+ { -+ grub_uint16_t code = grub_be_to_cpu16 (dhcp_opt->code); -+ grub_uint16_t len = grub_be_to_cpu16 (dhcp_opt->len); -+ grub_uint16_t option_size = sizeof (*dhcp_opt) + len; -+ -+ if (dhcp_remain_size < option_size || code == 0) -+ break; -+ -+ if (code == GRUB_NET_DHCP6_OPTION_BOOTFILE_URL) -+ { -+ char *url = grub_malloc (len + 1); -+ -+ grub_memcpy (url, dhcp_opt->data, len); -+ url[len] = 0; -+ -+ url_get_boot_location ((const char *)url, device, path, 1); -+ grub_free (url); -+ break; -+ } -+ -+ dhcp_remain_size -= option_size; -+ dhcp_opt = (struct grub_net_dhcp6_option *)((grub_uint8_t *)dhcp_opt + option_size); -+ } -+} -+ -+static grub_efi_net_interface_t * -+grub_efi_net_config_from_device_path (grub_efi_device_path_t *dp, -+ struct grub_efi_net_device *netdev, -+ char **device, -+ char **path) -+{ -+ grub_efi_net_interface_t *inf = NULL; -+ -+ while (1) -+ { -+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); -+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); -+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); -+ -+ if (type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE) -+ { -+ if (subtype == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE) -+ { -+ grub_efi_uri_device_path_t *uri_dp; -+ uri_dp = (grub_efi_uri_device_path_t *) dp; -+ /* Beware that uri_dp->uri may not be null terminated */ -+ url_get_boot_location ((const char *)uri_dp->uri, device, path, 1); -+ } -+ else if (subtype == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE) -+ { -+ grub_efi_net_ip_manual_address_t net_ip; -+ grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) dp; -+ -+ if (inf) -+ continue; -+ grub_memcpy (net_ip.ip4.address, ipv4->local_ip_address, sizeof (net_ip.ip4.address)); -+ grub_memcpy (net_ip.ip4.subnet_mask, ipv4->subnet_mask, sizeof (net_ip.ip4.subnet_mask)); -+ net_ip.is_ip6 = 0; -+ inf = grub_efi_net_create_interface (netdev, -+ netdev->card_name, -+ &net_ip, -+ 1); -+ } -+ else if (subtype == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE) -+ { -+ grub_efi_net_ip_manual_address_t net_ip; -+ grub_efi_ipv6_device_path_t *ipv6 = (grub_efi_ipv6_device_path_t *) dp; -+ -+ if (inf) -+ continue; -+ grub_memcpy (net_ip.ip6.address, ipv6->local_ip_address, sizeof (net_ip.ip6.address)); -+ net_ip.ip6.prefix_length = GRUB_EFI_IP6_PREFIX_LENGTH; -+ net_ip.ip6.is_anycast = 0; -+ net_ip.is_ip6 = 1; -+ inf = grub_efi_net_create_interface (netdev, -+ netdev->card_name, -+ &net_ip, -+ 1); -+ } -+ } -+ -+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) -+ break; -+ dp = (grub_efi_device_path_t *) ((char *) dp + len); -+ } -+ -+ return inf; -+} -+ -+static grub_efi_net_interface_t * -+grub_efi_net_config_from_handle (grub_efi_handle_t *hnd, -+ struct grub_efi_net_device *netdev, -+ char **device, -+ char **path) -+{ -+ grub_efi_pxe_t *pxe = NULL; -+ -+ if (hnd == netdev->ip4_pxe_handle) -+ pxe = netdev->ip4_pxe; -+ else if (hnd == netdev->ip6_pxe_handle) -+ pxe = netdev->ip6_pxe; -+ -+ if (!pxe) -+ return (grub_efi_net_config_from_device_path ( -+ grub_efi_get_device_path (hnd), -+ netdev, -+ device, -+ path)); -+ -+ if (pxe->mode->using_ipv6) -+ { -+ grub_efi_net_ip_manual_address_t net_ip; -+ -+ pxe_get_boot_location_v6 ( -+ (const struct grub_net_dhcp6_packet *) &pxe->mode->dhcp_ack, -+ sizeof (pxe->mode->dhcp_ack), -+ device, -+ path); -+ -+ grub_memcpy (net_ip.ip6.address, pxe->mode->station_ip.v6, sizeof(net_ip.ip6.address)); -+ net_ip.ip6.prefix_length = GRUB_EFI_IP6_PREFIX_LENGTH; -+ net_ip.ip6.is_anycast = 0; -+ net_ip.is_ip6 = 1; -+ return (grub_efi_net_create_interface (netdev, -+ netdev->card_name, -+ &net_ip, -+ 1)); -+ } -+ else -+ { -+ grub_efi_net_ip_manual_address_t net_ip; -+ -+ pxe_get_boot_location ( -+ (const struct grub_net_bootp_packet *) &pxe->mode->dhcp_ack, -+ device, -+ path, -+ 1); -+ -+ grub_memcpy (net_ip.ip4.address, pxe->mode->station_ip.v4, sizeof (net_ip.ip4.address)); -+ grub_memcpy (net_ip.ip4.subnet_mask, pxe->mode->subnet_mask.v4, sizeof (net_ip.ip4.subnet_mask)); -+ net_ip.is_ip6 = 0; -+ return (grub_efi_net_create_interface (netdev, -+ netdev->card_name, -+ &net_ip, -+ 1)); -+ } -+} -+ -+static const char * -+grub_efi_net_var_get_address (struct grub_env_var *var, -+ const char *val __attribute__ ((unused))) -+{ -+ struct grub_efi_net_device *dev; -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ { -+ grub_efi_net_interface_t *inf; -+ -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ { -+ char *var_name; -+ -+ var_name = grub_xasprintf ("net_%s_ip", inf->name); -+ if (grub_strcmp (var_name, var->name) == 0) -+ return efi_net_interface_get_address (inf); -+ grub_free (var_name); -+ var_name = grub_xasprintf ("net_%s_mac", inf->name); -+ if (grub_strcmp (var_name, var->name) == 0) -+ return efi_net_interface_get_hw_address (inf); -+ grub_free (var_name); -+ } -+ } -+ -+ return NULL; -+} -+ -+static char * -+grub_efi_net_var_set_interface (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val) -+{ -+ struct grub_efi_net_device *dev; -+ grub_efi_net_interface_t *inf; -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ if (grub_strcmp (inf->name, val) == 0) -+ { -+ net_default_interface = inf; -+ return grub_strdup (val); -+ } -+ -+ return NULL; -+} -+ -+static char * -+grub_efi_net_var_set_server (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val) -+{ -+ grub_free (default_server); -+ default_server = grub_strdup (val); -+ return grub_strdup (val); -+} -+ -+static const char * -+grub_efi_net_var_get_server (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val __attribute__ ((unused))) -+{ -+ return default_server ? : ""; -+} -+ -+static const char * -+grub_efi_net_var_get_ip (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val __attribute__ ((unused))) -+{ -+ const char *intf = grub_env_get ("net_default_interface"); -+ const char *ret = NULL; -+ if (intf) -+ { -+ char *buf = grub_xasprintf ("net_%s_ip", intf); -+ if (buf) -+ ret = grub_env_get (buf); -+ grub_free (buf); -+ } -+ return ret; -+} -+ -+static const char * -+grub_efi_net_var_get_mac (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val __attribute__ ((unused))) -+{ -+ const char *intf = grub_env_get ("net_default_interface"); -+ const char *ret = NULL; -+ if (intf) -+ { -+ char *buf = grub_xasprintf ("net_%s_mac", intf); -+ if (buf) -+ ret = grub_env_get (buf); -+ grub_free (buf); -+ } -+ return ret; -+} -+ -+static void -+grub_efi_net_export_interface_vars (void) -+{ -+ struct grub_efi_net_device *dev; -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ { -+ grub_efi_net_interface_t *inf; -+ -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ { -+ char *var; -+ -+ var = grub_xasprintf ("net_%s_ip", inf->name); -+ grub_register_variable_hook (var, grub_efi_net_var_get_address, 0); -+ grub_env_export (var); -+ grub_free (var); -+ var = grub_xasprintf ("net_%s_mac", inf->name); -+ grub_register_variable_hook (var, grub_efi_net_var_get_address, 0); -+ grub_env_export (var); -+ grub_free (var); -+ } -+ } -+} -+ -+static void -+grub_efi_net_unset_interface_vars (void) -+{ -+ struct grub_efi_net_device *dev; -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ { -+ grub_efi_net_interface_t *inf; -+ -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ { -+ char *var; -+ -+ var = grub_xasprintf ("net_%s_ip", inf->name); -+ grub_register_variable_hook (var, 0, 0); -+ grub_env_unset (var); -+ grub_free (var); -+ var = grub_xasprintf ("net_%s_mac", inf->name); -+ grub_register_variable_hook (var, 0, 0); -+ grub_env_unset (var); -+ grub_free (var); -+ } -+ } -+} -+ -+grub_efi_net_interface_t * -+grub_efi_net_create_interface (struct grub_efi_net_device *dev, -+ const char *interface_name, -+ grub_efi_net_ip_manual_address_t *net_ip, -+ int has_subnet) -+{ -+ grub_efi_net_interface_t *inf; -+ -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ { -+ if (inf->prefer_ip6 == net_ip->is_ip6) -+ break; -+ } -+ -+ if (!inf) -+ { -+ inf = grub_malloc (sizeof(*inf)); -+ inf->name = grub_strdup (interface_name); -+ inf->prefer_ip6 = net_ip->is_ip6; -+ inf->dev = dev; -+ inf->next = dev->net_interfaces; -+ inf->ip_config = (net_ip->is_ip6) ? efi_net_ip6_config : efi_net_ip4_config ; -+ dev->net_interfaces = inf; -+ } -+ else -+ { -+ grub_free (inf->name); -+ inf->name = grub_strdup (interface_name); -+ } -+ -+ if (!efi_net_interface_set_address (inf, net_ip, has_subnet)) -+ { -+ grub_error (GRUB_ERR_BUG, N_("Set Address Failed")); -+ return NULL; -+ } -+ -+ return inf; -+} -+ -+static void -+grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, -+ char **path) -+{ -+ grub_efi_handle_t config_hnd; -+ -+ struct grub_efi_net_device *netdev; -+ grub_efi_net_interface_t *inf; -+ -+ config_hnd = grub_efi_locate_device_path (&ip4_config_guid, grub_efi_get_device_path (hnd), NULL); -+ -+ if (!config_hnd) -+ return; -+ -+ for (netdev = net_devices; netdev; netdev = netdev->next) -+ if (netdev->handle == config_hnd) -+ break; -+ -+ if (!netdev) -+ return; -+ -+ if (!(inf = grub_efi_net_config_from_handle (hnd, netdev, device, path))) -+ return; -+ -+ grub_env_set ("net_default_interface", inf->name); -+ grub_efi_net_export_interface_vars (); -+} -+ -+static grub_err_t -+grub_efi_netfs_dir (grub_device_t device, const char *path __attribute__ ((unused)), -+ grub_fs_dir_hook_t hook __attribute__ ((unused)), -+ void *hook_data __attribute__ ((unused))) -+{ -+ if (!device->net) -+ return grub_error (GRUB_ERR_BUG, "invalid net device"); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_efi_netfs_open (struct grub_file *file_out __attribute__ ((unused)), -+ const char *name __attribute__ ((unused))) -+{ -+ struct grub_file *file, *bufio; -+ -+ file = grub_malloc (sizeof (*file)); -+ if (!file) -+ return grub_errno; -+ -+ grub_memcpy (file, file_out, sizeof (struct grub_file)); -+ file->device->net->name = grub_strdup (name); -+ -+ if (!file->device->net->name) -+ { -+ grub_free (file); -+ return grub_errno; -+ } -+ -+ efi_net_interface(open, file, name); -+ grub_print_error (); -+ -+ bufio = grub_bufio_open (file, 32768); -+ if (!bufio) -+ { -+ grub_free (file->device->net->name); -+ grub_free (file); -+ return grub_errno; -+ } -+ grub_memcpy (file_out, bufio, sizeof (struct grub_file)); -+ grub_free (bufio); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_ssize_t -+grub_efihttp_chunk_read (grub_file_t file, char *buf, -+ grub_size_t len, grub_size_t chunk_size) -+{ -+ char *chunk = grub_malloc (chunk_size); -+ grub_size_t sum = 0; -+ -+ while (len) -+ { -+ grub_ssize_t rd; -+ grub_size_t sz = (len > chunk_size) ? chunk_size : len; -+ -+ rd = efi_net_interface (read, file, chunk, sz); -+ -+ if (rd <= 0) -+ return rd; -+ -+ if (buf) -+ { -+ grub_memcpy (buf, chunk, rd); -+ buf += rd; -+ } -+ sum += rd; -+ len -= rd; -+ } -+ -+ grub_free (chunk); -+ return sum; -+} -+ -+static grub_ssize_t -+grub_efi_netfs_read (grub_file_t file __attribute__ ((unused)), -+ char *buf __attribute__ ((unused)), grub_size_t len __attribute__ ((unused))) -+{ -+ if (file->offset > file->device->net->offset) -+ { -+ grub_efihttp_chunk_read (file, NULL, file->offset - file->device->net->offset, 10240); -+ } -+ else if (file->offset < file->device->net->offset) -+ { -+ efi_net_interface (close, file); -+ efi_net_interface (open, file, file->device->net->name); -+ if (file->offset) -+ grub_efihttp_chunk_read (file, NULL, file->offset, 10240); -+ } -+ -+ return efi_net_interface (read, file, buf, len); -+} -+ -+static grub_err_t -+grub_efi_netfs_close (grub_file_t file) -+{ -+ efi_net_interface (close, file); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_efi_handle_t -+grub_efi_service_binding (grub_efi_handle_t dev, grub_efi_guid_t *service_binding_guid) -+{ -+ grub_efi_service_binding_t *service; -+ grub_efi_status_t status; -+ grub_efi_handle_t child_dev = NULL; -+ -+ service = grub_efi_open_protocol (dev, service_binding_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ if (!service) -+ { -+ grub_error (GRUB_ERR_IO, N_("couldn't open efi service binding protocol")); -+ return NULL; -+ } -+ -+ status = efi_call_2 (service->create_child, service, &child_dev); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_IO, N_("Failed to create child device of http service %x"), status); -+ return NULL; -+ } -+ -+ return child_dev; -+} -+ -+static grub_err_t -+grub_efi_net_parse_address (const char *address, -+ grub_efi_ip4_config2_manual_address_t *ip4, -+ grub_efi_ip6_config_manual_address_t *ip6, -+ int *is_ip6, -+ int *has_cidr) -+{ -+ const char *rest; -+ -+ if (grub_efi_string_to_ip4_address (address, &ip4->address, &rest)) -+ { -+ *is_ip6 = 0; -+ if (*rest == '/') -+ { -+ grub_uint32_t subnet_mask_size; -+ -+ subnet_mask_size = grub_strtoul (rest + 1, (char **) &rest, 0); -+ -+ if (!grub_errno && subnet_mask_size <= 32 && *rest == 0) -+ { -+ grub_uint32_t subnet_mask; -+ -+ subnet_mask = grub_cpu_to_be32 ((0xffffffffU << (32 - subnet_mask_size))); -+ grub_memcpy (ip4->subnet_mask, &subnet_mask, sizeof (ip4->subnet_mask)); -+ if (has_cidr) -+ *has_cidr = 1; -+ return GRUB_ERR_NONE; -+ } -+ } -+ else if (*rest == 0) -+ { -+ grub_uint32_t subnet_mask = 0xffffffffU; -+ grub_memcpy (ip4->subnet_mask, &subnet_mask, sizeof (ip4->subnet_mask)); -+ if (has_cidr) -+ *has_cidr = 0; -+ return GRUB_ERR_NONE; -+ } -+ } -+ else if (grub_efi_string_to_ip6_address (address, &ip6->address, &rest)) -+ { -+ *is_ip6 = 1; -+ if (*rest == '/') -+ { -+ grub_efi_uint8_t prefix_length; -+ -+ prefix_length = grub_strtoul (rest + 1, (char **) &rest, 0); -+ if (!grub_errno && prefix_length <= 128 && *rest == 0) -+ { -+ ip6->prefix_length = prefix_length; -+ ip6->is_anycast = 0; -+ if (has_cidr) -+ *has_cidr = 1; -+ return GRUB_ERR_NONE; -+ } -+ } -+ else if (*rest == 0) -+ { -+ ip6->prefix_length = 128; -+ ip6->is_anycast = 0; -+ if (has_cidr) -+ *has_cidr = 0; -+ return GRUB_ERR_NONE; -+ } -+ } -+ -+ return grub_error (GRUB_ERR_NET_BAD_ADDRESS, -+ N_("unrecognised network address `%s'"), -+ address); -+} -+ -+static grub_efi_net_interface_t * -+match_route (const char *server) -+{ -+ grub_err_t err; -+ grub_efi_ip4_config2_manual_address_t ip4; -+ grub_efi_ip6_config_manual_address_t ip6; -+ grub_efi_net_interface_t *inf; -+ int is_ip6 = 0; -+ -+ err = grub_efi_net_parse_address (server, &ip4, &ip6, &is_ip6, 0); -+ -+ if (err) -+ { -+ grub_print_error (); -+ return NULL; -+ } -+ -+ if (is_ip6) -+ { -+ struct grub_efi_net_device *dev; -+ grub_efi_net_ip_address_t addr; -+ -+ grub_memcpy (addr.ip6, ip6.address, sizeof(ip6.address)); -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ if ((inf = efi_net_ip6_config->best_interface (dev, &addr))) -+ return inf; -+ } -+ else -+ { -+ struct grub_efi_net_device *dev; -+ grub_efi_net_ip_address_t addr; -+ -+ grub_memcpy (addr.ip4, ip4.address, sizeof(ip4.address)); -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ if ((inf = efi_net_ip4_config->best_interface (dev, &addr))) -+ return inf; -+ } -+ -+ return 0; -+} -+ -+static void -+grub_efi_net_add_pxebc_to_cards (void) -+{ -+ grub_efi_uintn_t num_handles; -+ grub_efi_handle_t *handles; -+ grub_efi_handle_t *handle; -+ -+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &pxe_io_guid, -+ 0, &num_handles); -+ if (!handles) -+ return; -+ -+ for (handle = handles; num_handles--; handle++) -+ { -+ grub_efi_device_path_t *dp, *ddp, *ldp; -+ grub_efi_pxe_t *pxe; -+ struct grub_efi_net_device *d; -+ int is_ip6 = 0; -+ -+ dp = grub_efi_get_device_path (*handle); -+ if (!dp) -+ continue; -+ -+ ddp = grub_efi_duplicate_device_path (dp); -+ ldp = grub_efi_find_last_device_path (ddp); -+ -+ if (ldp->type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE -+ && ldp->subtype == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE) -+ { -+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ ldp->length = sizeof (*ldp); -+ } -+ else if (ldp->type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE -+ && ldp->subtype == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE) -+ { -+ is_ip6 = 1; -+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ ldp->length = sizeof (*ldp); -+ } -+ -+ for (d = net_devices; d; d = d->next) -+ if (grub_efi_compare_device_paths (ddp, grub_efi_get_device_path (d->handle)) == 0) -+ break; -+ -+ if (!d) -+ { -+ grub_free (ddp); -+ continue; -+ } -+ -+ pxe = grub_efi_open_protocol (*handle, &pxe_io_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ -+ if (!pxe) -+ { -+ grub_free (ddp); -+ continue; -+ } -+ -+ if (is_ip6) -+ { -+ d->ip6_pxe_handle = *handle; -+ d->ip6_pxe = pxe; -+ } -+ else -+ { -+ d->ip4_pxe_handle = *handle; -+ d->ip4_pxe = pxe; -+ } -+ -+ grub_free (ddp); -+ } -+ -+ grub_free (handles); -+} -+ -+static void -+set_ip_policy_to_static (void) -+{ -+ struct grub_efi_net_device *dev; -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ { -+ grub_efi_ip4_config2_policy_t ip4_policy = GRUB_EFI_IP4_CONFIG2_POLICY_STATIC; -+ -+ if (efi_call_4 (dev->ip4_config->set_data, dev->ip4_config, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_POLICY, -+ sizeof (ip4_policy), &ip4_policy) != GRUB_EFI_SUCCESS) -+ grub_dprintf ("efinetfs", "could not set GRUB_EFI_IP4_CONFIG2_POLICY_STATIC on dev `%s'", dev->card_name); -+ -+ if (dev->ip6_config) -+ { -+ grub_efi_ip6_config_policy_t ip6_policy = GRUB_EFI_IP6_CONFIG_POLICY_MANUAL; -+ -+ if (efi_call_4 (dev->ip6_config->set_data, dev->ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_POLICY, -+ sizeof (ip6_policy), &ip6_policy) != GRUB_EFI_SUCCESS) -+ grub_dprintf ("efinetfs", "could not set GRUB_EFI_IP6_CONFIG_POLICY_MANUAL on dev `%s'", dev->card_name); -+ } -+ } -+} -+ -+/* FIXME: Do not fail if the card did not support any of the protocol (Eg http) */ -+static void -+grub_efi_net_find_cards (void) -+{ -+ grub_efi_uintn_t num_handles; -+ grub_efi_handle_t *handles; -+ grub_efi_handle_t *handle; -+ int id; -+ -+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &ip4_config_guid, -+ 0, &num_handles); -+ if (!handles) -+ return; -+ -+ for (id = 0, handle = handles; num_handles--; handle++, id++) -+ { -+ grub_efi_device_path_t *dp; -+ grub_efi_ip4_config2_protocol_t *ip4_config; -+ grub_efi_ip6_config_protocol_t *ip6_config; -+ grub_efi_handle_t http_handle; -+ grub_efi_http_t *http; -+ grub_efi_handle_t dhcp4_handle; -+ grub_efi_dhcp4_protocol_t *dhcp4; -+ grub_efi_handle_t dhcp6_handle; -+ grub_efi_dhcp6_protocol_t *dhcp6; -+ -+ struct grub_efi_net_device *d; -+ -+ dp = grub_efi_get_device_path (*handle); -+ if (!dp) -+ continue; -+ -+ ip4_config = grub_efi_open_protocol (*handle, &ip4_config_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ if (!ip4_config) -+ continue; -+ -+ ip6_config = grub_efi_open_protocol (*handle, &ip6_config_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ -+ http_handle = grub_efi_service_binding (*handle, &http_service_binding_guid); -+ grub_errno = GRUB_ERR_NONE; -+ http = (http_handle) -+ ? grub_efi_open_protocol (http_handle, &http_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL) -+ : NULL; -+ -+ dhcp4_handle = grub_efi_service_binding (*handle, &dhcp4_service_binding_guid); -+ grub_errno = GRUB_ERR_NONE; -+ dhcp4 = (dhcp4_handle) -+ ? grub_efi_open_protocol (dhcp4_handle, &dhcp4_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL) -+ : NULL; -+ -+ -+ dhcp6_handle = grub_efi_service_binding (*handle, &dhcp6_service_binding_guid); -+ grub_errno = GRUB_ERR_NONE; -+ dhcp6 = (dhcp6_handle) -+ ? grub_efi_open_protocol (dhcp6_handle, &dhcp6_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL) -+ : NULL; -+ -+ d = grub_malloc (sizeof (*d)); -+ if (!d) -+ { -+ grub_free (handles); -+ while (net_devices) -+ { -+ d = net_devices->next; -+ grub_free (net_devices); -+ net_devices = d; -+ } -+ return; -+ } -+ d->handle = *handle; -+ d->ip4_config = ip4_config; -+ d->ip6_config = ip6_config; -+ d->http_handle = http_handle; -+ d->http = http; -+ d->dhcp4_handle = dhcp4_handle; -+ d->dhcp4 = dhcp4; -+ d->dhcp6_handle = dhcp6_handle; -+ d->dhcp6 = dhcp6; -+ d->next = net_devices; -+ d->card_name = grub_xasprintf ("efinet%d", id); -+ d->net_interfaces = NULL; -+ net_devices = d; -+ } -+ -+ grub_efi_net_add_pxebc_to_cards (); -+ grub_free (handles); -+ set_ip_policy_to_static (); -+} -+ -+static void -+listroutes_ip4 (struct grub_efi_net_device *netdev) -+{ -+ char **routes; -+ -+ routes = NULL; -+ -+ if ((routes = efi_net_ip4_config->get_route_table (netdev))) -+ { -+ char **r; -+ -+ for (r = routes; *r; ++r) -+ grub_printf ("%s\n", *r); -+ } -+ -+ if (routes) -+ { -+ char **r; -+ -+ for (r = routes; *r; ++r) -+ grub_free (*r); -+ grub_free (routes); -+ } -+} -+ -+static void -+listroutes_ip6 (struct grub_efi_net_device *netdev) -+{ -+ char **routes; -+ -+ routes = NULL; -+ -+ if ((routes = efi_net_ip6_config->get_route_table (netdev))) -+ { -+ char **r; -+ -+ for (r = routes; *r; ++r) -+ grub_printf ("%s\n", *r); -+ } -+ -+ if (routes) -+ { -+ char **r; -+ -+ for (r = routes; *r; ++r) -+ grub_free (*r); -+ grub_free (routes); -+ } -+} -+ -+static grub_err_t -+grub_cmd_efi_listroutes (struct grub_command *cmd __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **args __attribute__ ((unused))) -+{ -+ struct grub_efi_net_device *netdev; -+ -+ for (netdev = net_devices; netdev; netdev = netdev->next) -+ { -+ listroutes_ip4 (netdev); -+ listroutes_ip6 (netdev); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+static grub_err_t -+grub_cmd_efi_listcards (struct grub_command *cmd __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **args __attribute__ ((unused))) -+{ -+ struct grub_efi_net_device *dev; -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ { -+ char *hw_addr; -+ -+ hw_addr = efi_net_ip4_config->get_hw_address (dev); -+ -+ if (hw_addr) -+ { -+ grub_printf ("%s %s\n", dev->card_name, hw_addr); -+ grub_free (hw_addr); -+ } -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_efi_listaddrs (struct grub_command *cmd __attribute__ ((unused)), -+ int argc __attribute__ ((unused)), -+ char **args __attribute__ ((unused))) -+{ -+ struct grub_efi_net_device *dev; -+ grub_efi_net_interface_t *inf; -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ for (inf = dev->net_interfaces; inf; inf = inf->next) -+ { -+ char *hw_addr = NULL; -+ char *addr = NULL; -+ -+ if ((hw_addr = efi_net_interface_get_hw_address (inf)) -+ && (addr = efi_net_interface_get_address (inf))) -+ grub_printf ("%s %s %s\n", inf->name, hw_addr, addr); -+ -+ if (hw_addr) -+ grub_free (hw_addr); -+ if (addr) -+ grub_free (addr); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+/* FIXME: support MAC specifying. */ -+static grub_err_t -+grub_cmd_efi_addaddr (struct grub_command *cmd __attribute__ ((unused)), -+ int argc, char **args) -+{ -+ struct grub_efi_net_device *dev; -+ grub_err_t err; -+ grub_efi_ip4_config2_manual_address_t ip4; -+ grub_efi_ip6_config_manual_address_t ip6; -+ grub_efi_net_ip_manual_address_t net_ip; -+ int is_ip6 = 0; -+ int cidr = 0; -+ -+ if (argc != 3) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected")); -+ -+ for (dev = net_devices; dev; dev = dev->next) -+ { -+ if (grub_strcmp (dev->card_name, args[1]) == 0) -+ break; -+ } -+ -+ if (!dev) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("card not found")); -+ -+ err = grub_efi_net_parse_address (args[2], &ip4, &ip6, &is_ip6, &cidr); -+ -+ if (err) -+ return err; -+ -+ net_ip.is_ip6 = is_ip6; -+ if (is_ip6) -+ grub_memcpy (&net_ip.ip6, &ip6, sizeof(net_ip.ip6)); -+ else -+ grub_memcpy (&net_ip.ip4, &ip4, sizeof(net_ip.ip4)); -+ -+ if (!grub_efi_net_create_interface (dev, -+ args[0], -+ &net_ip, -+ cidr)) -+ return grub_errno; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static struct grub_fs grub_efi_netfs; -+ -+static grub_net_t -+grub_net_open_real (const char *name __attribute__ ((unused))) -+{ -+ grub_size_t protnamelen; -+ const char *protname, *server; -+ grub_net_t ret; -+ -+ net_interface = NULL; -+ -+ if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) -+ { -+ protname = "tftp"; -+ protnamelen = sizeof ("tftp") - 1; -+ server = name + sizeof ("pxe:") - 1; -+ } -+ else if (grub_strcmp (name, "pxe") == 0) -+ { -+ protname = "tftp"; -+ protnamelen = sizeof ("tftp") - 1; -+ server = default_server; -+ } -+ else -+ { -+ const char *comma; -+ -+ comma = grub_strchr (name, ','); -+ if (comma) -+ { -+ protnamelen = comma - name; -+ server = comma + 1; -+ protname = name; -+ } -+ else -+ { -+ protnamelen = grub_strlen (name); -+ server = default_server; -+ protname = name; -+ } -+ } -+ -+ if (!server) -+ { -+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, -+ N_("no server is specified")); -+ return NULL; -+ } -+ -+ /*FIXME: Use DNS translate name to address */ -+ net_interface = match_route (server); -+ -+ /*XXX: should we check device with default gateway ? */ -+ if (!net_interface && !(net_interface = net_default_interface)) -+ { -+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' no route found"), -+ name); -+ return NULL; -+ } -+ -+ if ((protnamelen == (sizeof ("https") - 1) -+ && grub_memcmp ("https", protname, protnamelen) == 0)) -+ { -+ net_interface->io = &io_http; -+ net_interface->io_type = 1; -+ } -+ else if ((protnamelen == (sizeof ("http") - 1) -+ && grub_memcmp ("http", protname, protnamelen) == 0)) -+ { -+ net_interface->io = &io_http; -+ net_interface->io_type = 0; -+ } -+ else if (protnamelen == (sizeof ("tftp") - 1) -+ && grub_memcmp ("tftp", protname, protnamelen) == 0) -+ { -+ net_interface->io = &io_pxe; -+ net_interface->io_type = 0; -+ } -+ else -+ { -+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), -+ name); -+ return NULL; -+ } -+ -+ /*XXX: Should we try to avoid doing excess "reconfigure" here ??? */ -+ efi_net_interface (configure); -+ -+ ret = grub_zalloc (sizeof (*ret)); -+ if (!ret) -+ return NULL; -+ -+ ret->server = grub_strdup (server); -+ if (!ret->server) -+ { -+ grub_free (ret); -+ return NULL; -+ } -+ -+ ret->fs = &grub_efi_netfs; -+ return ret; -+} -+#if 0 -+static grub_command_t cmd_efi_lsaddr; -+static grub_command_t cmd_efi_lscards; -+static grub_command_t cmd_efi_lsroutes; -+static grub_command_t cmd_efi_addaddr; -+#endif -+ -+static struct grub_fs grub_efi_netfs = -+ { -+ .name = "efi netfs", -+ .fs_dir = grub_efi_netfs_dir, -+ .fs_open = grub_efi_netfs_open, -+ .fs_read = grub_efi_netfs_read, -+ .fs_close = grub_efi_netfs_close, -+ .fs_label = NULL, -+ .fs_uuid = NULL, -+ .fs_mtime = NULL, -+ }; -+ -+int -+grub_efi_net_boot_from_https (void) -+{ -+ grub_efi_loaded_image_t *image = NULL; -+ grub_efi_device_path_t *dp; -+ -+ image = grub_efi_get_loaded_image (grub_efi_image_handle); -+ if (!image) -+ return 0; -+ -+ dp = grub_efi_get_device_path (image->device_handle); -+ -+ while (1) -+ { -+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); -+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); -+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); -+ -+ if ((type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE) -+ && (subtype == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) -+ { -+ grub_efi_uri_device_path_t *uri_dp = (grub_efi_uri_device_path_t *) dp; -+ return (grub_strncmp ((const char*)uri_dp->uri, "https://", sizeof ("https://") - 1) == 0) ? 1 : 0; -+ } -+ -+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) -+ break; -+ dp = (grub_efi_device_path_t *) ((char *) dp + len); -+ } -+ -+ return 0; -+} -+ -+int -+grub_efi_net_boot_from_opa (void) -+{ -+ grub_efi_loaded_image_t *image = NULL; -+ grub_efi_device_path_t *dp; -+ -+ image = grub_efi_get_loaded_image (grub_efi_image_handle); -+ if (!image) -+ return 0; -+ -+ dp = grub_efi_get_device_path (image->device_handle); -+ -+ while (1) -+ { -+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); -+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); -+ grub_efi_uint16_t len = GRUB_EFI_DEVICE_PATH_LENGTH (dp); -+ -+ if ((type == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE) -+ && (subtype == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)) -+ { -+ grub_efi_mac_address_device_path_t *mac_dp = (grub_efi_mac_address_device_path_t *)dp; -+ return (mac_dp->if_type == 0xC7) ? 1 : 0; -+ } -+ -+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) -+ break; -+ dp = (grub_efi_device_path_t *) ((char *) dp + len); -+ } -+ -+ return 0; -+} -+ -+static char * -+grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val __attribute__ ((unused))) -+{ -+ return NULL; -+} -+ -+grub_command_func_t grub_efi_net_list_routes = grub_cmd_efi_listroutes; -+grub_command_func_t grub_efi_net_list_cards = grub_cmd_efi_listcards; -+grub_command_func_t grub_efi_net_list_addrs = grub_cmd_efi_listaddrs; -+grub_command_func_t grub_efi_net_add_addr = grub_cmd_efi_addaddr; -+ -+int -+grub_efi_net_fs_init () -+{ -+ grub_efi_net_find_cards (); -+ grub_efi_net_config = grub_efi_net_config_real; -+ grub_net_open = grub_net_open_real; -+ grub_register_variable_hook ("net_default_server", grub_efi_net_var_get_server, -+ grub_efi_net_var_set_server); -+ grub_env_export ("net_default_server"); -+ grub_register_variable_hook ("pxe_default_server", grub_efi_net_var_get_server, -+ grub_efi_net_var_set_server); -+ grub_env_export ("pxe_default_server"); -+ grub_register_variable_hook ("net_default_interface", 0, -+ grub_efi_net_var_set_interface); -+ grub_env_export ("net_default_interface"); -+ grub_register_variable_hook ("net_default_ip", grub_efi_net_var_get_ip, -+ 0); -+ grub_env_export ("net_default_ip"); -+ grub_register_variable_hook ("net_default_mac", grub_efi_net_var_get_mac, -+ 0); -+ grub_env_export ("net_default_mac"); -+ -+ grub_env_set ("grub_netfs_type", "efi"); -+ grub_register_variable_hook ("grub_netfs_type", 0, grub_env_write_readonly); -+ grub_env_export ("grub_netfs_type"); -+ -+ return 1; -+} -+ -+void -+grub_efi_net_fs_fini (void) -+{ -+ grub_env_unset ("grub_netfs_type"); -+ grub_efi_net_unset_interface_vars (); -+ grub_register_variable_hook ("net_default_server", 0, 0); -+ grub_env_unset ("net_default_server"); -+ grub_register_variable_hook ("net_default_interface", 0, 0); -+ grub_env_unset ("net_default_interface"); -+ grub_register_variable_hook ("pxe_default_server", 0, 0); -+ grub_env_unset ("pxe_default_server"); -+ grub_register_variable_hook ("net_default_ip", 0, 0); -+ grub_env_unset ("net_default_ip"); -+ grub_register_variable_hook ("net_default_mac", 0, 0); -+ grub_env_unset ("net_default_mac"); -+ grub_efi_net_config = NULL; -+ grub_net_open = NULL; -+ grub_fs_unregister (&grub_efi_netfs); -+} -diff --git a/grub-core/net/efi/pxe.c b/grub-core/net/efi/pxe.c -new file mode 100644 -index 00000000000..531949cba5c ---- /dev/null -+++ b/grub-core/net/efi/pxe.c -@@ -0,0 +1,424 @@ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static grub_efi_ip6_config_manual_address_t * -+efi_ip6_config_manual_address (grub_efi_ip6_config_protocol_t *ip6_config) -+{ -+ grub_efi_uintn_t sz; -+ grub_efi_status_t status; -+ grub_efi_ip6_config_manual_address_t *manual_address; -+ -+ sz = sizeof (*manual_address); -+ manual_address = grub_malloc (sz); -+ if (!manual_address) -+ return NULL; -+ -+ status = efi_call_4 (ip6_config->get_data, ip6_config, -+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, -+ &sz, manual_address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (manual_address); -+ return NULL; -+ } -+ -+ return manual_address; -+} -+ -+static grub_efi_ip4_config2_manual_address_t * -+efi_ip4_config_manual_address (grub_efi_ip4_config2_protocol_t *ip4_config) -+{ -+ grub_efi_uintn_t sz; -+ grub_efi_status_t status; -+ grub_efi_ip4_config2_manual_address_t *manual_address; -+ -+ sz = sizeof (*manual_address); -+ manual_address = grub_malloc (sz); -+ if (!manual_address) -+ return NULL; -+ -+ status = efi_call_4 (ip4_config->get_data, ip4_config, -+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, -+ &sz, manual_address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_free (manual_address); -+ return NULL; -+ } -+ -+ return manual_address; -+} -+ -+static void -+pxe_configure (struct grub_efi_net_device *dev, int prefer_ip6) -+{ -+ grub_efi_pxe_t *pxe = (prefer_ip6) ? dev->ip6_pxe : dev->ip4_pxe; -+ -+ grub_efi_pxe_mode_t *mode = pxe->mode; -+ -+ if (!mode->started) -+ { -+ grub_efi_status_t status; -+ status = efi_call_2 (pxe->start, pxe, prefer_ip6); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ grub_printf ("Couldn't start PXE\n"); -+ } -+ -+#if 0 -+ grub_printf ("PXE STARTED: %u\n", mode->started); -+ grub_printf ("PXE USING IPV6: %u\n", mode->using_ipv6); -+#endif -+ -+ if (mode->using_ipv6) -+ { -+ grub_efi_ip6_config_manual_address_t *manual_address; -+ manual_address = efi_ip6_config_manual_address (dev->ip6_config); -+ -+ if (manual_address && -+ grub_memcmp (manual_address->address, mode->station_ip.v6, sizeof (manual_address->address)) != 0) -+ { -+ grub_efi_status_t status; -+ grub_efi_pxe_ip_address_t station_ip; -+ -+ grub_memcpy (station_ip.v6.addr, manual_address->address, sizeof (station_ip.v6.addr)); -+ status = efi_call_3 (pxe->set_station_ip, pxe, &station_ip, NULL); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ grub_printf ("Couldn't set station ip\n"); -+ -+ grub_free (manual_address); -+ } -+ } -+ else -+ { -+ grub_efi_ip4_config2_manual_address_t *manual_address; -+ manual_address = efi_ip4_config_manual_address (dev->ip4_config); -+ -+ if (manual_address && -+ grub_memcmp (manual_address->address, mode->station_ip.v4, sizeof (manual_address->address)) != 0) -+ { -+ grub_efi_status_t status; -+ grub_efi_pxe_ip_address_t station_ip; -+ grub_efi_pxe_ip_address_t subnet_mask; -+ -+ grub_memcpy (station_ip.v4.addr, manual_address->address, sizeof (station_ip.v4.addr)); -+ grub_memcpy (subnet_mask.v4.addr, manual_address->subnet_mask, sizeof (subnet_mask.v4.addr)); -+ -+ status = efi_call_3 (pxe->set_station_ip, pxe, &station_ip, &subnet_mask); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ grub_printf ("Couldn't set station ip\n"); -+ -+ grub_free (manual_address); -+ } -+ } -+ -+#if 0 -+ if (mode->using_ipv6) -+ { -+ grub_printf ("PXE STATION IP: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", -+ mode->station_ip.v6.addr[0], -+ mode->station_ip.v6.addr[1], -+ mode->station_ip.v6.addr[2], -+ mode->station_ip.v6.addr[3], -+ mode->station_ip.v6.addr[4], -+ mode->station_ip.v6.addr[5], -+ mode->station_ip.v6.addr[6], -+ mode->station_ip.v6.addr[7], -+ mode->station_ip.v6.addr[8], -+ mode->station_ip.v6.addr[9], -+ mode->station_ip.v6.addr[10], -+ mode->station_ip.v6.addr[11], -+ mode->station_ip.v6.addr[12], -+ mode->station_ip.v6.addr[13], -+ mode->station_ip.v6.addr[14], -+ mode->station_ip.v6.addr[15]); -+ } -+ else -+ { -+ grub_printf ("PXE STATION IP: %d.%d.%d.%d\n", -+ mode->station_ip.v4.addr[0], -+ mode->station_ip.v4.addr[1], -+ mode->station_ip.v4.addr[2], -+ mode->station_ip.v4.addr[3]); -+ grub_printf ("PXE SUBNET MASK: %d.%d.%d.%d\n", -+ mode->subnet_mask.v4.addr[0], -+ mode->subnet_mask.v4.addr[1], -+ mode->subnet_mask.v4.addr[2], -+ mode->subnet_mask.v4.addr[3]); -+ } -+#endif -+ -+ /* TODO: Set The Station IP to the IP2 Config */ -+} -+ -+static int -+parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) -+{ -+ grub_uint16_t newip[8]; -+ const char *ptr = val; -+ int word, quaddot = -1; -+ int bracketed = 0; -+ -+ if (ptr[0] == '[') { -+ bracketed = 1; -+ ptr++; -+ } -+ -+ if (ptr[0] == ':' && ptr[1] != ':') -+ return 0; -+ if (ptr[0] == ':') -+ ptr++; -+ -+ for (word = 0; word < 8; word++) -+ { -+ unsigned long t; -+ if (*ptr == ':') -+ { -+ quaddot = word; -+ word--; -+ ptr++; -+ continue; -+ } -+ t = grub_strtoul (ptr, (char **) &ptr, 16); -+ if (grub_errno) -+ { -+ grub_errno = GRUB_ERR_NONE; -+ break; -+ } -+ if (t & ~0xffff) -+ return 0; -+ newip[word] = grub_cpu_to_be16 (t); -+ if (*ptr != ':') -+ break; -+ ptr++; -+ } -+ if (quaddot == -1 && word < 7) -+ return 0; -+ if (quaddot != -1) -+ { -+ grub_memmove (&newip[quaddot + 7 - word], &newip[quaddot], -+ (word - quaddot + 1) * sizeof (newip[0])); -+ grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0])); -+ } -+ grub_memcpy (ip, newip, 16); -+ if (bracketed && *ptr == ']') { -+ ptr++; -+ } -+ if (rest) -+ *rest = ptr; -+ return 1; -+} -+ -+static grub_err_t -+pxe_open (struct grub_efi_net_device *dev, -+ int prefer_ip6, -+ grub_file_t file, -+ const char *filename, -+ int type __attribute__((unused))) -+{ -+ int i; -+ char *p; -+ grub_efi_status_t status; -+ grub_efi_pxe_ip_address_t server_ip; -+ grub_efi_uint64_t file_size = 0; -+ grub_efi_pxe_t *pxe = (prefer_ip6) ? dev->ip6_pxe : dev->ip4_pxe; -+ -+ if (pxe->mode->using_ipv6) -+ { -+ const char *rest; -+ grub_uint64_t ip6[2]; -+ if (parse_ip6 (file->device->net->server, ip6, &rest) && *rest == 0) -+ grub_memcpy (server_ip.v6.addr, ip6, sizeof (server_ip.v6.addr)); -+ /* TODO: ERROR Handling Here */ -+#if 0 -+ grub_printf ("PXE SERVER IP: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", -+ server_ip.v6.addr[0], -+ server_ip.v6.addr[1], -+ server_ip.v6.addr[2], -+ server_ip.v6.addr[3], -+ server_ip.v6.addr[4], -+ server_ip.v6.addr[5], -+ server_ip.v6.addr[6], -+ server_ip.v6.addr[7], -+ server_ip.v6.addr[8], -+ server_ip.v6.addr[9], -+ server_ip.v6.addr[10], -+ server_ip.v6.addr[11], -+ server_ip.v6.addr[12], -+ server_ip.v6.addr[13], -+ server_ip.v6.addr[14], -+ server_ip.v6.addr[15]); -+#endif -+ } -+ else -+ { -+ for (i = 0, p = file->device->net->server; i < 4; ++i, ++p) -+ server_ip.v4.addr[i] = grub_strtoul (p, &p, 10); -+ } -+ -+ status = efi_call_10 (pxe->mtftp, -+ pxe, -+ GRUB_EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, -+ NULL, -+ 0, -+ &file_size, -+ NULL, -+ &server_ip, -+ (grub_efi_char8_t *)filename, -+ NULL, -+ 0); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return grub_error (GRUB_ERR_IO, "Couldn't get file size"); -+ -+ file->size = (grub_off_t)file_size; -+ file->not_easily_seekable = 0; -+ file->data = 0; -+ file->device->net->offset = 0; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+pxe_close (struct grub_efi_net_device *dev __attribute__((unused)), -+ int prefer_ip6 __attribute__((unused)), -+ grub_file_t file __attribute__((unused))) -+{ -+ file->offset = 0; -+ file->size = 0; -+ file->device->net->offset = 0; -+ -+ if (file->data) -+ { -+ grub_free (file->data); -+ file->data = NULL; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_ssize_t -+pxe_read (struct grub_efi_net_device *dev, -+ int prefer_ip6, -+ grub_file_t file, -+ char *buf, -+ grub_size_t len) -+{ -+ int i; -+ char *p; -+ grub_efi_status_t status; -+ grub_efi_pxe_t *pxe = (prefer_ip6) ? dev->ip6_pxe : dev->ip4_pxe; -+ grub_efi_uint64_t bufsz = len; -+ grub_efi_pxe_ip_address_t server_ip; -+ char *buf2 = NULL; -+ -+ if (file->data) -+ { -+ /* TODO: RANGE Check for offset and file size */ -+ grub_memcpy (buf, (char*)file->data + file->device->net->offset, len); -+ file->device->net->offset += len; -+ return len; -+ } -+ -+ if (file->device->net->offset) -+ { -+ grub_error (GRUB_ERR_BUG, "No Offet Read Possible"); -+ grub_print_error (); -+ return 0; -+ } -+ -+ if (pxe->mode->using_ipv6) -+ { -+ const char *rest; -+ grub_uint64_t ip6[2]; -+ if (parse_ip6 (file->device->net->server, ip6, &rest) && *rest == 0) -+ grub_memcpy (server_ip.v6.addr, ip6, sizeof (server_ip.v6.addr)); -+ /* TODO: ERROR Handling Here */ -+ } -+ else -+ { -+ for (i = 0, p = file->device->net->server; i < 4; ++i, ++p) -+ server_ip.v4.addr[i] = grub_strtoul (p, &p, 10); -+ } -+ -+ status = efi_call_10 (pxe->mtftp, -+ pxe, -+ GRUB_EFI_PXE_BASE_CODE_TFTP_READ_FILE, -+ buf, -+ 0, -+ &bufsz, -+ NULL, -+ &server_ip, -+ (grub_efi_char8_t *)file->device->net->name, -+ NULL, -+ 0); -+ -+ if (bufsz != file->size) -+ { -+ grub_error (GRUB_ERR_BUG, "Short read should not happen here"); -+ grub_print_error (); -+ return 0; -+ } -+ -+ if (status == GRUB_EFI_BUFFER_TOO_SMALL) -+ { -+ -+ buf2 = grub_malloc (bufsz); -+ -+ if (!buf2) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "ERROR OUT OF MEMORY"); -+ grub_print_error (); -+ return 0; -+ } -+ -+ status = efi_call_10 (pxe->mtftp, -+ pxe, -+ GRUB_EFI_PXE_BASE_CODE_TFTP_READ_FILE, -+ buf2, -+ 0, -+ &bufsz, -+ NULL, -+ &server_ip, -+ (grub_efi_char8_t *)file->device->net->name, -+ NULL, -+ 0); -+ } -+ -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ if (buf2) -+ grub_free (buf2); -+ -+ grub_error (GRUB_ERR_IO, "Failed to Read File"); -+ grub_print_error (); -+ return 0; -+ } -+ -+ if (buf2) -+ grub_memcpy (buf, buf2, len); -+ -+ file->device->net->offset = len; -+ -+ if (buf2) -+ file->data = buf2; -+ -+ return len; -+} -+ -+struct grub_efi_net_io io_pxe = -+ { -+ .configure = pxe_configure, -+ .open = pxe_open, -+ .read = pxe_read, -+ .close = pxe_close -+ }; -+ -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 0ce5e675ed7..55aed92722c 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -32,6 +32,9 @@ - #include - #include - #include -+#ifdef GRUB_MACHINE_EFI -+#include -+#endif - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -2033,8 +2036,49 @@ static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; - static grub_command_t cmd_lsroutes, cmd_lscards; - static grub_command_t cmd_lsaddr, cmd_slaac; - -+#ifdef GRUB_MACHINE_EFI -+ -+static enum { -+ INIT_MODE_NONE, -+ INIT_MODE_GRUB, -+ INIT_MODE_EFI -+} init_mode; -+ -+static grub_command_t cmd_bootp, cmd_bootp6; -+ -+#endif -+ - GRUB_MOD_INIT(net) - { -+#ifdef GRUB_MACHINE_EFI -+ if (grub_net_open) -+ return; -+ -+ if ((grub_efi_net_boot_from_https () || grub_efi_net_boot_from_opa ()) -+ && grub_efi_net_fs_init ()) -+ { -+ cmd_lsroutes = grub_register_command ("net_ls_routes", grub_efi_net_list_routes, -+ "", N_("list network routes")); -+ cmd_lscards = grub_register_command ("net_ls_cards", grub_efi_net_list_cards, -+ "", N_("list network cards")); -+ cmd_lsaddr = grub_register_command ("net_ls_addr", grub_efi_net_list_addrs, -+ "", N_("list network addresses")); -+ cmd_addaddr = grub_register_command ("net_add_addr", grub_efi_net_add_addr, -+ /* TRANSLATORS: HWADDRESS stands for -+ "hardware address". */ -+ N_("SHORTNAME CARD ADDRESS [HWADDRESS]"), -+ N_("Add a network address.")); -+ cmd_bootp = grub_register_command ("net_bootp", grub_efi_net_bootp, -+ N_("[CARD]"), -+ N_("perform a bootp autoconfiguration")); -+ cmd_bootp6 = grub_register_command ("net_bootp6", grub_efi_net_bootp6, -+ N_("[CARD]"), -+ N_("perform a bootp autoconfiguration")); -+ init_mode = INIT_MODE_EFI; -+ return; -+ } -+#endif -+ - grub_register_variable_hook ("net_default_server", defserver_get_env, - defserver_set_env); - grub_env_export ("net_default_server"); -@@ -2082,10 +2126,37 @@ GRUB_MOD_INIT(net) - grub_net_restore_hw, - GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); - grub_net_poll_cards_idle = grub_net_poll_cards_idle_real; -+ -+#ifdef GRUB_MACHINE_EFI -+ grub_env_set ("grub_netfs_type", "grub"); -+ grub_register_variable_hook ("grub_netfs_type", 0, grub_env_write_readonly); -+ grub_env_export ("grub_netfs_type"); -+ init_mode = INIT_MODE_GRUB; -+#endif -+ - } - - GRUB_MOD_FINI(net) - { -+ -+#ifdef GRUB_MACHINE_EFI -+ if (init_mode == INIT_MODE_NONE) -+ return; -+ -+ if (init_mode == INIT_MODE_EFI) -+ { -+ grub_unregister_command (cmd_lsroutes); -+ grub_unregister_command (cmd_lscards); -+ grub_unregister_command (cmd_lsaddr); -+ grub_unregister_command (cmd_addaddr); -+ grub_unregister_command (cmd_bootp); -+ grub_unregister_command (cmd_bootp6); -+ grub_efi_net_fs_fini (); -+ init_mode = INIT_MODE_NONE; -+ return; -+ } -+#endif -+ - grub_register_variable_hook ("net_default_server", 0, 0); - grub_register_variable_hook ("pxe_default_server", 0, 0); - -@@ -2104,4 +2175,7 @@ GRUB_MOD_FINI(net) - grub_net_fini_hw (0); - grub_loader_unregister_preboot_hook (fini_hnd); - grub_net_poll_cards_idle = grub_net_poll_cards_idle_real; -+#ifdef GRUB_MACHINE_EFI -+ init_mode = INIT_MODE_NONE; -+#endif - } -diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c -index a2461cda1c4..77958dd9dd5 100644 ---- a/util/grub-mknetdir.c -+++ b/util/grub-mknetdir.c -@@ -32,13 +32,15 @@ - - static char *rootdir = NULL, *subdir = NULL; - static char *debug_image = NULL; -+static char efi_netfs = 0; - - enum - { - OPTION_NET_DIRECTORY = 0x301, - OPTION_SUBDIR, - OPTION_DEBUG, -- OPTION_DEBUG_IMAGE -+ OPTION_DEBUG_IMAGE, -+ OPTION_DEBUG_EFI_NETFS - }; - - static struct argp_option options[] = { -@@ -49,6 +51,7 @@ static struct argp_option options[] = { - 0, N_("relative subdirectory on network server"), 2}, - {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, - {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2}, -+ {"debug-efi-netfs", OPTION_DEBUG_EFI_NETFS, 0, OPTION_HIDDEN, 0, 2}, - {0, 0, 0, 0, 0, 0} - }; - -@@ -67,6 +70,9 @@ argp_parser (int key, char *arg, struct argp_state *state) - free (subdir); - subdir = xstrdup (arg); - return 0; -+ case OPTION_DEBUG_EFI_NETFS: -+ efi_netfs = 1; -+ return 0; - /* This is an undocumented feature... */ - case OPTION_DEBUG: - verbosity++; -@@ -82,7 +88,6 @@ argp_parser (int key, char *arg, struct argp_state *state) - } - } - -- - struct argp argp = { - options, argp_parser, NULL, - "\v"N_("Prepares GRUB network boot images at net_directory/subdir " -@@ -92,7 +97,7 @@ struct argp argp = { - - static char *base; - --static const struct -+static struct - { - const char *mkimage_target; - const char *netmodule; -@@ -156,6 +161,7 @@ process_input_dir (const char *input_dir, enum grub_install_plat platform) - grub_install_push_module (targets[platform].netmodule); - - output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext); -+ - grub_install_make_image_wrap (input_dir, prefix, output, - 0, load_cfg, - targets[platform].mkimage_target, 0); -@@ -195,7 +201,16 @@ main (int argc, char *argv[]) - - grub_install_mkdir_p (base); - -- grub_install_push_module ("tftp"); -+ if (!efi_netfs) -+ { -+ grub_install_push_module ("tftp"); -+ grub_install_push_module ("http"); -+ } -+ else -+ { -+ targets[GRUB_INSTALL_PLATFORM_I386_EFI].netmodule = "efi_netfs"; -+ targets[GRUB_INSTALL_PLATFORM_X86_64_EFI].netmodule = "efi_netfs"; -+ } - - if (!grub_install_source_directory) - { -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 0b490195ad9..f431f49973e 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -622,6 +622,23 @@ typedef union - - typedef grub_efi_uint64_t grub_efi_physical_address_t; - typedef grub_efi_uint64_t grub_efi_virtual_address_t; -+typedef struct { -+ grub_uint8_t addr[4]; -+} grub_efi_pxe_ipv4_address_t; -+ -+typedef struct { -+ grub_uint8_t addr[16]; -+} grub_efi_pxe_ipv6_address_t; -+ -+typedef struct { -+ grub_uint8_t addr[32]; -+} grub_efi_pxe_mac_address_t; -+ -+typedef union { -+ grub_uint32_t addr[4]; -+ grub_efi_pxe_ipv4_address_t v4; -+ grub_efi_pxe_ipv6_address_t v6; -+} grub_efi_pxe_ip_address_t; - - struct grub_efi_guid - { -@@ -889,6 +906,8 @@ struct grub_efi_ipv6_device_path - grub_efi_uint16_t remote_port; - grub_efi_uint16_t protocol; - grub_efi_uint8_t static_ip_address; -+ grub_efi_uint8_t prefix_length; -+ grub_efi_ipv6_address_t gateway_ip_address; - } GRUB_PACKED; - typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t; - -@@ -938,6 +957,15 @@ struct grub_efi_uri_device_path - } GRUB_PACKED; - typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t; - -+#define GRUB_EFI_DNS_DEVICE_PATH_SUBTYPE 31 -+struct grub_efi_dns_device_path -+{ -+ grub_efi_device_path_t header; -+ grub_efi_uint8_t is_ipv6; -+ grub_efi_pxe_ip_address_t dns_server_ip[0]; -+} GRUB_PACKED; -+typedef struct grub_efi_dns_device_path grub_efi_dns_device_path_t; -+ - #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 - - /* Media Device Path. */ -@@ -1020,6 +1048,23 @@ struct grub_efi_bios_device_path - } GRUB_PACKED; - typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t; - -+/* Service Binding definitions */ -+struct grub_efi_service_binding; -+ -+typedef grub_efi_status_t -+(*grub_efi_service_binding_create_child) (struct grub_efi_service_binding *this, -+ grub_efi_handle_t *child_handle); -+ -+typedef grub_efi_status_t -+(*grub_efi_service_binding_destroy_child) (struct grub_efi_service_binding *this, -+ grub_efi_handle_t *child_handle); -+ -+typedef struct grub_efi_service_binding -+{ -+ grub_efi_service_binding_create_child create_child; -+ grub_efi_service_binding_destroy_child destroy_child; -+} grub_efi_service_binding_t; -+ - struct grub_efi_open_protocol_information_entry - { - grub_efi_handle_t agent_handle; -@@ -1569,23 +1614,27 @@ typedef struct grub_efi_pxe_tftp_error - grub_efi_char8_t error_string[127]; - } grub_efi_pxe_tftp_error_t; - --typedef struct { -- grub_uint8_t addr[4]; --} grub_efi_pxe_ipv4_address_t; -+typedef grub_efi_uint16_t grub_efi_pxe_base_code_udp_port_t; - --typedef struct { -- grub_uint8_t addr[16]; --} grub_efi_pxe_ipv6_address_t; -+typedef enum { -+ GRUB_EFI_PXE_BASE_CODE_TFTP_FIRST, -+ GRUB_EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, -+ GRUB_EFI_PXE_BASE_CODE_TFTP_READ_FILE, -+ GRUB_EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, -+ GRUB_EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY, -+ GRUB_EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE, -+ GRUB_EFI_PXE_BASE_CODE_MTFTP_READ_FILE, -+ GRUB_EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY, -+ GRUB_EFI_PXE_BASE_CODE_MTFTP_LAST -+} grub_efi_pxe_base_code_tftp_opcode_t; - - typedef struct { -- grub_uint8_t addr[32]; --} grub_efi_pxe_mac_address_t; -- --typedef union { -- grub_uint32_t addr[4]; -- grub_efi_pxe_ipv4_address_t v4; -- grub_efi_pxe_ipv6_address_t v6; --} grub_efi_pxe_ip_address_t; -+ grub_efi_ip_address_t mcast_ip; -+ grub_efi_pxe_base_code_udp_port_t c_port; -+ grub_efi_pxe_base_code_udp_port_t s_port; -+ grub_efi_uint16_t listen_timeout; -+ grub_efi_uint16_t transmit_timeout; -+} grub_efi_pxe_base_code_mtftp_info_t; - - #define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8 - typedef struct grub_efi_pxe_ip_filter -@@ -1652,17 +1701,31 @@ typedef struct grub_efi_pxe_mode - typedef struct grub_efi_pxe - { - grub_uint64_t rev; -- void (*start) (void); -+ grub_efi_status_t (*start) (struct grub_efi_pxe *this, grub_efi_boolean_t use_ipv6); - void (*stop) (void); -- void (*dhcp) (void); -+ grub_efi_status_t (*dhcp) (struct grub_efi_pxe *this, -+ grub_efi_boolean_t sort_offers); - void (*discover) (void); -- void (*mftp) (void); -+ grub_efi_status_t (*mtftp) (struct grub_efi_pxe *this, -+ grub_efi_pxe_base_code_tftp_opcode_t operation, -+ void *buffer_ptr, -+ grub_efi_boolean_t overwrite, -+ grub_efi_uint64_t *buffer_size, -+ grub_efi_uintn_t *block_size, -+ grub_efi_pxe_ip_address_t *server_ip, -+ //grub_efi_ip_address_t *server_ip, -+ grub_efi_char8_t *filename, -+ grub_efi_pxe_base_code_mtftp_info_t *info, -+ grub_efi_boolean_t dont_use_buffer); - void (*udpwrite) (void); - void (*udpread) (void); - void (*setipfilter) (void); - void (*arp) (void); - void (*setparams) (void); -- void (*setstationip) (void); -+ grub_efi_status_t (*set_station_ip) (struct grub_efi_pxe *this, -+ grub_efi_pxe_ip_address_t *new_station_ip, -+ grub_efi_pxe_ip_address_t *new_subnet_mask); -+ //void (*setstationip) (void); - void (*setpackets) (void); - struct grub_efi_pxe_mode *mode; - } grub_efi_pxe_t; -@@ -1924,6 +1987,44 @@ struct grub_efi_ip4_config2_protocol - }; - typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t; - -+struct grub_efi_ip4_route_table { -+ grub_efi_ipv4_address_t subnet_address; -+ grub_efi_ipv4_address_t subnet_mask; -+ grub_efi_ipv4_address_t gateway_address; -+}; -+ -+typedef struct grub_efi_ip4_route_table grub_efi_ip4_route_table_t; -+ -+#define GRUB_EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE 32 -+ -+struct grub_efi_ip4_config2_interface_info { -+ grub_efi_char16_t name[GRUB_EFI_IP4_CONFIG2_INTERFACE_INFO_NAME_SIZE]; -+ grub_efi_uint8_t if_type; -+ grub_efi_uint32_t hw_address_size; -+ grub_efi_mac_address_t hw_address; -+ grub_efi_ipv4_address_t station_address; -+ grub_efi_ipv4_address_t subnet_mask; -+ grub_efi_uint32_t route_table_size; -+ grub_efi_ip4_route_table_t *route_table; -+}; -+ -+typedef struct grub_efi_ip4_config2_interface_info grub_efi_ip4_config2_interface_info_t; -+ -+enum grub_efi_ip4_config2_policy { -+ GRUB_EFI_IP4_CONFIG2_POLICY_STATIC, -+ GRUB_EFI_IP4_CONFIG2_POLICY_DHCP, -+ GRUB_EFI_IP4_CONFIG2_POLICY_MAX -+}; -+ -+typedef enum grub_efi_ip4_config2_policy grub_efi_ip4_config2_policy_t; -+ -+struct grub_efi_ip4_config2_manual_address { -+ grub_efi_ipv4_address_t address; -+ grub_efi_ipv4_address_t subnet_mask; -+}; -+ -+typedef struct grub_efi_ip4_config2_manual_address grub_efi_ip4_config2_manual_address_t; -+ - enum grub_efi_ip6_config_data_type { - GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, - GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID, -@@ -1958,6 +2059,49 @@ struct grub_efi_ip6_config_protocol - }; - typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t; - -+enum grub_efi_ip6_config_policy { -+ GRUB_EFI_IP6_CONFIG_POLICY_MANUAL, -+ GRUB_EFI_IP6_CONFIG_POLICY_AUTOMATIC -+}; -+typedef enum grub_efi_ip6_config_policy grub_efi_ip6_config_policy_t; -+ -+struct grub_efi_ip6_address_info { -+ grub_efi_ipv6_address_t address; -+ grub_efi_uint8_t prefix_length; -+}; -+typedef struct grub_efi_ip6_address_info grub_efi_ip6_address_info_t; -+ -+struct grub_efi_ip6_route_table { -+ grub_efi_pxe_ipv6_address_t gateway; -+ grub_efi_pxe_ipv6_address_t destination; -+ grub_efi_uint8_t prefix_length; -+}; -+typedef struct grub_efi_ip6_route_table grub_efi_ip6_route_table_t; -+ -+struct grub_efi_ip6_config_interface_info { -+ grub_efi_char16_t name[32]; -+ grub_efi_uint8_t if_type; -+ grub_efi_uint32_t hw_address_size; -+ grub_efi_mac_address_t hw_address; -+ grub_efi_uint32_t address_info_count; -+ grub_efi_ip6_address_info_t *address_info; -+ grub_efi_uint32_t route_count; -+ grub_efi_ip6_route_table_t *route_table; -+}; -+typedef struct grub_efi_ip6_config_interface_info grub_efi_ip6_config_interface_info_t; -+ -+struct grub_efi_ip6_config_dup_addr_detect_transmits { -+ grub_efi_uint32_t dup_addr_detect_transmits; -+}; -+typedef struct grub_efi_ip6_config_dup_addr_detect_transmits grub_efi_ip6_config_dup_addr_detect_transmits_t; -+ -+struct grub_efi_ip6_config_manual_address { -+ grub_efi_ipv6_address_t address; -+ grub_efi_boolean_t is_anycast; -+ grub_efi_uint8_t prefix_length; -+}; -+typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_address_t; -+ - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ - || defined(__riscv) -diff --git a/include/grub/efi/dhcp.h b/include/grub/efi/dhcp.h -new file mode 100644 -index 00000000000..fdb88eb810e ---- /dev/null -+++ b/include/grub/efi/dhcp.h -@@ -0,0 +1,343 @@ -+#ifndef GRUB_EFI_DHCP_HEADER -+#define GRUB_EFI_DHCP_HEADER 1 -+ -+#define GRUB_EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID \ -+ { 0x9d9a39d8, 0xbd42, 0x4a73, \ -+ { 0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80 } \ -+ } -+ -+#define GRUB_EFI_DHCP4_PROTOCOL_GUID \ -+ { 0x8a219718, 0x4ef5, 0x4761, \ -+ { 0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56 } \ -+ } -+ -+#define GRUB_EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID \ -+ { 0x9fb9a8a1, 0x2f4a, 0x43a6, \ -+ { 0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4 ,0x7a, 0xd5 } \ -+ } -+ -+#define GRUB_EFI_DHCP6_PROTOCOL_GUID \ -+ { 0x87c8bad7, 0x595, 0x4053, \ -+ { 0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b } \ -+ } -+ -+typedef struct grub_efi_dhcp4_protocol grub_efi_dhcp4_protocol_t; -+ -+enum grub_efi_dhcp4_state { -+ GRUB_EFI_DHCP4_STOPPED, -+ GRUB_EFI_DHCP4_INIT, -+ GRUB_EFI_DHCP4_SELECTING, -+ GRUB_EFI_DHCP4_REQUESTING, -+ GRUB_EFI_DHCP4_BOUND, -+ GRUB_EFI_DHCP4_RENEWING, -+ GRUB_EFI_DHCP4_REBINDING, -+ GRUB_EFI_DHCP4_INIT_REBOOT, -+ GRUB_EFI_DHCP4_REBOOTING -+}; -+ -+typedef enum grub_efi_dhcp4_state grub_efi_dhcp4_state_t; -+ -+struct grub_efi_dhcp4_header { -+ grub_efi_uint8_t op_code; -+ grub_efi_uint8_t hw_type; -+ grub_efi_uint8_t hw_addr_len; -+ grub_efi_uint8_t hops; -+ grub_efi_uint32_t xid; -+ grub_efi_uint16_t seconds; -+ grub_efi_uint16_t reserved; -+ grub_efi_ipv4_address_t client_addr; -+ grub_efi_ipv4_address_t your_addr; -+ grub_efi_ipv4_address_t server_addr; -+ grub_efi_ipv4_address_t gateway_addr; -+ grub_efi_uint8_t client_hw_addr[16]; -+ grub_efi_char8_t server_name[64]; -+ grub_efi_char8_t boot_file_name[128]; -+} GRUB_PACKED; -+ -+typedef struct grub_efi_dhcp4_header grub_efi_dhcp4_header_t; -+ -+struct grub_efi_dhcp4_packet { -+ grub_efi_uint32_t size; -+ grub_efi_uint32_t length; -+ struct { -+ grub_efi_dhcp4_header_t header; -+ grub_efi_uint32_t magik; -+ grub_efi_uint8_t option[1]; -+ } dhcp4; -+} GRUB_PACKED; -+ -+typedef struct grub_efi_dhcp4_packet grub_efi_dhcp4_packet_t; -+ -+struct grub_efi_dhcp4_listen_point { -+ grub_efi_ipv4_address_t listen_address; -+ grub_efi_ipv4_address_t subnet_mask; -+ grub_efi_uint16_t listen_port; -+}; -+ -+typedef struct grub_efi_dhcp4_listen_point grub_efi_dhcp4_listen_point_t; -+ -+struct grub_efi_dhcp4_transmit_receive_token { -+ grub_efi_status_t status; -+ grub_efi_event_t completion_event; -+ grub_efi_ipv4_address_t remote_address; -+ grub_efi_uint16_t remote_port; -+ grub_efi_ipv4_address_t gateway_address; -+ grub_efi_uint32_t listen_point_count; -+ grub_efi_dhcp4_listen_point_t *listen_points; -+ grub_efi_uint32_t timeout_value; -+ grub_efi_dhcp4_packet_t *packet; -+ grub_efi_uint32_t response_count; -+ grub_efi_dhcp4_packet_t *response_list; -+}; -+ -+typedef struct grub_efi_dhcp4_transmit_receive_token grub_efi_dhcp4_transmit_receive_token_t; -+ -+enum grub_efi_dhcp4_event { -+ GRUB_EFI_DHCP4_SEND_DISCOVER = 0X01, -+ GRUB_EFI_DHCP4_RCVD_OFFER, -+ GRUB_EFI_DHCP4_SELECT_OFFER, -+ GRUB_EFI_DHCP4_SEND_REQUEST, -+ GRUB_EFI_DHCP4_RCVD_ACK, -+ GRUB_EFI_DHCP4_RCVD_NAK, -+ GRUB_EFI_DHCP4_SEND_DECLINE, -+ GRUB_EFI_DHCP4_BOUND_COMPLETED, -+ GRUB_EFI_DHCP4_ENTER_RENEWING, -+ GRUB_EFI_DHCP4_ENTER_REBINDING, -+ GRUB_EFI_DHCP4_ADDRESS_LOST, -+ GRUB_EFI_DHCP4_FAIL -+}; -+ -+typedef enum grub_efi_dhcp4_event grub_efi_dhcp4_event_t; -+ -+struct grub_efi_dhcp4_packet_option { -+ grub_efi_uint8_t op_code; -+ grub_efi_uint8_t length; -+ grub_efi_uint8_t data[1]; -+} GRUB_PACKED; -+ -+typedef struct grub_efi_dhcp4_packet_option grub_efi_dhcp4_packet_option_t; -+ -+struct grub_efi_dhcp4_config_data { -+ grub_efi_uint32_t discover_try_count; -+ grub_efi_uint32_t *discover_timeout; -+ grub_efi_uint32_t request_try_count; -+ grub_efi_uint32_t *request_timeout; -+ grub_efi_ipv4_address_t client_address; -+ grub_efi_status_t (*dhcp4_callback) ( -+ grub_efi_dhcp4_protocol_t *this, -+ void *context, -+ grub_efi_dhcp4_state_t current_state, -+ grub_efi_dhcp4_event_t dhcp4_event, -+ grub_efi_dhcp4_packet_t *packet, -+ grub_efi_dhcp4_packet_t **new_packet -+ ); -+ void *callback_context; -+ grub_efi_uint32_t option_count; -+ grub_efi_dhcp4_packet_option_t **option_list; -+}; -+ -+typedef struct grub_efi_dhcp4_config_data grub_efi_dhcp4_config_data_t; -+ -+struct grub_efi_dhcp4_mode_data { -+ grub_efi_dhcp4_state_t state; -+ grub_efi_dhcp4_config_data_t config_data; -+ grub_efi_ipv4_address_t client_address; -+ grub_efi_mac_address_t client_mac_address; -+ grub_efi_ipv4_address_t server_address; -+ grub_efi_ipv4_address_t router_address; -+ grub_efi_ipv4_address_t subnet_mask; -+ grub_efi_uint32_t lease_time; -+ grub_efi_dhcp4_packet_t *reply_packet; -+}; -+ -+typedef struct grub_efi_dhcp4_mode_data grub_efi_dhcp4_mode_data_t; -+ -+struct grub_efi_dhcp4_protocol { -+ grub_efi_status_t (*get_mode_data) (grub_efi_dhcp4_protocol_t *this, -+ grub_efi_dhcp4_mode_data_t *dhcp4_mode_data); -+ grub_efi_status_t (*configure) (grub_efi_dhcp4_protocol_t *this, -+ grub_efi_dhcp4_config_data_t *dhcp4_cfg_data); -+ grub_efi_status_t (*start) (grub_efi_dhcp4_protocol_t *this, -+ grub_efi_event_t completion_event); -+ grub_efi_status_t (*renew_rebind) (grub_efi_dhcp4_protocol_t *this, -+ grub_efi_boolean_t rebind_request, -+ grub_efi_event_t completion_event); -+ grub_efi_status_t (*release) (grub_efi_dhcp4_protocol_t *this); -+ grub_efi_status_t (*stop) (grub_efi_dhcp4_protocol_t *this); -+ grub_efi_status_t (*build) (grub_efi_dhcp4_protocol_t *this, -+ grub_efi_dhcp4_packet_t *seed_packet, -+ grub_efi_uint32_t delete_count, -+ grub_efi_uint8_t *delete_list, -+ grub_efi_uint32_t append_count, -+ grub_efi_dhcp4_packet_option_t *append_list[], -+ grub_efi_dhcp4_packet_t **new_packet); -+ grub_efi_status_t (*transmit_receive) (grub_efi_dhcp4_protocol_t *this, -+ grub_efi_dhcp4_transmit_receive_token_t *token); -+ grub_efi_status_t (*parse) (grub_efi_dhcp4_protocol_t *this, -+ grub_efi_dhcp4_packet_t *packet, -+ grub_efi_uint32_t *option_count, -+ grub_efi_dhcp4_packet_option_t *packet_option_list[]); -+}; -+ -+typedef struct grub_efi_dhcp6_protocol grub_efi_dhcp6_protocol_t; -+ -+struct grub_efi_dhcp6_retransmission { -+ grub_efi_uint32_t irt; -+ grub_efi_uint32_t mrc; -+ grub_efi_uint32_t mrt; -+ grub_efi_uint32_t mrd; -+}; -+ -+typedef struct grub_efi_dhcp6_retransmission grub_efi_dhcp6_retransmission_t; -+ -+enum grub_efi_dhcp6_event { -+ GRUB_EFI_DHCP6_SEND_SOLICIT, -+ GRUB_EFI_DHCP6_RCVD_ADVERTISE, -+ GRUB_EFI_DHCP6_SELECT_ADVERTISE, -+ GRUB_EFI_DHCP6_SEND_REQUEST, -+ GRUB_EFI_DHCP6_RCVD_REPLY, -+ GRUB_EFI_DHCP6_RCVD_RECONFIGURE, -+ GRUB_EFI_DHCP6_SEND_DECLINE, -+ GRUB_EFI_DHCP6_SEND_CONFIRM, -+ GRUB_EFI_DHCP6_SEND_RELEASE, -+ GRUB_EFI_DHCP6_SEND_RENEW, -+ GRUB_EFI_DHCP6_SEND_REBIND -+}; -+ -+typedef enum grub_efi_dhcp6_event grub_efi_dhcp6_event_t; -+ -+struct grub_efi_dhcp6_packet_option { -+ grub_efi_uint16_t op_code; -+ grub_efi_uint16_t op_len; -+ grub_efi_uint8_t data[1]; -+} GRUB_PACKED; -+ -+typedef struct grub_efi_dhcp6_packet_option grub_efi_dhcp6_packet_option_t; -+ -+struct grub_efi_dhcp6_header { -+ grub_efi_uint32_t transaction_id:24; -+ grub_efi_uint32_t message_type:8; -+} GRUB_PACKED; -+ -+typedef struct grub_efi_dhcp6_header grub_efi_dhcp6_header_t; -+ -+struct grub_efi_dhcp6_packet { -+ grub_efi_uint32_t size; -+ grub_efi_uint32_t length; -+ struct { -+ grub_efi_dhcp6_header_t header; -+ grub_efi_uint8_t option[1]; -+ } dhcp6; -+} GRUB_PACKED; -+ -+typedef struct grub_efi_dhcp6_packet grub_efi_dhcp6_packet_t; -+ -+struct grub_efi_dhcp6_ia_address { -+ grub_efi_ipv6_address_t ip_address; -+ grub_efi_uint32_t preferred_lifetime; -+ grub_efi_uint32_t valid_lifetime; -+}; -+ -+typedef struct grub_efi_dhcp6_ia_address grub_efi_dhcp6_ia_address_t; -+ -+enum grub_efi_dhcp6_state { -+ GRUB_EFI_DHCP6_INIT, -+ GRUB_EFI_DHCP6_SELECTING, -+ GRUB_EFI_DHCP6_REQUESTING, -+ GRUB_EFI_DHCP6_DECLINING, -+ GRUB_EFI_DHCP6_CONFIRMING, -+ GRUB_EFI_DHCP6_RELEASING, -+ GRUB_EFI_DHCP6_BOUND, -+ GRUB_EFI_DHCP6_RENEWING, -+ GRUB_EFI_DHCP6_REBINDING -+}; -+ -+typedef enum grub_efi_dhcp6_state grub_efi_dhcp6_state_t; -+ -+#define GRUB_EFI_DHCP6_IA_TYPE_NA 3 -+#define GRUB_EFI_DHCP6_IA_TYPE_TA 4 -+ -+struct grub_efi_dhcp6_ia_descriptor { -+ grub_efi_uint16_t type; -+ grub_efi_uint32_t ia_id; -+}; -+ -+typedef struct grub_efi_dhcp6_ia_descriptor grub_efi_dhcp6_ia_descriptor_t; -+ -+struct grub_efi_dhcp6_ia { -+ grub_efi_dhcp6_ia_descriptor_t descriptor; -+ grub_efi_dhcp6_state_t state; -+ grub_efi_dhcp6_packet_t *reply_packet; -+ grub_efi_uint32_t ia_address_count; -+ grub_efi_dhcp6_ia_address_t ia_address[1]; -+}; -+ -+typedef struct grub_efi_dhcp6_ia grub_efi_dhcp6_ia_t; -+ -+struct grub_efi_dhcp6_duid { -+ grub_efi_uint16_t length; -+ grub_efi_uint8_t duid[1]; -+}; -+ -+typedef struct grub_efi_dhcp6_duid grub_efi_dhcp6_duid_t; -+ -+struct grub_efi_dhcp6_mode_data { -+ grub_efi_dhcp6_duid_t *client_id; -+ grub_efi_dhcp6_ia_t *ia; -+}; -+ -+typedef struct grub_efi_dhcp6_mode_data grub_efi_dhcp6_mode_data_t; -+ -+struct grub_efi_dhcp6_config_data { -+ grub_efi_status_t (*dhcp6_callback) (grub_efi_dhcp6_protocol_t this, -+ void *context, -+ grub_efi_dhcp6_state_t current_state, -+ grub_efi_dhcp6_event_t dhcp6_event, -+ grub_efi_dhcp6_packet_t *packet, -+ grub_efi_dhcp6_packet_t **new_packet); -+ void *callback_context; -+ grub_efi_uint32_t option_count; -+ grub_efi_dhcp6_packet_option_t **option_list; -+ grub_efi_dhcp6_ia_descriptor_t ia_descriptor; -+ grub_efi_event_t ia_info_event; -+ grub_efi_boolean_t reconfigure_accept; -+ grub_efi_boolean_t rapid_commit; -+ grub_efi_dhcp6_retransmission_t *solicit_retransmission; -+}; -+ -+typedef struct grub_efi_dhcp6_config_data grub_efi_dhcp6_config_data_t; -+ -+struct grub_efi_dhcp6_protocol { -+ grub_efi_status_t (*get_mode_data) (grub_efi_dhcp6_protocol_t *this, -+ grub_efi_dhcp6_mode_data_t *dhcp6_mode_data, -+ grub_efi_dhcp6_config_data_t *dhcp6_config_data); -+ grub_efi_status_t (*configure) (grub_efi_dhcp6_protocol_t *this, -+ grub_efi_dhcp6_config_data_t *dhcp6_cfg_data); -+ grub_efi_status_t (*start) (grub_efi_dhcp6_protocol_t *this); -+ grub_efi_status_t (*info_request) (grub_efi_dhcp6_protocol_t *this, -+ grub_efi_boolean_t send_client_id, -+ grub_efi_dhcp6_packet_option_t *option_request, -+ grub_efi_uint32_t option_count, -+ grub_efi_dhcp6_packet_option_t *option_list[], -+ grub_efi_dhcp6_retransmission_t *retransmission, -+ grub_efi_event_t timeout_event, -+ grub_efi_status_t (*reply_callback) (grub_efi_dhcp6_protocol_t *this, -+ void *context, -+ grub_efi_dhcp6_packet_t *packet), -+ void *callback_context); -+ grub_efi_status_t (*renew_rebind) (grub_efi_dhcp6_protocol_t *this, -+ grub_efi_boolean_t rebind_request); -+ grub_efi_status_t (*decline) (grub_efi_dhcp6_protocol_t *this, -+ grub_efi_uint32_t address_count, -+ grub_efi_ipv6_address_t *addresses); -+ grub_efi_status_t (*release) (grub_efi_dhcp6_protocol_t *this, -+ grub_efi_uint32_t address_count, -+ grub_efi_ipv6_address_t *addresses); -+ grub_efi_status_t (*stop) (grub_efi_dhcp6_protocol_t *this); -+ grub_efi_status_t (*parse) (grub_efi_dhcp6_protocol_t *this, -+ grub_efi_dhcp6_packet_t *packet, -+ grub_efi_uint32_t *option_count, -+ grub_efi_dhcp6_packet_option_t *packet_option_list[]); -+}; -+ -+#endif /* ! GRUB_EFI_DHCP_HEADER */ -diff --git a/include/grub/efi/http.h b/include/grub/efi/http.h -new file mode 100644 -index 00000000000..c5e9a89f505 ---- /dev/null -+++ b/include/grub/efi/http.h -@@ -0,0 +1,215 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_EFI_HTTP_HEADER -+#define GRUB_EFI_HTTP_HEADER 1 -+ -+#include -+#include -+#include -+ -+#define GRUB_EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID \ -+ { 0xbdc8e6af, 0xd9bc, 0x4379, \ -+ { 0xa7, 0x2a, 0xe0, 0xc4, 0xe7, 0x5d, 0xae, 0x1c } \ -+ } -+ -+#define GRUB_EFI_HTTP_PROTOCOL_GUID \ -+ { 0x7A59B29B, 0x910B, 0x4171, \ -+ { 0x82, 0x42, 0xA8, 0x5A, 0x0D, 0xF2, 0x5B, 0x5B } \ -+ } -+ -+#define EFIHTTP_WAIT_TIME 10000 // 10000ms = 10s -+#define EFIHTTP_RX_BUF_LEN 10240 -+ -+//****************************************** -+// Protocol Interface Structure -+//****************************************** -+struct grub_efi_http; -+ -+//****************************************** -+// EFI_HTTP_VERSION -+//****************************************** -+typedef enum { -+ GRUB_EFI_HTTPVERSION10, -+ GRUB_EFI_HTTPVERSION11, -+ GRUB_EFI_HTTPVERSIONUNSUPPORTED -+} grub_efi_http_version_t; -+ -+//****************************************** -+// EFI_HTTPv4_ACCESS_POINT -+//****************************************** -+typedef struct { -+ grub_efi_boolean_t use_default_address; -+ grub_efi_ipv4_address_t local_address; -+ grub_efi_ipv4_address_t local_subnet; -+ grub_efi_uint16_t local_port; -+} grub_efi_httpv4_access_point_t; -+ -+//****************************************** -+// EFI_HTTPv6_ACCESS_POINT -+//****************************************** -+typedef struct { -+ grub_efi_ipv6_address_t local_address; -+ grub_efi_uint16_t local_port; -+} grub_efi_httpv6_access_point_t; -+ -+//****************************************** -+// EFI_HTTP_CONFIG_DATA -+//****************************************** -+typedef struct { -+ grub_efi_http_version_t http_version; -+ grub_efi_uint32_t timeout_millisec; -+ grub_efi_boolean_t local_address_is_ipv6; -+ union { -+ grub_efi_httpv4_access_point_t *ipv4_node; -+ grub_efi_httpv6_access_point_t *ipv6_node; -+ } access_point; -+} grub_efi_http_config_data_t; -+ -+//****************************************** -+// EFI_HTTP_METHOD -+//****************************************** -+typedef enum { -+ GRUB_EFI_HTTPMETHODGET, -+ GRUB_EFI_HTTPMETHODPOST, -+ GRUB_EFI_HTTPMETHODPATCH, -+ GRUB_EFI_HTTPMETHODOPTIONS, -+ GRUB_EFI_HTTPMETHODCONNECT, -+ GRUB_EFI_HTTPMETHODHEAD, -+ GRUB_EFI_HTTPMETHODPUT, -+ GRUB_EFI_HTTPMETHODDELETE, -+ GRUB_EFI_HTTPMETHODTRACE, -+} grub_efi_http_method_t; -+ -+//****************************************** -+// EFI_HTTP_REQUEST_DATA -+//****************************************** -+typedef struct { -+ grub_efi_http_method_t method; -+ grub_efi_char16_t *url; -+} grub_efi_http_request_data_t; -+ -+typedef enum { -+ GRUB_EFI_HTTP_STATUS_UNSUPPORTED_STATUS = 0, -+ GRUB_EFI_HTTP_STATUS_100_CONTINUE, -+ GRUB_EFI_HTTP_STATUS_101_SWITCHING_PROTOCOLS, -+ GRUB_EFI_HTTP_STATUS_200_OK, -+ GRUB_EFI_HTTP_STATUS_201_CREATED, -+ GRUB_EFI_HTTP_STATUS_202_ACCEPTED, -+ GRUB_EFI_HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION, -+ GRUB_EFI_HTTP_STATUS_204_NO_CONTENT, -+ GRUB_EFI_HTTP_STATUS_205_RESET_CONTENT, -+ GRUB_EFI_HTTP_STATUS_206_PARTIAL_CONTENT, -+ GRUB_EFI_HTTP_STATUS_300_MULTIPLE_CHIOCES, -+ GRUB_EFI_HTTP_STATUS_301_MOVED_PERMANENTLY, -+ GRUB_EFI_HTTP_STATUS_302_FOUND, -+ GRUB_EFI_HTTP_STATUS_303_SEE_OTHER, -+ GRUB_EFI_HTTP_STATUS_304_NOT_MODIFIED, -+ GRUB_EFI_HTTP_STATUS_305_USE_PROXY, -+ GRUB_EFI_HTTP_STATUS_307_TEMPORARY_REDIRECT, -+ GRUB_EFI_HTTP_STATUS_400_BAD_REQUEST, -+ GRUB_EFI_HTTP_STATUS_401_UNAUTHORIZED, -+ GRUB_EFI_HTTP_STATUS_402_PAYMENT_REQUIRED, -+ GRUB_EFI_HTTP_STATUS_403_FORBIDDEN, -+ GRUB_EFI_HTTP_STATUS_404_NOT_FOUND, -+ GRUB_EFI_HTTP_STATUS_405_METHOD_NOT_ALLOWED, -+ GRUB_EFI_HTTP_STATUS_406_NOT_ACCEPTABLE, -+ GRUB_EFI_HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED, -+ GRUB_EFI_HTTP_STATUS_408_REQUEST_TIME_OUT, -+ GRUB_EFI_HTTP_STATUS_409_CONFLICT, -+ GRUB_EFI_HTTP_STATUS_410_GONE, -+ GRUB_EFI_HTTP_STATUS_411_LENGTH_REQUIRED, -+ GRUB_EFI_HTTP_STATUS_412_PRECONDITION_FAILED, -+ GRUB_EFI_HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE, -+ GRUB_EFI_HTTP_STATUS_414_REQUEST_URI_TOO_LARGE, -+ GRUB_EFI_HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE, -+ GRUB_EFI_HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED, -+ GRUB_EFI_HTTP_STATUS_417_EXPECTATION_FAILED, -+ GRUB_EFI_HTTP_STATUS_500_INTERNAL_SERVER_ERROR, -+ GRUB_EFI_HTTP_STATUS_501_NOT_IMPLEMENTED, -+ GRUB_EFI_HTTP_STATUS_502_BAD_GATEWAY, -+ GRUB_EFI_HTTP_STATUS_503_SERVICE_UNAVAILABLE, -+ GRUB_EFI_HTTP_STATUS_504_GATEWAY_TIME_OUT, -+ GRUB_EFI_HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED -+} grub_efi_http_status_code_t; -+ -+//****************************************** -+// EFI_HTTP_RESPONSE_DATA -+//****************************************** -+typedef struct { -+ grub_efi_http_status_code_t status_code; -+} grub_efi_http_response_data_t; -+ -+//****************************************** -+// EFI_HTTP_HEADER -+//****************************************** -+typedef struct { -+ grub_efi_char8_t *field_name; -+ grub_efi_char8_t *field_value; -+} grub_efi_http_header_t; -+ -+//****************************************** -+// EFI_HTTP_MESSAGE -+//****************************************** -+typedef struct { -+ union { -+ grub_efi_http_request_data_t *request; -+ grub_efi_http_response_data_t *response; -+ } data; -+ grub_efi_uint32_t header_count; -+ grub_efi_http_header_t *headers; -+ grub_efi_uint32_t body_length; -+ void *body; -+} grub_efi_http_message_t; -+ -+//****************************************** -+// EFI_HTTP_TOKEN -+//****************************************** -+typedef struct { -+ grub_efi_event_t event; -+ grub_efi_status_t status; -+ grub_efi_http_message_t *message; -+} grub_efi_http_token_t; -+ -+struct grub_efi_http { -+ grub_efi_status_t -+ (*get_mode_data) (struct grub_efi_http *this, -+ grub_efi_http_config_data_t *http_config_data); -+ -+ grub_efi_status_t -+ (*configure) (struct grub_efi_http *this, -+ grub_efi_http_config_data_t *http_config_data); -+ -+ grub_efi_status_t -+ (*request) (struct grub_efi_http *this, -+ grub_efi_http_token_t *token); -+ -+ grub_efi_status_t -+ (*cancel) (struct grub_efi_http *this, -+ grub_efi_http_token_t *token); -+ -+ grub_efi_status_t -+ (*response) (struct grub_efi_http *this, -+ grub_efi_http_token_t *token); -+ -+ grub_efi_status_t -+ (*poll) (struct grub_efi_http *this); -+}; -+typedef struct grub_efi_http grub_efi_http_t; -+ -+#endif /* !GRUB_EFI_HTTP_HEADER */ -diff --git a/include/grub/net/efi.h b/include/grub/net/efi.h -new file mode 100644 -index 00000000000..de90d223e8e ---- /dev/null -+++ b/include/grub/net/efi.h -@@ -0,0 +1,144 @@ -+#ifndef GRUB_NET_EFI_HEADER -+#define GRUB_NET_EFI_HEADER 1 -+ -+#include -+#include -+#include -+#include -+ -+typedef struct grub_efi_net_interface grub_efi_net_interface_t; -+typedef struct grub_efi_net_ip_config grub_efi_net_ip_config_t; -+typedef union grub_efi_net_ip_address grub_efi_net_ip_address_t; -+typedef struct grub_efi_net_ip_manual_address grub_efi_net_ip_manual_address_t; -+ -+struct grub_efi_net_interface -+{ -+ char *name; -+ int prefer_ip6; -+ struct grub_efi_net_device *dev; -+ struct grub_efi_net_io *io; -+ grub_efi_net_ip_config_t *ip_config; -+ int io_type; -+ struct grub_efi_net_interface *next; -+}; -+ -+#define efi_net_interface_get_hw_address(inf) inf->ip_config->get_hw_address (inf->dev) -+#define efi_net_interface_get_address(inf) inf->ip_config->get_address (inf->dev) -+#define efi_net_interface_get_route_table(inf) inf->ip_config->get_route_table (inf->dev) -+#define efi_net_interface_set_address(inf, addr, with_subnet) inf->ip_config->set_address (inf->dev, addr, with_subnet) -+#define efi_net_interface_set_gateway(inf, addr) inf->ip_config->set_gateway (inf->dev, addr) -+#define efi_net_interface_set_dns(inf, addr) inf->ip_config->set_dns (inf->dev, addr) -+ -+struct grub_efi_net_ip_config -+{ -+ char * (*get_hw_address) (struct grub_efi_net_device *dev); -+ char * (*get_address) (struct grub_efi_net_device *dev); -+ char ** (*get_route_table) (struct grub_efi_net_device *dev); -+ grub_efi_net_interface_t * (*best_interface) (struct grub_efi_net_device *dev, grub_efi_net_ip_address_t *address); -+ int (*set_address) (struct grub_efi_net_device *dev, grub_efi_net_ip_manual_address_t *net_ip, int with_subnet); -+ int (*set_gateway) (struct grub_efi_net_device *dev, grub_efi_net_ip_address_t *address); -+ int (*set_dns) (struct grub_efi_net_device *dev, grub_efi_net_ip_address_t *dns); -+}; -+ -+union grub_efi_net_ip_address -+{ -+ grub_efi_ipv4_address_t ip4; -+ grub_efi_ipv6_address_t ip6; -+}; -+ -+struct grub_efi_net_ip_manual_address -+{ -+ int is_ip6; -+ union -+ { -+ grub_efi_ip4_config2_manual_address_t ip4; -+ grub_efi_ip6_config_manual_address_t ip6; -+ }; -+}; -+ -+struct grub_efi_net_device -+{ -+ grub_efi_handle_t handle; -+ grub_efi_ip4_config2_protocol_t *ip4_config; -+ grub_efi_ip6_config_protocol_t *ip6_config; -+ grub_efi_handle_t http_handle; -+ grub_efi_http_t *http; -+ grub_efi_handle_t ip4_pxe_handle; -+ grub_efi_pxe_t *ip4_pxe; -+ grub_efi_handle_t ip6_pxe_handle; -+ grub_efi_pxe_t *ip6_pxe; -+ grub_efi_handle_t dhcp4_handle; -+ grub_efi_dhcp4_protocol_t *dhcp4; -+ grub_efi_handle_t dhcp6_handle; -+ grub_efi_dhcp6_protocol_t *dhcp6; -+ char *card_name; -+ grub_efi_net_interface_t *net_interfaces; -+ struct grub_efi_net_device *next; -+}; -+ -+struct grub_efi_net_io -+{ -+ void (*configure) (struct grub_efi_net_device *dev, int prefer_ip6); -+ grub_err_t (*open) (struct grub_efi_net_device *dev, -+ int prefer_ip6, -+ grub_file_t file, -+ const char *filename, -+ int type); -+ grub_ssize_t (*read) (struct grub_efi_net_device *dev, -+ int prefer_ip6, -+ grub_file_t file, -+ char *buf, -+ grub_size_t len); -+ grub_err_t (*close) (struct grub_efi_net_device *dev, -+ int prefer_ip6, -+ grub_file_t file); -+}; -+ -+extern struct grub_efi_net_device *net_devices; -+ -+extern struct grub_efi_net_io io_http; -+extern struct grub_efi_net_io io_pxe; -+ -+extern grub_efi_net_ip_config_t *efi_net_ip4_config; -+extern grub_efi_net_ip_config_t *efi_net_ip6_config; -+ -+char * -+grub_efi_ip4_address_to_string (grub_efi_ipv4_address_t *address); -+ -+char * -+grub_efi_ip6_address_to_string (grub_efi_pxe_ipv6_address_t *address); -+ -+char * -+grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_address_t hw_address); -+ -+int -+grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *address, const char **rest); -+ -+int -+grub_efi_string_to_ip6_address (const char *val, grub_efi_ipv6_address_t *address, const char **rest); -+ -+char * -+grub_efi_ip6_interface_name (struct grub_efi_net_device *dev); -+ -+char * -+grub_efi_ip4_interface_name (struct grub_efi_net_device *dev); -+ -+grub_efi_net_interface_t * -+grub_efi_net_create_interface (struct grub_efi_net_device *dev, -+ const char *interface_name, -+ grub_efi_net_ip_manual_address_t *net_ip, -+ int has_subnet); -+ -+int grub_efi_net_fs_init (void); -+void grub_efi_net_fs_fini (void); -+int grub_efi_net_boot_from_https (void); -+int grub_efi_net_boot_from_opa (void); -+ -+extern grub_command_func_t grub_efi_net_list_routes; -+extern grub_command_func_t grub_efi_net_list_cards; -+extern grub_command_func_t grub_efi_net_list_addrs; -+extern grub_command_func_t grub_efi_net_add_addr; -+extern grub_command_func_t grub_efi_net_bootp; -+extern grub_command_func_t grub_efi_net_bootp6; -+ -+#endif /* ! GRUB_NET_EFI_HEADER */ diff --git a/0083-AUDIT-0-http-boot-tracker-bug.patch b/0083-AUDIT-0-http-boot-tracker-bug.patch deleted file mode 100644 index ef3e67b..0000000 --- a/0083-AUDIT-0-http-boot-tracker-bug.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sebastian Krahmer -Date: Tue, 28 Nov 2017 17:24:38 +0800 -Subject: [PATCH] AUDIT-0: http boot tracker bug - -Fixing a memory leak in case of error, and a integer overflow, leading to a -heap overflow due to overly large chunk sizes. - -We need to check against some maximum value, otherwise values like 0xffffffff -will eventually lead in the allocation functions to small sized buffers, since -the len is rounded up to the next reasonable alignment. The following memcpy -will then smash the heap, leading to RCE. - -This is no big issue for pure http boot, since its going to execute an -untrusted kernel anyway, but it will break trusted boot scenarios, where only -signed code is allowed to be executed. - -Signed-off-by: Michael Chang ---- - grub-core/net/efi/net.c | 4 +++- - grub-core/net/http.c | 5 ++++- - 2 files changed, 7 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 86bce6535d3..4bb308026ce 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -645,8 +645,10 @@ grub_efihttp_chunk_read (grub_file_t file, char *buf, - - rd = efi_net_interface (read, file, chunk, sz); - -- if (rd <= 0) -+ if (rd <= 0) { -+ grub_free (chunk); - return rd; -+ } - - if (buf) - { -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index 12a2632ea55..b52b558d631 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -31,7 +31,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); - - enum - { -- HTTP_PORT = 80 -+ HTTP_PORT = 80, -+ HTTP_MAX_CHUNK_SIZE = 0x80000000 - }; - - -@@ -78,6 +79,8 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) - if (data->in_chunk_len == 2) - { - data->chunk_rem = grub_strtoul (ptr, 0, 16); -+ if (data->chunk_rem > HTTP_MAX_CHUNK_SIZE) -+ return GRUB_ERR_NET_PACKET_TOO_BIG; - grub_errno = GRUB_ERR_NONE; - if (data->chunk_rem == 0) - { diff --git a/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch b/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch deleted file mode 100644 index f8de42a..0000000 --- a/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 4 Jun 2018 19:49:47 +0200 -Subject: [PATCH] grub-editenv: Add "incr" command to increment integer value - env. variables - -To be able to automatically detect if the last boot was successful, -We want to keep count of succesful / failed boots in some integer -environment variable. - -This commit adds a grub-editenvt "incr" command to increment such -integer value env. variables by 1 for use from various boot scripts. - -Signed-off-by: Hans de Goede ---- - util/grub-editenv.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 50 insertions(+) - -diff --git a/util/grub-editenv.c b/util/grub-editenv.c -index db6f187cc63..948eec8a114 100644 ---- a/util/grub-editenv.c -+++ b/util/grub-editenv.c -@@ -53,6 +53,9 @@ static struct argp_option options[] = { - /* TRANSLATORS: "unset" is a keyword. It's a summary of "unset" subcommand. */ - {N_("unset [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, - N_("Delete variables."), 0}, -+ /* TRANSLATORS: "incr" is a keyword. It's a summary of "incr" subcommand. */ -+ {N_("incr [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, -+ N_("Increase value of integer variables."), 0}, - - {0, 0, 0, OPTION_DOC, N_("Options:"), -1}, - {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, -@@ -253,6 +256,51 @@ unset_variables (const char *name, int argc, char *argv[]) - grub_envblk_close (envblk); - } - -+struct get_int_value_params { -+ char *varname; -+ int value; -+}; -+ -+static int -+get_int_value (const char *varname, const char *value, void *hook_data) -+{ -+ struct get_int_value_params *params = hook_data; -+ -+ if (strcmp (varname, params->varname) == 0) { -+ params->value = strtol (value, NULL, 10); -+ return 1; -+ } -+ return 0; -+} -+ -+static void -+incr_variables (const char *name, int argc, char *argv[]) -+{ -+ grub_envblk_t envblk; -+ char buf[16]; -+ -+ envblk = open_envblk_file (name); -+ while (argc) -+ { -+ struct get_int_value_params params = { -+ .varname = argv[0], -+ .value = 0, /* Consider unset variables 0 */ -+ }; -+ -+ grub_envblk_iterate (envblk, ¶ms, get_int_value); -+ snprintf(buf, sizeof(buf), "%d", params.value + 1); -+ -+ if (! grub_envblk_set (envblk, argv[0], buf)) -+ grub_util_error ("%s", _("environment block too small")); -+ -+ argc--; -+ argv++; -+ } -+ -+ write_envblk (name, envblk); -+ grub_envblk_close (envblk); -+} -+ - int - main (int argc, char *argv[]) - { -@@ -292,6 +340,8 @@ main (int argc, char *argv[]) - set_variables (filename, argc - curindex, argv + curindex); - else if (strcmp (command, "unset") == 0) - unset_variables (filename, argc - curindex, argv + curindex); -+ else if (strcmp (command, "incr") == 0) -+ incr_variables (filename, argc - curindex, argv + curindex); - else - { - char *program = xstrdup(program_name); diff --git a/0085-Add-auto-hide-menu-support.patch b/0085-Add-auto-hide-menu-support.patch deleted file mode 100644 index 863cd05..0000000 --- a/0085-Add-auto-hide-menu-support.patch +++ /dev/null @@ -1,189 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 6 Jun 2018 08:44:11 +0200 -Subject: [PATCH] Add auto-hide menu support - -On single-os systems we do not want to show the menu, unless something -went wrong with the previous boot, in which case the user may need the -menu to debug/fix the problem. - -This commit adds a new grub.d/00_menu_auto_hide file which emits a -config snippet implementing this. I've chosen to do this in a separate -grub.d file because chances of this going upstream are small and this way -it will be easier to rebase. - -Since auto-hiding the menu requires detecting the previous boot was ok, -we get fastboot support (where we don't check for a key at all) for free -so this commit also adds support for this. - -The new config-file code uses the following variables: - -menu_auto_hide Set this to "1" to activate the new auto-hide feature - Set this to "2" to auto-hide the menu even when multiple - operating systems are installed. Note the menu will still - auto show after booting an other os as that won't set - boot_success. -menu_show_once Set this to "1" to force showing the menu once. -boot_success The OS sets this to "1" to indicate a successful boot. -boot_indeterminate The OS increments this integer when rebooting after e.g. - installing updates or a selinux relabel. -fastboot If set to "1" and the conditions for auto-hiding the menu - are met, the menu is not shown and all checks for keypresses - are skipped, booting the default immediately. - -30_os-prober.in changes somewhat inspired by: -https://git.launchpad.net/~ubuntu-core-dev/grub/+git/ubuntu/tree/debian/patches/quick_boot.patch - -Signed-off-by: Hans de Goede ---- -Changes in v2: --Drop shutdown_success tests, there is no meaningful way for systemd to set - this flag (by the time it knows all filesystems are unmounted or read-only --Drop fwsetup_once support, systemd already supports booting directly into - the fwsetup by doing "systemctl reboot --firmware" ---- - Makefile.util.def | 6 +++++ - util/grub.d/01_menu_auto_hide.in | 48 ++++++++++++++++++++++++++++++++++++++++ - util/grub.d/30_os-prober.in | 18 +++++++++++++++ - 3 files changed, 72 insertions(+) - create mode 100644 util/grub.d/01_menu_auto_hide.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 48512bc6311..314e6f2acf8 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -458,6 +458,12 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = '01_menu_auto_hide'; -+ common = util/grub.d/01_menu_auto_hide.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '01_users'; - common = util/grub.d/01_users.in; -diff --git a/util/grub.d/01_menu_auto_hide.in b/util/grub.d/01_menu_auto_hide.in -new file mode 100644 -index 00000000000..ad175870a54 ---- /dev/null -+++ b/util/grub.d/01_menu_auto_hide.in -@@ -0,0 +1,48 @@ -+#! /bin/sh -+ -+# Disable / skip generating menu-auto-hide config parts on serial terminals -+for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do -+ case "$x" in -+ serial*) -+ exit 0 -+ ;; -+ esac -+done -+ -+cat << EOF -+if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then -+ set last_boot_ok=1 -+else -+ set last_boot_ok=0 -+fi -+ -+# Reset boot_indeterminate after a successful boot -+if [ "\${boot_success}" = "1" ] ; then -+ set boot_indeterminate=0 -+# Avoid boot_indeterminate causing the menu to be hidden more then once -+elif [ "\${boot_indeterminate}" = "1" ]; then -+ set boot_indeterminate=2 -+fi -+set boot_success=0 -+save_env boot_success boot_indeterminate -+ -+if [ x\$feature_timeout_style = xy ] ; then -+ if [ "\${menu_show_once}" ]; then -+ unset menu_show_once -+ save_env menu_show_once -+ set timeout_style=menu -+ set timeout=60 -+ elif [ "\${menu_auto_hide}" -a "\${last_boot_ok}" = "1" ]; then -+ set orig_timeout_style=\${timeout_style} -+ set orig_timeout=\${timeout} -+ if [ "\${fastboot}" = "1" ]; then -+ # timeout_style=menu + timeout=0 avoids the countdown code keypress check -+ set timeout_style=menu -+ set timeout=0 -+ else -+ set timeout_style=hidden -+ set timeout=1 -+ fi -+ fi -+fi -+EOF -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 4b27bd20153..3c9431cfcfb 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -42,6 +42,7 @@ if [ -z "${OSPROBED}" ] ; then - fi - - osx_entry() { -+ found_other_os=1 - # TRANSLATORS: it refers on the OS residing on device %s - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - hints="" -@@ -102,6 +103,7 @@ for OS in ${OSPROBED} ; do - - case ${BOOT} in - chain) -+ found_other_os=1 - - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - cat << EOF -@@ -132,6 +134,7 @@ EOF - EOF - ;; - efi) -+ found_other_os=1 - - EFIPATH=${DEVICE#*@} - DEVICE=${DEVICE%@*} -@@ -176,6 +179,7 @@ EOF - LINITRD="${LINITRD#/boot}" - fi - -+ found_other_os=1 - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - recovery_params="$(echo "${LPARAMS}" | grep single)" || true - counter=1 -@@ -257,6 +261,7 @@ EOF - done - ;; - hurd) -+ found_other_os=1 - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - cat << EOF - menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' { -@@ -283,6 +288,7 @@ EOF - EOF - ;; - minix) -+ found_other_os=1 - cat << EOF - menuentry "${LONGNAME} (on ${DEVICE}, Multiboot)" { - EOF -@@ -299,3 +305,15 @@ EOF - ;; - esac - done -+ -+# We override the results of the menu_auto_hide code here, this is a bit ugly, -+# but grub-mkconfig writes out the file linearly, so this is the only way -+if [ "${found_other_os}" = "1" ]; then -+ cat << EOF -+# Other OS found, undo autohiding of menu unless menu_auto_hide=2 -+if [ "\${orig_timeout_style}" -a "\${menu_auto_hide}" != "2" ]; then -+ set timeout_style=\${orig_timeout_style} -+ set timeout=\${orig_timeout} -+fi -+EOF -+fi diff --git a/0086-Add-grub-set-bootflag-utility.patch b/0086-Add-grub-set-bootflag-utility.patch deleted file mode 100644 index e39f8be..0000000 --- a/0086-Add-grub-set-bootflag-utility.patch +++ /dev/null @@ -1,295 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 12 Jun 2018 13:25:16 +0200 -Subject: [PATCH] Add grub-set-bootflag utility - -This commit adds a new grub-set-bootflag utility, which can be used -to set known bootflags in the grubenv: boot_success or menu_show_once. - -grub-set-bootflag is different from grub-editenv in 2 ways: - -1) It is intended to be executed by regular users so must be installed -as suid root. As such it is written to not use any existing grubenv -related code for easy auditing. - -It can't be executed through pkexec because we want to call it under gdm -and pkexec does not work under gdm due the gdm user having /sbin/nologin -as shell. - -2) Since it can be executed by regular users it only allows setting -(assigning a value of 1 to) bootflags which it knows about. Currently -those are just boot_success and menu_show_once. - -This commit also adds a couple of example systemd and files which show -how this can be used to set boot_success from a user-session: - -docs/grub-boot-success.service -docs/grub-boot-success.timer - -The 2 grub-boot-success.systemd files should be placed in /lib/systemd/user -and a symlink to grub-boot-success.timer should be added to -/lib/systemd/user/timers.target.wants. - -Signed-off-by: Hans de Goede -[makhomed: grub-boot-success.timer: Only run if not in a container] -Signed-off-by: Gena Makhomed -Signed-off-by: Robbie Harwood ---- - Makefile.util.def | 7 ++ - util/grub-set-bootflag.c | 160 +++++++++++++++++++++++++++++++++++++++++ - conf/Makefile.extra-dist | 3 + - docs/grub-boot-success.service | 6 ++ - docs/grub-boot-success.timer | 7 ++ - util/grub-set-bootflag.1 | 20 ++++++ - 6 files changed, 203 insertions(+) - create mode 100644 util/grub-set-bootflag.c - create mode 100644 docs/grub-boot-success.service - create mode 100644 docs/grub-boot-success.timer - create mode 100644 util/grub-set-bootflag.1 - -diff --git a/Makefile.util.def b/Makefile.util.def -index 314e6f2acf8..0b85a7fce4a 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -1446,3 +1446,10 @@ program = { - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - }; -+ -+program = { -+ name = grub-set-bootflag; -+ installdir = sbin; -+ mansection = 1; -+ common = util/grub-set-bootflag.c; -+}; -diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c -new file mode 100644 -index 00000000000..bb198f02351 ---- /dev/null -+++ b/util/grub-set-bootflag.c -@@ -0,0 +1,160 @@ -+/* grub-set-bootflag.c - tool to set boot-flags in the grubenv. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2018 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+/* -+ * NOTE this gets run by users as root (through pkexec), so this does not -+ * use any grub library / util functions to allow for easy auditing. -+ * The grub headers are only included to get certain defines. -+ */ -+ -+#include /* For *_DIR_NAME defines */ -+#include -+#include /* For GRUB_ENVBLK_DEFCFG define */ -+#include -+#include -+#include -+#include -+ -+#define GRUBENV "/" GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME "/" GRUB_ENVBLK_DEFCFG -+#define GRUBENV_SIZE 1024 -+ -+const char *bootflags[] = { -+ "boot_success", -+ "menu_show_once", -+ NULL -+}; -+ -+static void usage(void) -+{ -+ int i; -+ -+ fprintf (stderr, "Usage: 'grub-set-bootflag ', where is one of:\n"); -+ for (i = 0; bootflags[i]; i++) -+ fprintf (stderr, " %s\n", bootflags[i]); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ /* NOTE buf must be at least the longest bootflag length + 4 bytes */ -+ char env[GRUBENV_SIZE + 1], buf[64], *s; -+ const char *bootflag; -+ int i, len, ret; -+ FILE *f; -+ -+ if (argc != 2) -+ { -+ usage(); -+ return 1; -+ } -+ -+ for (i = 0; bootflags[i]; i++) -+ if (!strcmp (argv[1], bootflags[i])) -+ break; -+ if (!bootflags[i]) -+ { -+ fprintf (stderr, "Invalid bootflag: '%s'\n", argv[1]); -+ usage(); -+ return 1; -+ } -+ -+ bootflag = bootflags[i]; -+ len = strlen (bootflag); -+ -+ f = fopen (GRUBENV, "r"); -+ if (!f) -+ { -+ perror ("Error opening " GRUBENV " for reading"); -+ return 1; -+ } -+ -+ ret = fread (env, 1, GRUBENV_SIZE, f); -+ fclose (f); -+ if (ret != GRUBENV_SIZE) -+ { -+ errno = EINVAL; -+ perror ("Error reading from " GRUBENV); -+ return 1; -+ } -+ -+ /* 0 terminate env */ -+ env[GRUBENV_SIZE] = 0; -+ -+ if (strncmp (env, GRUB_ENVBLK_SIGNATURE, strlen (GRUB_ENVBLK_SIGNATURE))) -+ { -+ fprintf (stderr, "Error invalid environment block\n"); -+ return 1; -+ } -+ -+ /* Find a pre-existing definition of the bootflag */ -+ s = strstr (env, bootflag); -+ while (s && s[len] != '=') -+ s = strstr (s + len, bootflag); -+ -+ if (s && ((s[len + 1] != '0' && s[len + 1] != '1') || s[len + 2] != '\n')) -+ { -+ fprintf (stderr, "Pre-existing bootflag '%s' has unexpected value\n", bootflag); -+ return 1; -+ } -+ -+ /* No pre-existing bootflag? -> find free space */ -+ if (!s) -+ { -+ for (i = 0; i < (len + 3); i++) -+ buf[i] = '#'; -+ buf[i] = 0; -+ s = strstr (env, buf); -+ } -+ -+ if (!s) -+ { -+ fprintf (stderr, "No space in grubenv to store bootflag '%s'\n", bootflag); -+ return 1; -+ } -+ -+ /* The grubenv is not 0 terminated, so memcpy the name + '=' , '1', '\n' */ -+ snprintf(buf, sizeof(buf), "%s=1\n", bootflag); -+ memcpy(s, buf, len + 3); -+ -+ /* "r+", don't truncate so that the diskspace stays reserved */ -+ f = fopen (GRUBENV, "r+"); -+ if (!f) -+ { -+ perror ("Error opening " GRUBENV " for writing"); -+ return 1; -+ } -+ -+ ret = fwrite (env, 1, GRUBENV_SIZE, f); -+ if (ret != GRUBENV_SIZE) -+ { -+ perror ("Error writing to " GRUBENV); -+ return 1; -+ } -+ -+ ret = fflush (f); -+ if (ret) -+ { -+ perror ("Error flushing " GRUBENV); -+ return 1; -+ } -+ -+ fsync (fileno (f)); -+ fclose (f); -+ -+ return 0; -+} -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index b909f2c073a..ea58362b555 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -14,6 +14,9 @@ EXTRA_DIST += util/import_unicode.py - EXTRA_DIST += docs/autoiso.cfg - EXTRA_DIST += docs/grub.cfg - EXTRA_DIST += docs/osdetect.cfg -+EXTRA_DIST += docs/org.gnu.grub.policy -+EXTRA_DIST += docs/grub-boot-success.service -+EXTRA_DIST += docs/grub-boot-success.timer - - EXTRA_DIST += conf/i386-cygwin-img-ld.sc - -diff --git a/docs/grub-boot-success.service b/docs/grub-boot-success.service -new file mode 100644 -index 00000000000..80e79584c91 ---- /dev/null -+++ b/docs/grub-boot-success.service -@@ -0,0 +1,6 @@ -+[Unit] -+Description=Mark boot as successful -+ -+[Service] -+Type=oneshot -+ExecStart=/usr/sbin/grub2-set-bootflag boot_success -diff --git a/docs/grub-boot-success.timer b/docs/grub-boot-success.timer -new file mode 100644 -index 00000000000..406f1720056 ---- /dev/null -+++ b/docs/grub-boot-success.timer -@@ -0,0 +1,7 @@ -+[Unit] -+Description=Mark boot as successful after the user session has run 2 minutes -+ConditionUser=!@system -+ConditionVirtualization=!container -+ -+[Timer] -+OnActiveSec=2min -diff --git a/util/grub-set-bootflag.1 b/util/grub-set-bootflag.1 -new file mode 100644 -index 00000000000..57801da22a0 ---- /dev/null -+++ b/util/grub-set-bootflag.1 -@@ -0,0 +1,20 @@ -+.TH GRUB-SET-BOOTFLAG 1 "Tue Jun 12 2018" -+.SH NAME -+\fBgrub-set-bootflag\fR \(em Set a bootflag in the GRUB environment block. -+ -+.SH SYNOPSIS -+\fBgrub-set-bootflag\fR <\fIBOOTFLAG\fR> -+ -+.SH DESCRIPTION -+\fBgrub-set-bootflag\fR is a command line to set bootflags in GRUB's -+stored environment. -+ -+.SH COMMANDS -+.TP -+\fBBOOTFLAG\fR -+.RS 7 -+Bootflag to set, one of \fIboot_success\fR or \fIshow_menu_once\fR. -+.RE -+ -+.SH SEE ALSO -+.BR "info grub" diff --git a/0087-docs-Add-grub-boot-indeterminate.service-example.patch b/0087-docs-Add-grub-boot-indeterminate.service-example.patch deleted file mode 100644 index 44f6ad3..0000000 --- a/0087-docs-Add-grub-boot-indeterminate.service-example.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 19 Jun 2018 15:20:54 +0200 -Subject: [PATCH] docs: Add grub-boot-indeterminate.service example - -This is an example service file, for use from -/lib/systemd/system/system-update.target.wants -to increment the boot_indeterminate variable when -doing offline updates. - -Signed-off-by: Hans de Goede ---- - docs/grub-boot-indeterminate.service | 11 +++++++++++ - 1 file changed, 11 insertions(+) - create mode 100644 docs/grub-boot-indeterminate.service - -diff --git a/docs/grub-boot-indeterminate.service b/docs/grub-boot-indeterminate.service -new file mode 100644 -index 00000000000..6c8dcb186b6 ---- /dev/null -+++ b/docs/grub-boot-indeterminate.service -@@ -0,0 +1,11 @@ -+[Unit] -+Description=Mark boot as indeterminate -+DefaultDependencies=false -+Requires=sysinit.target -+After=sysinit.target -+Wants=system-update-pre.target -+Before=system-update-pre.target -+ -+[Service] -+Type=oneshot -+ExecStart=/usr/bin/grub2-editenv - incr boot_indeterminate diff --git a/0088-gentpl-add-disable-support.patch b/0088-gentpl-add-disable-support.patch deleted file mode 100644 index 2c3c998..0000000 --- a/0088-gentpl-add-disable-support.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 11 Jul 2018 13:43:15 -0400 -Subject: [PATCH] gentpl: add 'disable = ' support - -Signed-off-by: Peter Jones ---- - gentpl.py | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/gentpl.py b/gentpl.py -index 2cba0bbbd6f..628e8bec1d7 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -592,11 +592,21 @@ def platform_conditional(platform, closure): - # }; - # - def foreach_enabled_platform(defn, closure): -+ enabled = False -+ disabled = False - if 'enable' in defn: -+ enabled = True - for platform in GRUB_PLATFORMS: - if platform_tagged(defn, platform, "enable"): - platform_conditional(platform, closure) -- else: -+ -+ if 'disable' in defn: -+ disabled = True -+ for platform in GRUB_PLATFORMS: -+ if not platform_tagged(defn, platform, "disable"): -+ platform_conditional(platform, closure) -+ -+ if not enabled and not disabled: - for platform in GRUB_PLATFORMS: - platform_conditional(platform, closure) - -@@ -655,6 +665,8 @@ def first_time(defn, snippet): - def is_platform_independent(defn): - if 'enable' in defn: - return False -+ if 'disable' in defn: -+ return False - for suffix in [ "", "_nodist" ]: - template = platform_values(defn, GRUB_PLATFORMS[0], suffix) - for platform in GRUB_PLATFORMS[1:]: diff --git a/0089-gentpl-add-pc-firmware-type.patch b/0089-gentpl-add-pc-firmware-type.patch deleted file mode 100644 index 96dd2b8..0000000 --- a/0089-gentpl-add-pc-firmware-type.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 11:04:24 +0200 -Subject: [PATCH] gentpl: add 'pc' firmware type - -Signed-off-by: Peter Jones ---- - gentpl.py | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gentpl.py b/gentpl.py -index 628e8bec1d7..34a4eba2b42 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -51,6 +51,7 @@ GROUPS["riscv32"] = [ "riscv32_efi" ] - GROUPS["riscv64"] = [ "riscv64_efi" ] - - # Groups based on firmware -+GROUPS["pc"] = [ "i386_pc" ] - GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", - "riscv32_efi", "riscv64_efi" ] - GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] diff --git a/0090-efinet-also-use-the-firmware-acceleration-for-http.patch b/0090-efinet-also-use-the-firmware-acceleration-for-http.patch deleted file mode 100644 index 915b5aa..0000000 --- a/0090-efinet-also-use-the-firmware-acceleration-for-http.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 30 Jul 2018 14:06:42 -0400 -Subject: [PATCH] efinet: also use the firmware acceleration for http - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/net.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 4bb308026ce..6603cd83edc 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -1324,7 +1324,9 @@ grub_efi_net_boot_from_https (void) - && (subtype == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) - { - grub_efi_uri_device_path_t *uri_dp = (grub_efi_uri_device_path_t *) dp; -- return (grub_strncmp ((const char*)uri_dp->uri, "https://", sizeof ("https://") - 1) == 0) ? 1 : 0; -+ grub_dprintf ("efinet", "url:%s\n", (const char *)uri_dp->uri); -+ return (grub_strncmp ((const char *)uri_dp->uri, "https://", sizeof ("https://") - 1) == 0 || -+ grub_strncmp ((const char *)uri_dp->uri, "http://", sizeof ("http://") - 1) == 0); - } - - if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) diff --git a/0091-efi-http-Make-root_url-reflect-the-protocol-hostname.patch b/0091-efi-http-Make-root_url-reflect-the-protocol-hostname.patch deleted file mode 100644 index 985a037..0000000 --- a/0091-efi-http-Make-root_url-reflect-the-protocol-hostname.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 30 Jul 2018 16:39:57 -0400 -Subject: [PATCH] efi/http: Make root_url reflect the protocol+hostname of our - boot url. - -This lets you write config files that don't know urls. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/http.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index 3f61fd2fa5b..243acbaa35b 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - - static void - http_configure (struct grub_efi_net_device *dev, int prefer_ip6) -@@ -351,6 +352,24 @@ grub_efihttp_open (struct grub_efi_net_device *dev, - grub_err_t err; - grub_off_t size; - char *buf; -+ char *root_url; -+ grub_efi_ipv6_address_t address; -+ const char *rest; -+ -+ if (grub_efi_string_to_ip6_address (file->device->net->server, &address, &rest) && *rest == 0) -+ root_url = grub_xasprintf ("%s://[%s]", type ? "https" : "http", file->device->net->server); -+ else -+ root_url = grub_xasprintf ("%s://%s", type ? "https" : "http", file->device->net->server); -+ if (root_url) -+ { -+ grub_env_unset ("root_url"); -+ grub_env_set ("root_url", root_url); -+ grub_free (root_url); -+ } -+ else -+ { -+ return grub_errno; -+ } - - err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 1, 0); - if (err != GRUB_ERR_NONE) diff --git a/0092-Make-it-so-we-can-tell-configure-which-cflags-utils-.patch b/0092-Make-it-so-we-can-tell-configure-which-cflags-utils-.patch deleted file mode 100644 index ee2216e..0000000 --- a/0092-Make-it-so-we-can-tell-configure-which-cflags-utils-.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 26 Jun 2018 17:16:06 -0400 -Subject: [PATCH] Make it so we can tell configure which cflags utils are built - with - -This lets us have kernel.img be built with TARGET_CFLAGS but grub-mkimage and -friends built with HOST_CFLAGS. That in turn lets us build with an ARM compiler -that only has hard-float ABI versions of crt*.o and libgcc*, but still use soft -float for grub.efi. - -Signed-off-by: Peter Jones ---- - configure.ac | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- - conf/Makefile.common | 23 ++++++++++++----------- - gentpl.py | 8 ++++---- - 3 files changed, 64 insertions(+), 16 deletions(-) - -diff --git a/configure.ac b/configure.ac -index b50fb2e9897..b27573b3de5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -877,11 +877,23 @@ if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$p - TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow" - fi - -+# Should grub utils get the host CFLAGS, or the target CFLAGS? -+AC_ARG_WITH([utils], -+ AS_HELP_STRING([--with-utils=host|target|build], -+ [choose which flags to build utilities with. (default=target)]), -+ [have_with_utils=y], -+ [have_with_utils=n]) -+if test x"$have_with_utils" = xy ; then -+ with_utils="$withval" -+else -+ with_utils=target -+fi -+ - # GRUB doesn't use float or doubles at all. Yet some toolchains may decide - # that floats are a good fit to run instead of what's written in the code. - # Given that floating point unit is disabled (if present to begin with) - # when GRUB is running which may result in various hard crashes. --if test x"$platform" != xemu ; then -+if test x"$platform" != xemu -a x"$with_utils" == xtarget ; then - AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [ - grub_cv_target_cc_soft_float=no - if test "x$target_cpu" = xarm64; then -@@ -2011,6 +2023,41 @@ HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include" - -+case "$with_utils" in -+ host) -+ UTILS_CFLAGS=$HOST_CFLAGS -+ UTILS_CPPFLAGS=$HOST_CPPFLAGS -+ UTILS_CCASFLAGS=$HOST_CCASFLAGS -+ UTILS_LDFLAGS=$HOST_LDFLAGS -+ ;; -+ target) -+ UTILS_CFLAGS=$TARGET_CFLAGS -+ UTILS_CPPFLAGS=$TARGET_CPPFLAGS -+ UTILS_CCASFLAGS=$TARGET_CCASFLAGS -+ UTILS_LDFLAGS=$TARGET_LDFLAGS -+ ;; -+ build) -+ UTILS_CFLAGS=$BUILD_CFLAGS -+ UTILS_CPPFLAGS=$BUILD_CPPFLAGS -+ UTILS_CCASFLAGS=$BUILD_CCASFLAGS -+ UTILS_LDFLAGS=$BUILD_LDFLAGS -+ ;; -+ *) -+ AC_MSG_ERROR([--with-utils must be either host, target, or build]) -+ ;; -+esac -+AC_MSG_NOTICE([Using $with_utils flags for utilities.]) -+ -+unset CFLAGS -+unset CPPFLAGS -+unset CCASFLAGS -+unset LDFLAGS -+ -+AC_SUBST(UTILS_CFLAGS) -+AC_SUBST(UTILS_CPPFLAGS) -+AC_SUBST(UTILS_CCASFLAGS) -+AC_SUBST(UTILS_LDFLAGS) -+ - GRUB_TARGET_CPU="${target_cpu}" - GRUB_PLATFORM="${platform}" - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 5f0ef969857..2ff9b39357c 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -40,24 +40,25 @@ CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 - CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) - STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -R .note.gnu.property -R .gnu.build.attributes - --CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding --LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d --CPPFLAGS_MODULE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) --CCASFLAGS_MODULE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) -+CFLAGS_MODULE = $(TARGET_CFLAGS) $(CFLAGS_PLATFORM) -ffreestanding -+LDFLAGS_MODULE = $(TARGET_LDFLAGS) $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d -+CPPFLAGS_MODULE = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT) $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -+CCASFLAGS_MODULE = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT) $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) - - CFLAGS_IMAGE = $(CFLAGS_PLATFORM) -fno-builtin - LDFLAGS_IMAGE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-S - CPPFLAGS_IMAGE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) - CCASFLAGS_IMAGE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) - --CFLAGS_PROGRAM = --LDFLAGS_PROGRAM = --CPPFLAGS_PROGRAM = --CCASFLAGS_PROGRAM = -+CFLAGS_PROGRAM = $(UTILS_CFLAGS) -+LDFLAGS_PROGRAM = $(UTILS_LDFLAGS) -+CPPFLAGS_PROGRAM = $(UTILS_CPPFLAGS) -+CCASFLAGS_PROGRAM = $(UTILS_CCASFLAGS) - --CFLAGS_LIBRARY = --CPPFLAGS_LIBRARY = --CCASFLAGS_LIBRARY = -+CFLAGS_LIBRARY = $(UTILS_CFLAGS) -+LDFLAGS_LIBRARY = $(UTILS_LDFLAGS) -+CPPFLAGS_LIBRARY = $(UTILS_CPPFLAGS) -+CCASFLAGS_LIBRARY = $(UTILS_CCASFLAGS) - - # Other variables - -diff --git a/gentpl.py b/gentpl.py -index 34a4eba2b42..59f62ef9522 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -697,10 +697,10 @@ def module(defn, platform): - var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources") - var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") - var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) -- var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform)) -- var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) -- var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) -- var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) -+ var_set(cname(defn) + "_CFLAGS", "$(CFLAGS_MODULE) " + platform_cflags(defn, platform)) -+ var_set(cname(defn) + "_LDFLAGS", "$(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) -+ var_set(cname(defn) + "_CPPFLAGS", "$(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) -+ var_set(cname(defn) + "_CCASFLAGS", "$(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) - var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform)) - - gvar_add("dist_noinst_DATA", extra_dist(defn)) diff --git a/0093-module-verifier-make-it-possible-to-run-checkers-on-.patch b/0093-module-verifier-make-it-possible-to-run-checkers-on-.patch deleted file mode 100644 index e31b38f..0000000 --- a/0093-module-verifier-make-it-possible-to-run-checkers-on-.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 1 Aug 2018 10:24:52 -0400 -Subject: [PATCH] module-verifier: make it possible to run checkers on - grub-module-verifierxx.c - -This makes it so you can treat grub-module-verifierxx.c as a file you can -build directly, so syntax checkers like vim's "syntastic" plugin, which uses -"gcc -x c -fsyntax-only" to build it, will work. - -One still has to do whatever setup is required to make it pick the right -include dirs, which -W options we use, etc., but this makes it so you can do -the checking on the file you're editing, rather than on a different file. - -v2: fix the typo in the #else clause in util/grub-module-verifierXX.c - -Signed-off-by: Peter Jones ---- - util/grub-module-verifier32.c | 2 ++ - util/grub-module-verifier64.c | 2 ++ - util/grub-module-verifierXX.c | 9 +++++++++ - 3 files changed, 13 insertions(+) - -diff --git a/util/grub-module-verifier32.c b/util/grub-module-verifier32.c -index 257229f8f08..ba7d41aafea 100644 ---- a/util/grub-module-verifier32.c -+++ b/util/grub-module-verifier32.c -@@ -1,2 +1,4 @@ - #define MODULEVERIFIER_ELF32 1 -+#ifndef GRUB_MODULE_VERIFIERXX - #include "grub-module-verifierXX.c" -+#endif -diff --git a/util/grub-module-verifier64.c b/util/grub-module-verifier64.c -index 4db6b4bedd1..fc23ef800b3 100644 ---- a/util/grub-module-verifier64.c -+++ b/util/grub-module-verifier64.c -@@ -1,2 +1,4 @@ - #define MODULEVERIFIER_ELF64 1 -+#ifndef GRUB_MODULE_VERIFIERXX - #include "grub-module-verifierXX.c" -+#endif -diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c -index ceb24309aec..a98e2f9b1ac 100644 ---- a/util/grub-module-verifierXX.c -+++ b/util/grub-module-verifierXX.c -@@ -1,3 +1,12 @@ -+#define GRUB_MODULE_VERIFIERXX -+#if !defined(MODULEVERIFIER_ELF32) && !defined(MODULEVERIFIER_ELF64) -+#if __SIZEOF_POINTER__ == 8 -+#include "grub-module-verifier64.c" -+#else -+#include "grub-module-verifier32.c" -+#endif -+#endif -+ - #include - - #include diff --git a/0094-Rework-how-the-fdt-command-builds.patch b/0094-Rework-how-the-fdt-command-builds.patch deleted file mode 100644 index e233067..0000000 --- a/0094-Rework-how-the-fdt-command-builds.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 13:01:41 +0200 -Subject: [PATCH] Rework how the fdt command builds. - -Trying to avoid all variants of: -cat syminfo.lst | sort | gawk -f ../../grub-core/genmoddep.awk > moddep.lst || (rm -f moddep.lst; exit 1) -grub_fdt_install in linux is not defined -grub_fdt_load in linux is not defined -grub_fdt_unload in linux is not defined -grub_fdt_install in xen_boot is not defined -grub_fdt_load in xen_boot is not defined -grub_fdt_unload in xen_boot is not defined - -Signed-off-by: Peter Jones -[javierm: Fix build with platform emu, aarch64, and risc-v] -Signed-off-by: Javier Martinez Canillas -Signed-off-by: Robbie Harwood ---- - grub-core/Makefile.core.def | 5 ++--- - grub-core/lib/fdt.c | 2 -- - grub-core/loader/efi/fdt.c | 2 ++ - include/grub/fdt.h | 6 ++++++ - grub-core/Makefile.am | 1 + - 5 files changed, 11 insertions(+), 5 deletions(-) - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index c40170f2dd2..84a3d89de9a 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -177,7 +177,6 @@ kernel = { - arm_coreboot = kern/arm/coreboot/init.c; - arm_coreboot = kern/arm/coreboot/timer.c; - arm_coreboot = kern/arm/coreboot/coreboot.S; -- arm_coreboot = lib/fdt.c; - arm_coreboot = bus/fdt.c; - arm_coreboot = term/ps2.c; - arm_coreboot = term/arm/pl050.c; -@@ -351,6 +350,8 @@ kernel = { - riscv64 = kern/riscv/cache_flush.S; - riscv64 = kern/riscv/dl.c; - -+ fdt = lib/fdt.c; -+ - emu = disk/host.c; - emu = kern/emu/cache_s.S; - emu = kern/emu/hostdisk.c; -@@ -1825,7 +1826,6 @@ module = { - riscv32 = loader/riscv/linux.c; - riscv64 = loader/riscv/linux.c; - emu = loader/emu/linux.c; -- fdt = lib/fdt.c; - - common = loader/linux.c; - common = lib/cmdline.c; -@@ -1836,7 +1836,6 @@ module = { - module = { - name = fdt; - efi = loader/efi/fdt.c; -- common = lib/fdt.c; - enable = fdt; - }; - -diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c -index 0d371c5633e..37e04bd69e7 100644 ---- a/grub-core/lib/fdt.c -+++ b/grub-core/lib/fdt.c -@@ -21,8 +21,6 @@ - #include - #include - --GRUB_MOD_LICENSE ("GPLv3+"); -- - #define FDT_SUPPORTED_VERSION 17 - - #define FDT_BEGIN_NODE 0x00000001 -diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c -index c86f283d756..c572415d38a 100644 ---- a/grub-core/loader/efi/fdt.c -+++ b/grub-core/loader/efi/fdt.c -@@ -27,6 +27,8 @@ - #include - #include - -+GRUB_MOD_LICENSE ("GPLv3+"); -+ - static void *loaded_fdt; - static void *fdt; - -diff --git a/include/grub/fdt.h b/include/grub/fdt.h -index e609c7e4111..3514aa4a5b6 100644 ---- a/include/grub/fdt.h -+++ b/include/grub/fdt.h -@@ -19,6 +19,9 @@ - #ifndef GRUB_FDT_HEADER - #define GRUB_FDT_HEADER 1 - -+#if !defined(GRUB_MACHINE_EMU) && \ -+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) -+ - #include - #include - -@@ -144,4 +147,7 @@ int EXPORT_FUNC(grub_fdt_set_prop) (void *fdt, unsigned int nodeoffset, const ch - grub_fdt_set_prop ((fdt), (nodeoffset), "reg", reg_64, 16); \ - }) - -+#endif /* !defined(GRUB_MACHINE_EMU) && \ -+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) */ -+ - #endif /* ! GRUB_FDT_HEADER */ -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index f512573c0da..dd49939aaa9 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -76,6 +76,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/sb.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h diff --git a/0095-Disable-non-wordsize-allocations-on-arm.patch b/0095-Disable-non-wordsize-allocations-on-arm.patch deleted file mode 100644 index e28041a..0000000 --- a/0095-Disable-non-wordsize-allocations-on-arm.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 2 Aug 2018 10:56:38 -0400 -Subject: [PATCH] Disable non-wordsize allocations on arm - -Signed-off-by: Peter Jones ---- - configure.ac | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/configure.ac b/configure.ac -index b27573b3de5..bb4e05ceef3 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1288,6 +1288,26 @@ if test "x$target_cpu" = xarm; then - done - ]) - -+ AC_CACHE_CHECK([for options to disable movt and movw relocations], -+ grub_cv_target_cc_mword_relocations, -+ [grub_cv_target_cc_mword_relocations=no -+ for cand in "-mword-relocations" ; do -+ if test x"$grub_cv_target_cc_mword_relocations" != xno ; then -+ break -+ fi -+ CFLAGS="$TARGET_CFLAGS $cand -Werror" -+ CPPFLAGS="$TARGET_CPPFLAGS" -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], -+ [grub_cv_target_cc_mword_relocations="$cand"], -+ []) -+ done -+ ]) -+ if test x"$grub_cv_target_cc_mword_relocations" = xno ; then -+ AC_MSG_ERROR(["your compiler doesn't support disabling movw/movt relocations"]) -+ else -+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mword_relocations" -+ fi -+ - if test x"$grub_cv_target_cc_mno_movt" != xno ; then - # A trick so that clang doesn't see it on link stage - TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt" diff --git a/0096-Prepend-prefix-when-HTTP-path-is-relative.patch b/0096-Prepend-prefix-when-HTTP-path-is-relative.patch deleted file mode 100644 index d3e599d..0000000 --- a/0096-Prepend-prefix-when-HTTP-path-is-relative.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Stephen Benjamin -Date: Thu, 16 Aug 2018 16:58:51 -0400 -Subject: [PATCH] Prepend prefix when HTTP path is relative - -This sets a couple of variables. With the url http://www.example.com/foo/bar : -http_path: /foo/bar -http_url: http://www.example.com/foo/bar - -Signed-off-by: Peter Jones -Signed-off-by: Stephen Benjamin -Signed-off-by: Robbie Harwood ---- - grub-core/kern/main.c | 10 +++++- - grub-core/net/efi/http.c | 82 ++++++++++++++++++++++++++++++++++++------------ - 2 files changed, 71 insertions(+), 21 deletions(-) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index d1de9fa6873..1c540fc8c26 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -131,11 +131,19 @@ grub_set_prefix_and_root (void) - if (fwdevice && fwpath) - { - char *fw_path; -+ char separator[3] = ")"; - -- fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath); -+ grub_dprintf ("fw_path", "\n"); -+ grub_dprintf ("fw_path", "fwdevice:\"%s\" fwpath:\"%s\"\n", fwdevice, fwpath); -+ -+ if (!grub_strncmp(fwdevice, "http", 4) && fwpath[0] != '/') -+ grub_strcpy(separator, ")/"); -+ -+ fw_path = grub_xasprintf ("(%s%s%s", fwdevice, separator, fwpath); - if (fw_path) - { - grub_env_set ("fw_path", fw_path); -+ grub_dprintf ("fw_path", "fw_path:\"%s\"\n", fw_path); - grub_free (fw_path); - } - } -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index 243acbaa35b..de351b2cd03 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -9,10 +9,52 @@ - static void - http_configure (struct grub_efi_net_device *dev, int prefer_ip6) - { -+ grub_efi_ipv6_address_t address; - grub_efi_http_config_data_t http_config; - grub_efi_httpv4_access_point_t httpv4_node; - grub_efi_httpv6_access_point_t httpv6_node; - grub_efi_status_t status; -+ int https; -+ char *http_url; -+ const char *rest, *http_server, *http_path = NULL; -+ -+ http_server = grub_env_get ("root"); -+ https = (grub_strncmp (http_server, "https", 5) == 0) ? 1 : 0; -+ -+ /* extract http server + port */ -+ if (http_server) -+ { -+ http_server = grub_strchr (http_server, ','); -+ if (http_server) -+ http_server++; -+ } -+ -+ /* fw_path is like (http,192.168.1.1:8000)/httpboot, extract path part */ -+ http_path = grub_env_get ("fw_path"); -+ if (http_path) -+ { -+ http_path = grub_strchr (http_path, ')'); -+ if (http_path) -+ { -+ http_path++; -+ grub_env_unset ("http_path"); -+ grub_env_set ("http_path", http_path); -+ } -+ } -+ -+ if (http_server && http_path) -+ { -+ if (grub_efi_string_to_ip6_address (http_server, &address, &rest) && *rest == 0) -+ http_url = grub_xasprintf ("%s://[%s]%s", https ? "https" : "http", http_server, http_path); -+ else -+ http_url = grub_xasprintf ("%s://%s%s", https ? "https" : "http", http_server, http_path); -+ if (http_url) -+ { -+ grub_env_unset ("http_url"); -+ grub_env_set ("http_url", http_url); -+ grub_free (http_url); -+ } -+ } - - grub_efi_http_t *http = dev->http; - -@@ -352,32 +394,32 @@ grub_efihttp_open (struct grub_efi_net_device *dev, - grub_err_t err; - grub_off_t size; - char *buf; -- char *root_url; -- grub_efi_ipv6_address_t address; -- const char *rest; -+ char *file_name = NULL; -+ const char *http_path; - -- if (grub_efi_string_to_ip6_address (file->device->net->server, &address, &rest) && *rest == 0) -- root_url = grub_xasprintf ("%s://[%s]", type ? "https" : "http", file->device->net->server); -- else -- root_url = grub_xasprintf ("%s://%s", type ? "https" : "http", file->device->net->server); -- if (root_url) -- { -- grub_env_unset ("root_url"); -- grub_env_set ("root_url", root_url); -- grub_free (root_url); -- } -- else -- { -+ /* If path is relative, prepend http_path */ -+ http_path = grub_env_get ("http_path"); -+ if (http_path && file->device->net->name[0] != '/') { -+ file_name = grub_xasprintf ("%s/%s", http_path, file->device->net->name); -+ if (!file_name) - return grub_errno; -- } -+ } - -- err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 1, 0); -+ err = efihttp_request (dev->http, file->device->net->server, -+ file_name ? file_name : file->device->net->name, type, 1, 0); - if (err != GRUB_ERR_NONE) -- return err; -+ { -+ grub_free (file_name); -+ return err; -+ } - -- err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 0, &size); -+ err = efihttp_request (dev->http, file->device->net->server, -+ file_name ? file_name : file->device->net->name, type, 0, &size); -+ grub_free (file_name); - if (err != GRUB_ERR_NONE) -- return err; -+ { -+ return err; -+ } - - buf = grub_malloc (size); - efihttp_read (dev, buf, size); diff --git a/0097-Make-grub_error-more-verbose.patch b/0097-Make-grub_error-more-verbose.patch deleted file mode 100644 index 2492e9f..0000000 --- a/0097-Make-grub_error-more-verbose.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 27 Aug 2018 13:14:06 -0400 -Subject: [PATCH] Make grub_error() more verbose - -Signed-off-by: Peter Jones ---- - grub-core/kern/err.c | 13 +++++++++++-- - include/grub/err.h | 8 ++++++-- - 2 files changed, 17 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c -index 53c734de70e..aebfe0cf839 100644 ---- a/grub-core/kern/err.c -+++ b/grub-core/kern/err.c -@@ -33,15 +33,24 @@ static struct grub_error_saved grub_error_stack_items[GRUB_ERROR_STACK_SIZE]; - static int grub_error_stack_pos; - static int grub_error_stack_assert; - -+#ifdef grub_error -+#undef grub_error -+#endif -+ - grub_err_t --grub_error (grub_err_t n, const char *fmt, ...) -+grub_error (grub_err_t n, const char *file, const int line, const char *fmt, ...) - { - va_list ap; -+ int m; - - grub_errno = n; - -+ m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%d:", file, line); -+ if (m < 0) -+ m = 0; -+ - va_start (ap, fmt); -- grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap); -+ grub_vsnprintf (grub_errmsg + m, sizeof (grub_errmsg) - m, _(fmt), ap); - va_end (ap); - - return n; -diff --git a/include/grub/err.h b/include/grub/err.h -index b08d5d0de4c..c0f90ef07c8 100644 ---- a/include/grub/err.h -+++ b/include/grub/err.h -@@ -85,8 +85,12 @@ struct grub_error_saved - extern grub_err_t EXPORT_VAR(grub_errno); - extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG]; - --grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...) -- __attribute__ ((format (GNU_PRINTF, 2, 3))); -+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...) -+ __attribute__ ((format (GNU_PRINTF, 4, 5))); -+ -+#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, ##__VA_ARGS__) -+ -+ - void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); - void EXPORT_FUNC(grub_error_push) (void); - int EXPORT_FUNC(grub_error_pop) (void); diff --git a/0098-Make-reset-an-alias-for-the-reboot-command.patch b/0098-Make-reset-an-alias-for-the-reboot-command.patch deleted file mode 100644 index c86acf1..0000000 --- a/0098-Make-reset-an-alias-for-the-reboot-command.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 31 Aug 2018 16:42:03 -0400 -Subject: [PATCH] Make "reset" an alias for the "reboot" command. - -I'm really tired of half the tools I get to use having one and the other half -having the other. - -Signed-off-by: Peter Jones ---- - grub-core/commands/reboot.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/grub-core/commands/reboot.c b/grub-core/commands/reboot.c -index 46d364c99a9..f5cc2283636 100644 ---- a/grub-core/commands/reboot.c -+++ b/grub-core/commands/reboot.c -@@ -32,15 +32,18 @@ grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)), - grub_reboot (); - } - --static grub_command_t cmd; -+static grub_command_t reboot_cmd, reset_cmd; - - GRUB_MOD_INIT(reboot) - { -- cmd = grub_register_command ("reboot", grub_cmd_reboot, -- 0, N_("Reboot the computer.")); -+ reboot_cmd = grub_register_command ("reboot", grub_cmd_reboot, -+ 0, N_("Reboot the computer.")); -+ reset_cmd = grub_register_command ("reset", grub_cmd_reboot, -+ 0, N_("Reboot the computer.")); - } - - GRUB_MOD_FINI(reboot) - { -- grub_unregister_command (cmd); -+ grub_unregister_command (reboot_cmd); -+ grub_unregister_command (reset_cmd); - } diff --git a/0099-Add-a-version-command.patch b/0099-Add-a-version-command.patch deleted file mode 100644 index bf3b4b8..0000000 --- a/0099-Add-a-version-command.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 11 Sep 2018 14:20:37 -0400 -Subject: [PATCH] Add a "version" command. - -This adds a command that shows you info about grub's version, the grub target -platform, the compiler version, and if you built with ---with-rpm-version=, the rpm package version. - -Signed-off-by: Peter Jones ---- - configure.ac | 13 ++++++++++ - grub-core/Makefile.core.def | 5 ++++ - grub-core/commands/version.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ - config.h.in | 1 + - 4 files changed, 75 insertions(+) - create mode 100644 grub-core/commands/version.c - -diff --git a/configure.ac b/configure.ac -index bb4e05ceef3..59ccda24475 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -312,6 +312,19 @@ AC_SUBST(target_cpu) - AC_SUBST(platform) - - # Define default variables -+have_with_rpm_version=n -+AC_ARG_WITH([rpm_version], -+ AS_HELP_STRING([--with-rpm-version=VERSION], -+ [set the rpm package version [[guessed]]]), -+ [have_with_rpm_version=y], -+ [have_with_rpm_version=n]) -+if test x$have_with_rpm_version = xy; then -+ rpm_version="$with_rpm_version" -+else -+ rpm_version="" -+fi -+GRUB_RPM_VERSION="$rpm_version" -+AC_SUBST(GRUB_RPM_VERSION) - - have_with_bootdir=n - AC_ARG_WITH([bootdir], -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 84a3d89de9a..498ca11762a 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -579,6 +579,11 @@ image = { - enable = mips_loongson; - }; - -+module = { -+ name = version; -+ common = commands/version.c; -+}; -+ - module = { - name = disk; - common = lib/disk.c; -diff --git a/grub-core/commands/version.c b/grub-core/commands/version.c -new file mode 100644 -index 00000000000..f0966a518f7 ---- /dev/null -+++ b/grub-core/commands/version.c -@@ -0,0 +1,56 @@ -+/* version.c - Command to print the grub version and build info. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_err_t -+grub_cmd_version (grub_command_t cmd UNUSED, int argc, char **args UNUSED) -+{ -+ if (argc != 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("no arguments expected")); -+ -+ grub_printf (_("GNU GRUB version %s\n"), PACKAGE_VERSION); -+ grub_printf (_("Platform %s-%s\n"), GRUB_TARGET_CPU, GRUB_PLATFORM); -+ if (grub_strlen(GRUB_RPM_VERSION) != 0) -+ grub_printf (_("RPM package version %s\n"), GRUB_RPM_VERSION); -+ grub_printf (_("Compiler version %s\n"), __VERSION__); -+ -+ return 0; -+} -+ -+static grub_command_t cmd; -+ -+GRUB_MOD_INIT(version) -+{ -+ cmd = grub_register_command ("version", grub_cmd_version, NULL, -+ N_("Print version and build information.")); -+} -+ -+GRUB_MOD_FINI(version) -+{ -+ grub_unregister_command (cmd); -+} -diff --git a/config.h.in b/config.h.in -index 9e8f9911b18..c7e316f0f1f 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -59,6 +59,7 @@ - - #define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" - #define GRUB_PLATFORM "@GRUB_PLATFORM@" -+#define GRUB_RPM_VERSION "@GRUB_RPM_VERSION@" - - #define RE_ENABLE_I18N 1 - diff --git a/0100-Add-more-dprintf-and-nerf-dprintf-in-script.c.patch b/0100-Add-more-dprintf-and-nerf-dprintf-in-script.c.patch deleted file mode 100644 index 9afb315..0000000 --- a/0100-Add-more-dprintf-and-nerf-dprintf-in-script.c.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 11 Sep 2018 15:58:29 -0400 -Subject: [PATCH] Add more dprintf, and nerf dprintf in script.c - -Signed-off-by: Peter Jones ---- - grub-core/disk/diskfilter.c | 3 +++ - grub-core/disk/efi/efidisk.c | 1 + - grub-core/kern/device.c | 1 + - grub-core/script/script.c | 5 +++++ - 4 files changed, 10 insertions(+) - -diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c -index 0320115662f..7cdffe3ebd5 100644 ---- a/grub-core/disk/diskfilter.c -+++ b/grub-core/disk/diskfilter.c -@@ -188,6 +188,8 @@ scan_disk (const char *name, int accept_diskfilter) - grub_disk_t disk; - static int scan_depth = 0; - -+ grub_dprintf ("diskfilter", "scanning %s\n", name); -+ - if (!accept_diskfilter && is_valid_diskfilter_name (name)) - return 0; - -@@ -1212,6 +1214,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, - the same. */ - if (pv->disk && grub_disk_native_sectors (disk) >= pv->part_size) - return GRUB_ERR_NONE; -+ grub_dprintf ("diskfilter", "checking %s\n", disk->name); - pv->disk = grub_disk_open (disk->name); - if (!pv->disk) - return grub_errno; -diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c -index f077b5f5535..fe8ba6e6c93 100644 ---- a/grub-core/disk/efi/efidisk.c -+++ b/grub-core/disk/efi/efidisk.c -@@ -855,6 +855,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) - return 0; - } - -+ grub_dprintf ("efidisk", "getting disk for %s\n", device_name); - parent = grub_disk_open (device_name); - grub_free (dup_dp); - -diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c -index 73b8ecc0c09..f58b58c89d5 100644 ---- a/grub-core/kern/device.c -+++ b/grub-core/kern/device.c -@@ -34,6 +34,7 @@ grub_device_open (const char *name) - { - grub_device_t dev = 0; - -+ grub_dprintf ("device", "opening device %s\n", name); - if (! name) - { - name = grub_env_get ("root"); -diff --git a/grub-core/script/script.c b/grub-core/script/script.c -index ec4d4337c66..844e8343ca7 100644 ---- a/grub-core/script/script.c -+++ b/grub-core/script/script.c -@@ -22,6 +22,11 @@ - #include - #include - -+#ifdef grub_dprintf -+#undef grub_dprintf -+#endif -+#define grub_dprintf(no, fmt, ...) -+ - /* It is not possible to deallocate the memory when a syntax error was - found. Because of that it is required to keep track of all memory - allocations. The memory is freed in case of an error, or assigned diff --git a/0101-arm-arm64-loader-Better-memory-allocation-and-error-.patch b/0101-arm-arm64-loader-Better-memory-allocation-and-error-.patch deleted file mode 100644 index 1fdc552..0000000 --- a/0101-arm-arm64-loader-Better-memory-allocation-and-error-.patch +++ /dev/null @@ -1,279 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 14:38:57 +0200 -Subject: [PATCH] arm/arm64 loader: Better memory allocation and error - messages. - -On mustang, our memory map looks like: - -Type Physical start - end #Pages Size Attributes -reserved 0000004000000000-00000040001fffff 00000200 2MiB UC WC WT WB -conv-mem 0000004000200000-0000004393ffffff 00393e00 14654MiB UC WC WT WB -ldr-code 0000004394000000-00000043f7ffffff 00064000 1600MiB UC WC WT WB -BS-data 00000043f8000000-00000043f801ffff 00000020 128KiB UC WC WT WB -conv-mem 00000043f8020000-00000043fa15bfff 0000213c 34032KiB UC WC WT WB -ldr-code 00000043fa15c000-00000043fa2a1fff 00000146 1304KiB UC WC WT WB -ldr-data 00000043fa2a2000-00000043fa3e8fff 00000147 1308KiB UC WC WT WB -conv-mem 00000043fa3e9000-00000043fa3e9fff 00000001 4KiB UC WC WT WB -ldr-data 00000043fa3ea000-00000043fa3eafff 00000001 4KiB UC WC WT WB -ldr-code 00000043fa3eb000-00000043fa4affff 000000c5 788KiB UC WC WT WB -BS-code 00000043fa4b0000-00000043fa59ffff 000000f0 960KiB UC WC WT WB -RT-code 00000043fa5a0000-00000043fa5affff 00000010 64KiB RT UC WC WT WB -RT-data 00000043fa5b0000-00000043fa5bffff 00000010 64KiB RT UC WC WT WB -RT-code 00000043fa5c0000-00000043fa5cffff 00000010 64KiB RT UC WC WT WB -ldr-data 00000043fa5d0000-00000043fa5d0fff 00000001 4KiB UC WC WT WB -BS-code 00000043fa5d1000-00000043fa5ddfff 0000000d 52KiB UC WC WT WB -reserved 00000043fa5de000-00000043fa60ffff 00000032 200KiB UC WC WT WB -ACPI-rec 00000043fa610000-00000043fa6affff 000000a0 640KiB UC WC WT WB -ACPI-nvs 00000043fa6b0000-00000043fa6bffff 00000010 64KiB UC WC WT WB -ACPI-rec 00000043fa6c0000-00000043fa70ffff 00000050 320KiB UC WC WT WB -RT-code 00000043fa710000-00000043fa72ffff 00000020 128KiB RT UC WC WT WB -RT-data 00000043fa730000-00000043fa78ffff 00000060 384KiB RT UC WC WT WB -RT-code 00000043fa790000-00000043fa79ffff 00000010 64KiB RT UC WC WT WB -RT-data 00000043fa7a0000-00000043fa99ffff 00000200 2MiB RT UC WC WT WB -RT-code 00000043fa9a0000-00000043fa9affff 00000010 64KiB RT UC WC WT WB -RT-data 00000043fa9b0000-00000043fa9cffff 00000020 128KiB RT UC WC WT WB -BS-code 00000043fa9d0000-00000043fa9d9fff 0000000a 40KiB UC WC WT WB -reserved 00000043fa9da000-00000043fa9dbfff 00000002 8KiB UC WC WT WB -conv-mem 00000043fa9dc000-00000043fc29dfff 000018c2 25352KiB UC WC WT WB -BS-data 00000043fc29e000-00000043fc78afff 000004ed 5044KiB UC WC WT WB -conv-mem 00000043fc78b000-00000043fca01fff 00000277 2524KiB UC WC WT WB -BS-data 00000043fca02000-00000043fcea3fff 000004a2 4744KiB UC WC WT WB -conv-mem 00000043fcea4000-00000043fcea4fff 00000001 4KiB UC WC WT WB -BS-data 00000043fcea5000-00000043fd192fff 000002ee 3000KiB UC WC WT WB -conv-mem 00000043fd193000-00000043fd2b0fff 0000011e 1144KiB UC WC WT WB -BS-data 00000043fd2b1000-00000043ff80ffff 0000255f 38268KiB UC WC WT WB -BS-code 00000043ff810000-00000043ff99ffff 00000190 1600KiB UC WC WT WB -RT-code 00000043ff9a0000-00000043ff9affff 00000010 64KiB RT UC WC WT WB -conv-mem 00000043ff9b0000-00000043ff9bffff 00000010 64KiB UC WC WT WB -RT-data 00000043ff9c0000-00000043ff9effff 00000030 192KiB RT UC WC WT WB -conv-mem 00000043ff9f0000-00000043ffa05fff 00000016 88KiB UC WC WT WB -BS-data 00000043ffa06000-00000043ffffffff 000005fa 6120KiB UC WC WT WB -MMIO 0000000010510000-0000000010510fff 00000001 4KiB RT -MMIO 0000000010548000-0000000010549fff 00000002 8KiB RT -MMIO 0000000017000000-0000000017001fff 00000002 8KiB RT -MMIO 000000001c025000-000000001c025fff 00000001 4KiB RT - -This patch adds a requirement when we're trying to find the base of ram, that -the memory we choose is actually /allocatable/ conventional memory, not merely -write-combining. On this machine that means we wind up with an allocation -around 0x4392XXXXXX, which is a reasonable address. - -This also changes grub_efi_allocate_pages_real() so that if 0 is allocated, it -tries to allocate again starting with the same max address it did the first -time, rather than interposing GRUB_EFI_MAX_USABLE_ADDRESS there, so that any -per-platform constraints on its given address are maintained. - -Signed-off-by: Peter Jones ---- - grub-core/kern/efi/mm.c | 33 +++++++++++++++----- - grub-core/loader/arm64/linux.c | 68 +++++++++++++++++++++++++++++++----------- - 2 files changed, 76 insertions(+), 25 deletions(-) - -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index f6aef0ef649..85ad4b4494c 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -154,6 +154,7 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, - { - grub_efi_status_t status; - grub_efi_boot_services_t *b; -+ grub_efi_physical_address_t ret = address; - - /* Limit the memory access to less than 4GB for 32-bit platforms. */ - if (address > GRUB_EFI_MAX_USABLE_ADDRESS) -@@ -170,19 +171,22 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, - } - - b = grub_efi_system_table->boot_services; -- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); -+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret); - if (status != GRUB_EFI_SUCCESS) - { -+ grub_dprintf ("efi", -+ "allocate_pages(%d, %d, 0x%0lx, 0x%016lx) = 0x%016lx\n", -+ alloctype, memtype, pages, address, status); - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - return NULL; - } - -- if (address == 0) -+ if (ret == 0) - { - /* Uggh, the address 0 was allocated... This is too annoying, - so reallocate another one. */ -- address = GRUB_EFI_MAX_USABLE_ADDRESS; -- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); -+ ret = address; -+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret); - grub_efi_free_pages (0, pages); - if (status != GRUB_EFI_SUCCESS) - { -@@ -191,9 +195,9 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, - } - } - -- grub_efi_store_alloc (address, pages); -+ grub_efi_store_alloc (ret, pages); - -- return (void *) ((grub_addr_t) address); -+ return (void *) ((grub_addr_t) ret); - } - - void * -@@ -713,8 +717,21 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) - for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; - (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); - desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) -- if (desc->attribute & GRUB_EFI_MEMORY_WB) -- *base_addr = grub_min (*base_addr, desc->physical_start); -+ { -+ if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY && -+ (desc->attribute & GRUB_EFI_MEMORY_WB)) -+ { -+ *base_addr = grub_min (*base_addr, desc->physical_start); -+ grub_dprintf ("efi", "setting base_addr=0x%016lx\n", *base_addr); -+ } -+ else -+ { -+ grub_dprintf ("efi", "ignoring address 0x%016lx\n", desc->physical_start); -+ } -+ } -+ -+ if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS) -+ grub_dprintf ("efi", "base_addr 0x%016lx is probably wrong.\n", *base_addr); - - grub_free(memory_map); - -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index 04994d5c67d..70a0075ec5e 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -71,20 +71,25 @@ finalize_params_linux (void) - { - grub_efi_loaded_image_t *loaded_image = NULL; - int node, retval, len; -- -+ grub_err_t err = GRUB_ERR_NONE; - void *fdt; - - fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE); -- - if (!fdt) -- goto failure; -+ { -+ err = grub_error(GRUB_ERR_BAD_OS, "failed to load FDT"); -+ goto failure; -+ } - - node = grub_fdt_find_subnode (fdt, 0, "chosen"); - if (node < 0) - node = grub_fdt_add_subnode (fdt, 0, "chosen"); - - if (node < 1) -- goto failure; -+ { -+ err = grub_error(grub_errno, "failed to load chosen fdt node."); -+ goto failure; -+ } - - /* Set initrd info */ - if (initrd_start && initrd_end > initrd_start) -@@ -95,15 +100,26 @@ finalize_params_linux (void) - retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", - initrd_start); - if (retval) -- goto failure; -+ { -+ err = grub_error(retval, "Failed to set linux,initrd-start property"); -+ goto failure; -+ } -+ - retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", - initrd_end); - if (retval) -- goto failure; -+ { -+ err = grub_error(retval, "Failed to set linux,initrd-end property"); -+ goto failure; -+ } - } - -- if (grub_fdt_install() != GRUB_ERR_NONE) -- goto failure; -+ retval = grub_fdt_install(); -+ if (retval != GRUB_ERR_NONE) -+ { -+ err = grub_error(retval, "Failed to install fdt"); -+ goto failure; -+ } - - grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n", - fdt); -@@ -111,14 +127,20 @@ finalize_params_linux (void) - /* Convert command line to UCS-2 */ - loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); - if (!loaded_image) -- goto failure; -+ { -+ err = grub_error(grub_errno, "Failed to install fdt"); -+ goto failure; -+ } - - loaded_image->load_options_size = len = - (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t); - loaded_image->load_options = - grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); - if (!loaded_image->load_options) -- return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters"); -+ { -+ err = grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters"); -+ goto failure; -+ } - - loaded_image->load_options_size = - 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, -@@ -128,7 +150,7 @@ finalize_params_linux (void) - - failure: - grub_fdt_unload(); -- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+ return err; - } - - static void -@@ -212,16 +234,28 @@ grub_linux_unload (void) - static void * - allocate_initrd_mem (int initrd_pages) - { -- grub_addr_t max_addr; -+ grub_addr_t max_addr = 0; -+ grub_err_t err; -+ void *ret; - -- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) -- return NULL; -+ err = grub_efi_get_ram_base (&max_addr); -+ if (err != GRUB_ERR_NONE) -+ { -+ grub_error (err, "grub_efi_get_ram_base() failed"); -+ return NULL; -+ } -+ -+ grub_dprintf ("linux", "max_addr: 0x%016lx, INITRD_MAX_ADDRESS_OFFSET: 0x%016llx\n", -+ max_addr, INITRD_MAX_ADDRESS_OFFSET); - - max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; -+ grub_dprintf ("linux", "calling grub_efi_allocate_pages_real (0x%016lx, 0x%08x, EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA)", max_addr, initrd_pages); - -- return grub_efi_allocate_pages_real (max_addr, initrd_pages, -- GRUB_EFI_ALLOCATE_MAX_ADDRESS, -- GRUB_EFI_LOADER_DATA); -+ ret = grub_efi_allocate_pages_real (max_addr, initrd_pages, -+ GRUB_EFI_ALLOCATE_MAX_ADDRESS, -+ GRUB_EFI_LOADER_DATA); -+ grub_dprintf ("linux", "got 0x%016llx\n", (unsigned long long)ret); -+ return ret; - } - - static grub_err_t diff --git a/0102-Try-to-pick-better-locations-for-kernel-and-initrd.patch b/0102-Try-to-pick-better-locations-for-kernel-and-initrd.patch deleted file mode 100644 index 06329b9..0000000 --- a/0102-Try-to-pick-better-locations-for-kernel-and-initrd.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 17:17:02 +0200 -Subject: [PATCH] Try to pick better locations for kernel and initrd - -- Don't limit allocations on 64-bit platforms to < 0x[37f]fffffff if - we're using the "large" code model ; use __UINTPTR_MAX__. -- Get the comparison right to check the address we've allocated. -- Fix the allocation for the command line as well. - -*But*, when we did this some systems started failing badly; coudln't -parse partition tables, etc. What's going on here is the disk controller -is silently failing DMAs to addresses above 4GB, so we're trying to parse -uninitialized (or HW zeroed) ram when looking for the partition table, -etc. - -So to limit this, we make grub_malloc() pick addresses below 4GB on -x86_64, but the direct EFI page allocation functions can get addresses -above that. - -Additionally, we now try to locate kernel+initrd+cmdline+etc below -0x7fffffff, and if they're too big to fit any memory window there, then -we try a higher address. - -Signed-off-by: Peter Jones -[david.abdurachmanov: fix macro for riscv64] -Signed-off-by: David Abdurachmanov -Signed-off-by: Robbie Harwood ---- - grub-core/kern/efi/mm.c | 8 ++++---- - grub-core/loader/i386/efi/linux.c | 24 +++++++++++++++++------- - include/grub/arm/efi/memory.h | 1 + - include/grub/arm64/efi/memory.h | 1 + - include/grub/i386/efi/memory.h | 1 + - include/grub/ia64/efi/memory.h | 1 + - include/grub/riscv64/efi/memory.h | 1 + - include/grub/x86_64/efi/memory.h | 4 +++- - 8 files changed, 29 insertions(+), 12 deletions(-) - -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 85ad4b4494c..e84961d078c 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -122,7 +122,7 @@ grub_efi_allocate_pages_max (grub_efi_physical_address_t max, - grub_efi_boot_services_t *b; - grub_efi_physical_address_t address = max; - -- if (max > 0xffffffff) -+ if (max > GRUB_EFI_MAX_USABLE_ADDRESS) - return 0; - - b = grub_efi_system_table->boot_services; -@@ -480,7 +480,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, - { - if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY - #if 1 -- && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS -+ && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS - #endif - && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 - && desc->num_pages != 0) -@@ -498,9 +498,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, - #if 1 - if (BYTES_TO_PAGES (filtered_desc->physical_start) - + filtered_desc->num_pages -- > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)) -+ > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)) - filtered_desc->num_pages -- = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS) -+ = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS) - - BYTES_TO_PAGES (filtered_desc->physical_start)); - #endif - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 3017d0f3e52..33e981e76e7 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -106,7 +107,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - size += ALIGN_UP (grub_file_size (files[i]), 4); - } - -- initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); -+ initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(size)); -+ if (!initrd_mem) -+ initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, BYTES_TO_PAGES(size)); - if (!initrd_mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); -@@ -202,8 +205,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- params = grub_efi_allocate_pages_max (0x3fffffff, -+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, - BYTES_TO_PAGES(sizeof(*params))); -+ if (!params) -+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, -+ BYTES_TO_PAGES(sizeof(*params))); - if (! params) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); -@@ -273,8 +279,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - #endif - - grub_dprintf ("linux", "setting up cmdline\n"); -- linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, -- BYTES_TO_PAGES(lh->cmdline_size + 1)); -+ linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, -+ BYTES_TO_PAGES(lh->cmdline_size + 1)); -+ if (!linux_cmdline) -+ linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS, -+ BYTES_TO_PAGES(lh->cmdline_size + 1)); - if (!linux_cmdline) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); -@@ -301,11 +310,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - kernel_mem = grub_efi_allocate_pages_max(lh->pref_address, - BYTES_TO_PAGES(lh->init_size)); -- - if (!kernel_mem) -- kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, -+ kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, -+ BYTES_TO_PAGES(lh->init_size)); -+ if (!kernel_mem) -+ kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS, - BYTES_TO_PAGES(lh->init_size)); -- - if (!kernel_mem) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); -diff --git a/include/grub/arm/efi/memory.h b/include/grub/arm/efi/memory.h -index 2c64918e3f7..a4c2ec83502 100644 ---- a/include/grub/arm/efi/memory.h -+++ b/include/grub/arm/efi/memory.h -@@ -2,5 +2,6 @@ - #include - - #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS - - #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/arm64/efi/memory.h b/include/grub/arm64/efi/memory.h -index c6cb3241714..acb61dca44b 100644 ---- a/include/grub/arm64/efi/memory.h -+++ b/include/grub/arm64/efi/memory.h -@@ -2,5 +2,6 @@ - #include - - #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS - - #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h -index 2c64918e3f7..a4c2ec83502 100644 ---- a/include/grub/i386/efi/memory.h -+++ b/include/grub/i386/efi/memory.h -@@ -2,5 +2,6 @@ - #include - - #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS - - #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/ia64/efi/memory.h b/include/grub/ia64/efi/memory.h -index 2c64918e3f7..a4c2ec83502 100644 ---- a/include/grub/ia64/efi/memory.h -+++ b/include/grub/ia64/efi/memory.h -@@ -2,5 +2,6 @@ - #include - - #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS - - #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/riscv64/efi/memory.h b/include/grub/riscv64/efi/memory.h -index c6cb3241714..acb61dca44b 100644 ---- a/include/grub/riscv64/efi/memory.h -+++ b/include/grub/riscv64/efi/memory.h -@@ -2,5 +2,6 @@ - #include - - #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS - - #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h -index 46e9145a308..e81cfb32213 100644 ---- a/include/grub/x86_64/efi/memory.h -+++ b/include/grub/x86_64/efi/memory.h -@@ -2,9 +2,11 @@ - #include - - #if defined (__code_model_large__) --#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff -+#define GRUB_EFI_MAX_USABLE_ADDRESS __UINTPTR_MAX__ -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS 0x7fffffff - #else - #define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffff -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS - #endif - - #endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/0103-Attempt-to-fix-up-all-the-places-Wsign-compare-error.patch b/0103-Attempt-to-fix-up-all-the-places-Wsign-compare-error.patch deleted file mode 100644 index c2f2a59..0000000 --- a/0103-Attempt-to-fix-up-all-the-places-Wsign-compare-error.patch +++ /dev/null @@ -1,397 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 18:03:25 +0200 -Subject: [PATCH] Attempt to fix up all the places -Wsign-compare=error finds. - -Signed-off-by: Peter Jones ---- - grub-core/kern/emu/misc.c | 2 +- - grub-core/lib/reed_solomon.c | 4 +- - grub-core/osdep/linux/blocklist.c | 2 +- - grub-core/osdep/linux/getroot.c | 2 +- - grub-core/osdep/linux/hostdisk.c | 2 +- - util/grub-fstest.c | 2 +- - util/grub-menulst2cfg.c | 2 +- - util/grub-mkfont.c | 13 +- - util/grub-probe.c | 2 +- - util/grub-rpm-sort.c | 2 +- - util/setup.c | 2 +- - bootstrap.conf | 3 +- - .../gnulib-patches/fix-sign-compare-errors.patch | 161 +++++++++++++++++++++ - 13 files changed, 181 insertions(+), 18 deletions(-) - create mode 100644 grub-core/lib/gnulib-patches/fix-sign-compare-errors.patch - -diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c -index eeea092752d..f08a1bb8415 100644 ---- a/grub-core/kern/emu/misc.c -+++ b/grub-core/kern/emu/misc.c -@@ -189,7 +189,7 @@ grub_util_get_image_size (const char *path) - sz = ftello (f); - if (sz < 0) - grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); -- if (sz != (size_t) sz) -+ if (sz > (off_t)(GRUB_SIZE_MAX >> 1)) - grub_util_error (_("file `%s' is too big"), path); - ret = (size_t) sz; - -diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c -index 467305b46ab..79037c093f7 100644 ---- a/grub-core/lib/reed_solomon.c -+++ b/grub-core/lib/reed_solomon.c -@@ -157,7 +157,7 @@ static void - rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) - { - gf_single_t *rs_polynomial; -- int i, j; -+ unsigned int i, j; - gf_single_t *m; - m = xcalloc (s + rs, sizeof (gf_single_t)); - grub_memcpy (m, data, s * sizeof (gf_single_t)); -@@ -324,7 +324,7 @@ static void - encode_block (gf_single_t *ptr, grub_size_t s, - gf_single_t *rptr, grub_size_t rs) - { -- int i, j; -+ unsigned int i, j; - for (i = 0; i < SECTOR_SIZE; i++) - { - grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; -diff --git a/grub-core/osdep/linux/blocklist.c b/grub-core/osdep/linux/blocklist.c -index c77d6085ccb..42a315031ff 100644 ---- a/grub-core/osdep/linux/blocklist.c -+++ b/grub-core/osdep/linux/blocklist.c -@@ -109,7 +109,7 @@ grub_install_get_blocklist (grub_device_t root_dev, - else - { - struct fiemap *fie2; -- int i; -+ unsigned int i; - fie2 = xmalloc (sizeof (*fie2) - + fie1.fm_mapped_extents - * sizeof (fie1.fm_extents[1])); -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index 28790307e00..9f730b35189 100644 ---- a/grub-core/osdep/linux/getroot.c -+++ b/grub-core/osdep/linux/getroot.c -@@ -236,7 +236,7 @@ grub_find_root_devices_from_btrfs (const char *dir) - { - int fd; - struct btrfs_ioctl_fs_info_args fsi; -- int i, j = 0; -+ unsigned int i, j = 0; - char **ret; - - fd = open (dir, 0); -diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c -index da62f924e35..7bc99ac1c1d 100644 ---- a/grub-core/osdep/linux/hostdisk.c -+++ b/grub-core/osdep/linux/hostdisk.c -@@ -83,7 +83,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - for (log_sector_size = 0; -- (1 << log_sector_size) < sector_size; -+ (1U << log_sector_size) < sector_size; - log_sector_size++); - - if (log_secsize) -diff --git a/util/grub-fstest.c b/util/grub-fstest.c -index 83865642009..bfcef852d83 100644 ---- a/util/grub-fstest.c -+++ b/util/grub-fstest.c -@@ -323,7 +323,7 @@ cmd_cmp (char *src, char *dest) - read_file (src, cmp_hook, ff); - - { -- grub_uint64_t pre; -+ long long pre; - pre = ftell (ff); - fseek (ff, 0, SEEK_END); - if (pre != ftell (ff)) -diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c -index a39f8693947..358d604210b 100644 ---- a/util/grub-menulst2cfg.c -+++ b/util/grub-menulst2cfg.c -@@ -34,7 +34,7 @@ main (int argc, char **argv) - char *buf = NULL; - size_t bufsize = 0; - char *suffix = xstrdup (""); -- int suffixlen = 0; -+ size_t suffixlen = 0; - const char *out_fname = 0; - - grub_util_host_init (&argc, &argv); -diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c -index 0fe45a6103d..3e09240b99f 100644 ---- a/util/grub-mkfont.c -+++ b/util/grub-mkfont.c -@@ -138,7 +138,8 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - int width, height; - int cuttop, cutbottom, cutleft, cutright; - grub_uint8_t *data; -- int mask, i, j, bitmap_size; -+ int mask, i, bitmap_size; -+ unsigned int j; - FT_GlyphSlot glyph; - int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME; - FT_Error err; -@@ -183,7 +184,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - cuttop = cutbottom = cutleft = cutright = 0; - else - { -- for (cuttop = 0; cuttop < glyph->bitmap.rows; cuttop++) -+ for (cuttop = 0; cuttop < (long)glyph->bitmap.rows; cuttop++) - { - for (j = 0; j < glyph->bitmap.width; j++) - if (glyph->bitmap.buffer[j / 8 + cuttop * glyph->bitmap.pitch] -@@ -203,10 +204,10 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - break; - } - cutbottom = glyph->bitmap.rows - 1 - cutbottom; -- if (cutbottom + cuttop >= glyph->bitmap.rows) -+ if (cutbottom + cuttop >= (long)glyph->bitmap.rows) - cutbottom = 0; - -- for (cutleft = 0; cutleft < glyph->bitmap.width; cutleft++) -+ for (cutleft = 0; cutleft < (long)glyph->bitmap.width; cutleft++) - { - for (j = 0; j < glyph->bitmap.rows; j++) - if (glyph->bitmap.buffer[cutleft / 8 + j * glyph->bitmap.pitch] -@@ -225,7 +226,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - break; - } - cutright = glyph->bitmap.width - 1 - cutright; -- if (cutright + cutleft >= glyph->bitmap.width) -+ if (cutright + cutleft >= (long)glyph->bitmap.width) - cutright = 0; - } - -@@ -262,7 +263,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - - mask = 0; - data = &glyph_info->bitmap[0] - 1; -- for (j = cuttop; j < height + cuttop; j++) -+ for (j = cuttop; j < (long)height + cuttop; j++) - for (i = cutleft; i < width + cutleft; i++) - add_pixel (&data, &mask, - glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] & -diff --git a/util/grub-probe.c b/util/grub-probe.c -index c08e46bbb40..c6fac732b40 100644 ---- a/util/grub-probe.c -+++ b/util/grub-probe.c -@@ -798,7 +798,7 @@ argp_parser (int key, char *arg, struct argp_state *state) - - case 't': - { -- int i; -+ unsigned int i; - - for (i = PRINT_FS; i < ARRAY_SIZE (targets); i++) - if (strcmp (arg, targets[i]) == 0) -diff --git a/util/grub-rpm-sort.c b/util/grub-rpm-sort.c -index f33bd1ed568..8345944105f 100644 ---- a/util/grub-rpm-sort.c -+++ b/util/grub-rpm-sort.c -@@ -232,7 +232,7 @@ main (int argc, char *argv[]) - struct arguments arguments; - char **package_names = NULL; - size_t n_package_names = 0; -- int i; -+ unsigned int i; - - grub_util_host_init (&argc, &argv); - -diff --git a/util/setup.c b/util/setup.c -index da5f2c07f50..8b22bb8ccac 100644 ---- a/util/setup.c -+++ b/util/setup.c -@@ -406,7 +406,7 @@ SETUP (const char *dir, - int is_ldm; - grub_err_t err; - grub_disk_addr_t *sectors; -- int i; -+ unsigned int i; - grub_fs_t fs; - unsigned int nsec, maxsec; - -diff --git a/bootstrap.conf b/bootstrap.conf -index 6b043fc354c..186be9c48ce 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -80,7 +80,8 @@ cp -a INSTALL INSTALL.grub - bootstrap_post_import_hook () { - set -e - for patchname in fix-base64 fix-null-deref fix-null-state-deref fix-regcomp-uninit-token \ -- fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width no-abort; do -+ fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width no-abort \ -+ fix-sign-compare-errors; do - patch -d grub-core/lib/gnulib -p2 \ - < "grub-core/lib/gnulib-patches/$patchname.patch" - done -diff --git a/grub-core/lib/gnulib-patches/fix-sign-compare-errors.patch b/grub-core/lib/gnulib-patches/fix-sign-compare-errors.patch -new file mode 100644 -index 00000000000..479029c0565 ---- /dev/null -+++ b/grub-core/lib/gnulib-patches/fix-sign-compare-errors.patch -@@ -0,0 +1,161 @@ -+diff --git a/lib/regcomp.c b/lib/regcomp.c -+index cc85f35ac58..361079d82d6 100644 -+--- a/lib/regcomp.c -++++ b/lib/regcomp.c -+@@ -322,7 +322,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, -+ *p++ = dfa->nodes[node].opr.c; -+ memset (&state, '\0', sizeof (state)); -+ if (__mbrtowc (&wc, (const char *) buf, p - buf, -+- &state) == p - buf -++ &state) == (size_t)(p - buf) -+ && (__wcrtomb ((char *) buf, __towlower (wc), &state) -+ != (size_t) -1)) -+ re_set_fastmap (fastmap, false, buf[0]); -+@@ -3778,7 +3778,7 @@ fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) -+ num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2) -+ ? -2 -+ : num == -1 -+- ? c - '0' -++ ? (Idx)(c - '0') -+ : MIN (RE_DUP_MAX + 1, num * 10 + c - '0')); -+ } -+ return num; -+diff --git a/lib/regex_internal.c b/lib/regex_internal.c -+index 9004ce809eb..193a1e3d332 100644 -+--- a/lib/regex_internal.c -++++ b/lib/regex_internal.c -+@@ -233,7 +233,7 @@ build_wcs_buffer (re_string_t *pstr) -+ /* Apply the translation if we need. */ -+ if (__glibc_unlikely (pstr->trans != NULL)) -+ { -+- int i, ch; -++ unsigned int i, ch; -+ -+ for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) -+ { -+@@ -376,7 +376,7 @@ build_wcs_upper_buffer (re_string_t *pstr) -+ prev_st = pstr->cur_state; -+ if (__glibc_unlikely (pstr->trans != NULL)) -+ { -+- int i, ch; -++ unsigned int i, ch; -+ -+ for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) -+ { -+@@ -754,7 +754,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) -+ memset (&cur_state, 0, sizeof (cur_state)); -+ mbclen = __mbrtowc (&wc2, (const char *) pp, mlen, -+ &cur_state); -+- if (raw + offset - p <= mbclen -++ if ((size_t)(raw + offset - p) <= mbclen -+ && mbclen < (size_t) -2) -+ { -+ memset (&pstr->cur_state, '\0', -+diff --git a/lib/regex_internal.h b/lib/regex_internal.h -+index 5462419b787..e0f8292395d 100644 -+--- a/lib/regex_internal.h -++++ b/lib/regex_internal.h -+@@ -425,7 +425,7 @@ struct re_string_t -+ unsigned char offsets_needed; -+ unsigned char newline_anchor; -+ unsigned char word_ops_used; -+- int mb_cur_max; -++ unsigned int mb_cur_max; -+ }; -+ typedef struct re_string_t re_string_t; -+ -+@@ -702,7 +702,7 @@ struct re_dfa_t -+ unsigned int is_utf8 : 1; -+ unsigned int map_notascii : 1; -+ unsigned int word_ops_used : 1; -+- int mb_cur_max; -++ unsigned int mb_cur_max; -+ bitset_t word_char; -+ reg_syntax_t syntax; -+ Idx *subexp_map; -+diff --git a/lib/regexec.c b/lib/regexec.c -+index 0a7a27b772e..b57d4f9141d 100644 -+--- a/lib/regexec.c -++++ b/lib/regexec.c -+@@ -443,7 +443,7 @@ re_search_stub (struct re_pattern_buffer *bufp, const char *string, Idx length, -+ { -+ if (ret_len) -+ { -+- assert (pmatch[0].rm_so == start); -++ assert (pmatch[0].rm_so == (long)start); -+ rval = pmatch[0].rm_eo - start; -+ } -+ else -+@@ -877,11 +877,11 @@ re_search_internal (const regex_t *preg, const char *string, Idx length, -+ if (__glibc_unlikely (mctx.input.offsets_needed != 0)) -+ { -+ pmatch[reg_idx].rm_so = -+- (pmatch[reg_idx].rm_so == mctx.input.valid_len -++ (pmatch[reg_idx].rm_so == (long)mctx.input.valid_len -+ ? mctx.input.valid_raw_len -+ : mctx.input.offsets[pmatch[reg_idx].rm_so]); -+ pmatch[reg_idx].rm_eo = -+- (pmatch[reg_idx].rm_eo == mctx.input.valid_len -++ (pmatch[reg_idx].rm_eo == (long)mctx.input.valid_len -+ ? mctx.input.valid_raw_len -+ : mctx.input.offsets[pmatch[reg_idx].rm_eo]); -+ } -+@@ -1418,11 +1418,11 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, -+ } -+ memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); -+ -+- for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;) -++ for (idx = pmatch[0].rm_so; idx <= (long)pmatch[0].rm_eo ;) -+ { -+ update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); -+ -+- if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) -++ if (idx == (long)pmatch[0].rm_eo && cur_node == mctx->last_node) -+ { -+ Idx reg_idx; -+ if (fs) -+@@ -1519,7 +1519,7 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, -+ if (reg_num < nmatch) -+ { -+ /* We are at the last node of this sub expression. */ -+- if (pmatch[reg_num].rm_so < cur_idx) -++ if (pmatch[reg_num].rm_so < (long)cur_idx) -+ { -+ pmatch[reg_num].rm_eo = cur_idx; -+ /* This is a non-empty match or we are not inside an optional -+@@ -2938,7 +2938,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, -+ mctx->state_log[str_idx] = cur_state; -+ } -+ -+- for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;) -++ for (null_cnt = 0; str_idx < last_str && null_cnt <= (long)mctx->max_mb_elem_len;) -+ { -+ re_node_set_empty (&next_nodes); -+ if (mctx->state_log[str_idx + 1]) -+@@ -3718,7 +3718,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, -+ const re_string_t *input, Idx str_idx) -+ { -+ const re_token_t *node = dfa->nodes + node_idx; -+- int char_len, elem_len; -++ unsigned int char_len, elem_len; -+ Idx i; -+ -+ if (__glibc_unlikely (node->type == OP_UTF8_PERIOD)) -+@@ -4066,7 +4066,7 @@ extend_buffers (re_match_context_t *mctx, int min_len) -+ /* Double the lengths of the buffers, but allocate at least MIN_LEN. */ -+ ret = re_string_realloc_buffers (pstr, -+ MAX (min_len, -+- MIN (pstr->len, pstr->bufs_len * 2))); -++ MIN ((long)pstr->len, pstr->bufs_len * 2))); -+ if (__glibc_unlikely (ret != REG_NOERROR)) -+ return ret; -+ -+@@ -4236,7 +4236,7 @@ match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, -+ = (from == to ? -1 : 0); -+ -+ mctx->bkref_ents[mctx->nbkref_ents++].more = 0; -+- if (mctx->max_mb_elem_len < to - from) -++ if (mctx->max_mb_elem_len < (long)(to - from)) -+ mctx->max_mb_elem_len = to - from; -+ return REG_NOERROR; -+ } diff --git a/0104-Don-t-use-Wno-sign-compare-Wno-conversion-Wno-error-.patch b/0104-Don-t-use-Wno-sign-compare-Wno-conversion-Wno-error-.patch deleted file mode 100644 index 1fa705e..0000000 --- a/0104-Don-t-use-Wno-sign-compare-Wno-conversion-Wno-error-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 18:20:37 +0200 -Subject: [PATCH] Don't use -Wno-sign-compare -Wno-conversion -Wno-error, do - use -Wextra. - -Signed-off-by: Peter Jones ---- - configure.ac | 14 +++++++++++--- - conf/Makefile.common | 2 +- - 2 files changed, 12 insertions(+), 4 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 59ccda24475..6eb297fdbf6 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1480,11 +1480,11 @@ fi - # Set them to their new values for the tests below. - CC="$TARGET_CC" - if test x"$platform" = xemu ; then --CFLAGS="$TARGET_CFLAGS -Wno-error" -+CFLAGS="$TARGET_CFLAGS" - elif test "x$TARGET_APPLE_LINKER" = x1 ; then --CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error" -+CFLAGS="$TARGET_CFLAGS -nostdlib -static" - else --CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" -+CFLAGS="$TARGET_CFLAGS -nostdlib" - fi - CPPFLAGS="$TARGET_CPPFLAGS" - -@@ -2047,6 +2047,14 @@ if test x"$enable_werror" != xno ; then - HOST_CFLAGS="$HOST_CFLAGS -Werror" - fi - -+AC_ARG_ENABLE([wextra], -+ [AS_HELP_STRING([--disable-wextra], -+ [do not use -Wextra when building GRUB])]) -+if test x"$enable_wextra" != xno ; then -+ TARGET_CFLAGS="$TARGET_CFLAGS -Wextra" -+ HOST_CFLAGS="$HOST_CFLAGS -Wextra" -+fi -+ - TARGET_CPP="$TARGET_CC -E" - TARGET_CCAS=$TARGET_CC - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 2ff9b39357c..35e14ff017e 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -66,7 +66,7 @@ grubconfdir = $(sysconfdir)/grub.d - platformdir = $(pkglibdir)/$(target_cpu)-$(platform) - starfielddir = $(pkgdatadir)/themes/starfield - --CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -+CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code - CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib - - CFLAGS_POSIX = -fno-builtin diff --git a/0105-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch b/0105-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch deleted file mode 100644 index fdd3096..0000000 --- a/0105-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 12 Jul 2019 09:53:32 +0200 -Subject: [PATCH] x86-efi: Use bounce buffers for reading to addresses > 4GB - -Lots of machines apparently can't DMA correctly above 4GB during UEFI, -so use bounce buffers for the initramfs read. - -Signed-off-by: Peter Jones ---- - grub-core/loader/i386/efi/linux.c | 52 +++++++++++++++++++++++++++++++++------ - 1 file changed, 45 insertions(+), 7 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 33e981e76e7..2f0336809e7 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -35,11 +35,16 @@ static grub_dl_t my_mod; - static int loaded; - static void *kernel_mem; - static grub_uint64_t kernel_size; --static grub_uint8_t *initrd_mem; -+static void *initrd_mem; - static grub_uint32_t handover_offset; - struct linux_kernel_params *params; - static char *linux_cmdline; - -+#define MIN(a, b) \ -+ ({ typeof (a) _a = (a); \ -+ typeof (b) _b = (b); \ -+ _a < _b ? _a : _b; }) -+ - #define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) - - static grub_err_t -@@ -73,6 +78,44 @@ grub_linuxefi_unload (void) - return GRUB_ERR_NONE; - } - -+#define BOUNCE_BUFFER_MAX 0x10000000ull -+ -+static grub_ssize_t -+read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) -+{ -+ grub_ssize_t bufpos = 0; -+ static grub_size_t bbufsz = 0; -+ static char *bbuf = NULL; -+ -+ if (bbufsz == 0) -+ bbufsz = MIN(BOUNCE_BUFFER_MAX, len); -+ -+ while (!bbuf && bbufsz) -+ { -+ bbuf = grub_malloc(bbufsz); -+ if (!bbuf) -+ bbufsz >>= 1; -+ } -+ if (!bbuf) -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate bounce buffer")); -+ -+ while (bufpos < (long long)len) -+ { -+ grub_ssize_t sz; -+ -+ sz = grub_file_read (file, bbuf, MIN(bbufsz, len - bufpos)); -+ if (sz < 0) -+ return sz; -+ if (sz == 0) -+ break; -+ -+ grub_memcpy(bufp + bufpos, bbuf, sz); -+ bufpos += sz; -+ } -+ -+ return bufpos; -+} -+ - static grub_err_t - grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -@@ -126,7 +169,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - for (i = 0; i < nfiles; i++) - { - grub_ssize_t cursize = grub_file_size (files[i]); -- if (grub_file_read (files[i], ptr, cursize) != cursize) -+ if (read (files[i], ptr, cursize) != cursize) - { - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), -@@ -152,11 +195,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - return grub_errno; - } - --#define MIN(a, b) \ -- ({ typeof (a) _a = (a); \ -- typeof (b) _b = (b); \ -- _a < _b ? _a : _b; }) -- - static grub_err_t - grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) diff --git a/0106-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch b/0106-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch deleted file mode 100644 index f8284ec..0000000 --- a/0106-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 13 Sep 2018 14:42:34 -0400 -Subject: [PATCH] x86-efi: Re-arrange grub_cmd_linux() a little bit. - -This just helps the next patch be easier to read. - -Signed-off-by: Peter Jones ---- - grub-core/loader/i386/efi/linux.c | 75 +++++++++++++++++++++------------------ - 1 file changed, 41 insertions(+), 34 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 2f0336809e7..5f48fa55619 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -243,32 +243,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, -- BYTES_TO_PAGES(sizeof(*params))); -- if (!params) -- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, -- BYTES_TO_PAGES(sizeof(*params))); -- if (! params) -- { -- grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); -- goto fail; -- } -+ lh = (struct linux_i386_kernel_header *)kernel; -+ grub_dprintf ("linux", "original lh is at %p\n", kernel); - -- grub_dprintf ("linux", "params = %p\n", params); -- -- grub_memset (params, 0, sizeof(*params)); -- -- setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); -- grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", -- MIN((grub_size_t)0x202+setup_header_end_offset, -- sizeof (*params)) - 0x1f1, -- (grub_uint8_t *)kernel + 0x1f1, -- (grub_uint8_t *)params + 0x1f1); -- grub_memcpy ((grub_uint8_t *)params + 0x1f1, -- (grub_uint8_t *)kernel + 0x1f1, -- MIN((grub_size_t)0x202+setup_header_end_offset,sizeof (*params)) - 0x1f1); -- lh = (struct linux_i386_kernel_header *)params; -- grub_dprintf ("linux", "lh is at %p\n", lh); - grub_dprintf ("linux", "checking lh->boot_flag\n"); - if (lh->boot_flag != grub_cpu_to_le16 (0xaa55)) - { -@@ -316,6 +293,34 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - #endif - -+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, -+ BYTES_TO_PAGES(sizeof(*params))); -+ if (!params) -+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, -+ BYTES_TO_PAGES(sizeof(*params))); -+ if (! params) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); -+ goto fail; -+ } -+ -+ grub_dprintf ("linux", "params = %p\n", params); -+ -+ grub_memset (params, 0, sizeof(*params)); -+ -+ setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); -+ grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", -+ MIN((grub_size_t)0x202+setup_header_end_offset, -+ sizeof (*params)) - 0x1f1, -+ (grub_uint8_t *)kernel + 0x1f1, -+ (grub_uint8_t *)params + 0x1f1); -+ grub_memcpy ((grub_uint8_t *)params + 0x1f1, -+ (grub_uint8_t *)kernel + 0x1f1, -+ MIN((grub_size_t)0x202+setup_header_end_offset,sizeof (*params)) - 0x1f1); -+ -+ lh = (struct linux_i386_kernel_header *)params; -+ grub_dprintf ("linux", "new lh is at %p\n", lh); -+ - grub_dprintf ("linux", "setting up cmdline\n"); - linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, - BYTES_TO_PAGES(lh->cmdline_size + 1)); -@@ -341,8 +346,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_dprintf ("linux", "setting lh->cmd_line_ptr\n"); - lh->cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; - -- grub_dprintf ("linux", "computing handover offset\n"); - handover_offset = lh->handover_offset; -+ grub_dprintf("linux", "handover_offset: %08x\n", handover_offset); - - start = (lh->setup_sects + 1) * 512; - -@@ -359,26 +364,28 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); - goto fail; - } -- -- grub_dprintf ("linux", "kernel_mem = %lx\n", (unsigned long) kernel_mem); -+ grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); - - grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); -- loaded=1; -+ -+ loaded = 1; -+ - grub_dprintf ("linux", "setting lh->code32_start to %p\n", kernel_mem); - lh->code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; - - grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start); - -- grub_dprintf ("linux", "setting lh->type_of_loader\n"); - lh->type_of_loader = 0x6; -+ grub_dprintf ("linux", "setting lh->type_of_loader = 0x%02x\n", -+ lh->type_of_loader); - -- grub_dprintf ("linux", "setting lh->ext_loader_{type,ver}\n"); - params->ext_loader_type = 0; - params->ext_loader_ver = 2; -- grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n", -- kernel_mem, handover_offset); -+ grub_dprintf ("linux", -+ "setting lh->ext_loader_{type,ver} = {0x%02x,0x%02x}\n", -+ params->ext_loader_type, params->ext_loader_ver); - -- fail: -+fail: - if (file) - grub_file_close (file); - diff --git a/0107-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch b/0107-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch deleted file mode 100644 index 4ad0696..0000000 --- a/0107-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch +++ /dev/null @@ -1,258 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 12 Sep 2018 16:03:55 -0400 -Subject: [PATCH] x86-efi: Make our own allocator for kernel stuff - -This helps enable allocations above 4GB. - -Signed-off-by: Peter Jones ---- - grub-core/loader/i386/efi/linux.c | 167 +++++++++++++++++++++----------------- - 1 file changed, 94 insertions(+), 73 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 5f48fa55619..3e4f7ef39f4 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -47,6 +47,65 @@ static char *linux_cmdline; - - #define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) - -+struct allocation_choice { -+ grub_efi_physical_address_t addr; -+ grub_efi_allocate_type_t alloc_type; -+}; -+ -+static struct allocation_choice max_addresses[] = -+ { -+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, -+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, -+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, -+ { 0, 0 } -+ }; -+ -+static inline void -+kernel_free(void *addr, grub_efi_uintn_t size) -+{ -+ if (addr && size) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)addr, -+ BYTES_TO_PAGES(size)); -+} -+ -+static void * -+kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) -+{ -+ void *addr = 0; -+ unsigned int i; -+ grub_efi_physical_address_t prev_max = 0; -+ -+ for (i = 0; max_addresses[i].addr != 0 && addr == 0; i++) -+ { -+ grub_uint64_t max = max_addresses[i].addr; -+ grub_efi_uintn_t pages; -+ -+ if (max == prev_max) -+ continue; -+ -+ pages = BYTES_TO_PAGES(size); -+ grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n", -+ pages, (void *)max); -+ -+ prev_max = max; -+ addr = grub_efi_allocate_pages_real (max, pages, -+ max_addresses[i].alloc_type, -+ GRUB_EFI_LOADER_DATA); -+ if (addr) -+ grub_dprintf ("linux", "Allocated at %p\n", addr); -+ } -+ -+ while (grub_error_pop ()) -+ { -+ ; -+ } -+ -+ if (addr == NULL) -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "%s", errmsg); -+ -+ return addr; -+} -+ - static grub_err_t - grub_linuxefi_boot (void) - { -@@ -62,19 +121,12 @@ grub_linuxefi_unload (void) - { - grub_dl_unref (my_mod); - loaded = 0; -- if (initrd_mem) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, -- BYTES_TO_PAGES(params->ramdisk_size)); -- if (linux_cmdline) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) -- linux_cmdline, -- BYTES_TO_PAGES(params->cmdline_size + 1)); -- if (kernel_mem) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -- BYTES_TO_PAGES(kernel_size)); -- if (params) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, -- BYTES_TO_PAGES(16384)); -+ -+ kernel_free(initrd_mem, params->ramdisk_size); -+ kernel_free(linux_cmdline, params->cmdline_size + 1); -+ kernel_free(kernel_mem, kernel_size); -+ kernel_free(params, sizeof(*params)); -+ - return GRUB_ERR_NONE; - } - -@@ -150,19 +202,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - size += ALIGN_UP (grub_file_size (files[i]), 4); - } - -- initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(size)); -- if (!initrd_mem) -- initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, BYTES_TO_PAGES(size)); -- if (!initrd_mem) -- { -- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); -- goto fail; -- } -- -- grub_dprintf ("linux", "initrd_mem = %lx\n", (unsigned long) initrd_mem); -+ initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); -+ if (initrd_mem == NULL) -+ goto fail; -+ grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); - - params->ramdisk_size = size; -- params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem; -+ params->ramdisk_image = initrd_mem; - - ptr = initrd_mem; - -@@ -221,7 +267,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - filelen = grub_file_size (file); - - kernel = grub_malloc(filelen); -- - if (!kernel) - { - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -@@ -274,7 +319,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - --#if defined(__x86_64__) || defined(__aarch64__) -+#if defined(__x86_64__) - grub_dprintf ("linux", "checking lh->xloadflags\n"); - if (!(lh->xloadflags & LINUX_XLF_KERNEL_64)) - { -@@ -293,17 +338,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - #endif - -- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, -- BYTES_TO_PAGES(sizeof(*params))); -+ params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters"); - if (!params) -- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, -- BYTES_TO_PAGES(sizeof(*params))); -- if (! params) -- { -- grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); -- goto fail; -- } -- -+ goto fail; - grub_dprintf ("linux", "params = %p\n", params); - - grub_memset (params, 0, sizeof(*params)); -@@ -322,19 +359,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_dprintf ("linux", "new lh is at %p\n", lh); - - grub_dprintf ("linux", "setting up cmdline\n"); -- linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, -- BYTES_TO_PAGES(lh->cmdline_size + 1)); -+ linux_cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline")); - if (!linux_cmdline) -- linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS, -- BYTES_TO_PAGES(lh->cmdline_size + 1)); -- if (!linux_cmdline) -- { -- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); -- goto fail; -- } -- -- grub_dprintf ("linux", "linux_cmdline = %lx\n", -- (unsigned long)linux_cmdline); -+ goto fail; -+ grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline); - - grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, -@@ -343,27 +371,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - GRUB_VERIFY_KERNEL_CMDLINE); - - grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); -- grub_dprintf ("linux", "setting lh->cmd_line_ptr\n"); -- lh->cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; -+ grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n", -+ linux_cmdline); -+ lh->cmd_line_ptr = linux_cmdline; - - handover_offset = lh->handover_offset; -- grub_dprintf("linux", "handover_offset: %08x\n", handover_offset); -+ grub_dprintf("linux", "handover_offset: 0x%08x\n", handover_offset); - - start = (lh->setup_sects + 1) * 512; - -- kernel_mem = grub_efi_allocate_pages_max(lh->pref_address, -- BYTES_TO_PAGES(lh->init_size)); -- if (!kernel_mem) -- kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, -- BYTES_TO_PAGES(lh->init_size)); -- if (!kernel_mem) -- kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS, -- BYTES_TO_PAGES(lh->init_size)); -- if (!kernel_mem) -+ grub_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address); -+ if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS) - { -- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); -- goto fail; -+ max_addresses[0].addr = lh->pref_address; -+ max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS; - } -+ kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel")); -+ if (!kernel_mem) -+ goto fail; - grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); - - grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); -@@ -398,18 +423,14 @@ fail: - loaded = 0; - } - -- if (linux_cmdline && lh && !loaded) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) -- linux_cmdline, -- BYTES_TO_PAGES(lh->cmdline_size + 1)); -+ if (!loaded) -+ { -+ if (lh) -+ kernel_free (linux_cmdline, lh->cmdline_size + 1); - -- if (kernel_mem && !loaded) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -- BYTES_TO_PAGES(kernel_size)); -- -- if (params && !loaded) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, -- BYTES_TO_PAGES(16384)); -+ kernel_free (kernel_mem, kernel_size); -+ kernel_free (params, sizeof(*params)); -+ } - - return grub_errno; - } diff --git a/0108-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch b/0108-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch deleted file mode 100644 index b1233ce..0000000 --- a/0108-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 12 Sep 2018 16:12:27 -0400 -Subject: [PATCH] x86-efi: Allow initrd+params+cmdline allocations above 4GB. - -This enables everything except the kernel itself to be above 4GB. -Putting the kernel up there still doesn't work, because of the way -params->code32_start is used. - -Signed-off-by: Peter Jones ---- - grub-core/loader/i386/efi/linux.c | 67 +++++++++++++++++++++++++++++++++++---- - include/grub/i386/linux.h | 6 +++- - 2 files changed, 65 insertions(+), 8 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 3e4f7ef39f4..6bc18d5aef5 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -52,13 +52,22 @@ struct allocation_choice { - grub_efi_allocate_type_t alloc_type; - }; - --static struct allocation_choice max_addresses[] = -+static struct allocation_choice max_addresses[4] = - { -+ /* the kernel overrides this one with pref_address and -+ * GRUB_EFI_ALLOCATE_ADDRESS */ - { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, -+ /* this one is always below 4GB, which we still *prefer* even if the flag -+ * is set. */ - { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, -+ /* If the flag in params is set, this one gets changed to be above 4GB. */ - { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS }, - { 0, 0 } - }; -+static struct allocation_choice saved_addresses[4]; -+ -+#define save_addresses() grub_memcpy(saved_addresses, max_addresses, sizeof(max_addresses)) -+#define restore_addresses() grub_memcpy(max_addresses, saved_addresses, sizeof(max_addresses)) - - static inline void - kernel_free(void *addr, grub_efi_uintn_t size) -@@ -80,6 +89,11 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) - grub_uint64_t max = max_addresses[i].addr; - grub_efi_uintn_t pages; - -+ /* -+ * When we're *not* loading the kernel, or >4GB allocations aren't -+ * supported, these entries are basically all the same, so don't re-try -+ * the same parameters. -+ */ - if (max == prev_max) - continue; - -@@ -168,6 +182,9 @@ read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) - return bufpos; - } - -+#define LOW_U32(val) ((grub_uint32_t)(((grub_addr_t)(val)) & 0xffffffffull)) -+#define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull)) -+ - static grub_err_t - grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -@@ -207,8 +224,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - goto fail; - grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); - -- params->ramdisk_size = size; -- params->ramdisk_image = initrd_mem; -+ params->ramdisk_size = LOW_U32(size); -+ params->ramdisk_image = LOW_U32(initrd_mem); -+#if defined(__x86_64__) -+ params->ext_ramdisk_size = HIGH_U32(size); -+ params->ext_ramdisk_image = HIGH_U32(initrd_mem); -+#endif - - ptr = initrd_mem; - -@@ -338,6 +359,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - #endif - -+#if defined(__x86_64__) -+ if (lh->xloadflags & LINUX_XLF_CAN_BE_LOADED_ABOVE_4G) -+ { -+ grub_dprintf ("linux", "Loading kernel above 4GB is supported; enabling.\n"); -+ max_addresses[2].addr = GRUB_EFI_MAX_USABLE_ADDRESS; -+ } -+ else -+ { -+ grub_dprintf ("linux", "Loading kernel above 4GB is not supported\n"); -+ } -+#endif -+ - params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters"); - if (!params) - goto fail; -@@ -372,21 +405,40 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); - grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n", -- linux_cmdline); -- lh->cmd_line_ptr = linux_cmdline; -+ LOW_U32(linux_cmdline)); -+ lh->cmd_line_ptr = LOW_U32(linux_cmdline); -+#if defined(__x86_64__) -+ if ((grub_efi_uintn_t)linux_cmdline > 0xffffffffull) -+ { -+ grub_dprintf ("linux", "setting params->ext_cmd_line_ptr to 0x%08x\n", -+ HIGH_U32(linux_cmdline)); -+ params->ext_cmd_line_ptr = HIGH_U32(linux_cmdline); -+ } -+#endif - - handover_offset = lh->handover_offset; - grub_dprintf("linux", "handover_offset: 0x%08x\n", handover_offset); - - start = (lh->setup_sects + 1) * 512; - -+ /* -+ * AFAICS >4GB for kernel *cannot* work because of params->code32_start being -+ * 32-bit and getting called unconditionally in head_64.S from either entry -+ * point. -+ * -+ * so nerf that out here... -+ */ -+ save_addresses(); - grub_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address); - if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS) - { - max_addresses[0].addr = lh->pref_address; - max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS; - } -+ max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; -+ max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; - kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel")); -+ restore_addresses(); - if (!kernel_mem) - goto fail; - grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); -@@ -395,8 +447,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - loaded = 1; - -- grub_dprintf ("linux", "setting lh->code32_start to %p\n", kernel_mem); -- lh->code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; -+ grub_dprintf ("linux", "setting lh->code32_start to 0x%08x\n", -+ LOW_U32(kernel_mem)); -+ lh->code32_start = LOW_U32(kernel_mem); - - grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start); - -diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h -index 25ef52c04eb..fac22476cc5 100644 ---- a/include/grub/i386/linux.h -+++ b/include/grub/i386/linux.h -@@ -236,7 +236,11 @@ struct linux_kernel_params - grub_uint32_t ofw_cif_handler; /* b8 */ - grub_uint32_t ofw_idt; /* bc */ - -- grub_uint8_t padding7[0x1b8 - 0xc0]; -+ grub_uint32_t ext_ramdisk_image; /* 0xc0 */ -+ grub_uint32_t ext_ramdisk_size; /* 0xc4 */ -+ grub_uint32_t ext_cmd_line_ptr; /* 0xc8 */ -+ -+ grub_uint8_t padding7[0x1b8 - 0xcc]; - - union - { diff --git a/0109-Fix-getroot.c-s-trampolines.patch b/0109-Fix-getroot.c-s-trampolines.patch deleted file mode 100644 index 29ec44c..0000000 --- a/0109-Fix-getroot.c-s-trampolines.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 28 Sep 2018 15:42:19 -0400 -Subject: [PATCH] Fix getroot.c's trampolines. - -This makes the stack executable on most of the grub utilities, which is -bad, and rpmdiff complains about it. - -Signed-off-by: Peter Jones ---- - grub-core/osdep/linux/getroot.c | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index 9f730b35189..f0c503f43d3 100644 ---- a/grub-core/osdep/linux/getroot.c -+++ b/grub-core/osdep/linux/getroot.c -@@ -1264,22 +1264,20 @@ grub_util_get_grub_dev_os (const char *os_dev) - return grub_dev; - } - -+static void *mp = NULL; -+static void -+btrfs_mount_path_hook(const char *m) -+{ -+ mp = strdup (m); -+} - - char * - grub_util_get_btrfs_subvol (const char *path, char **mount_path) - { -- char *mp = NULL; -- - if (mount_path) - *mount_path = NULL; - -- auto void -- mount_path_hook (const char *m) -- { -- mp = strdup (m); -- } -- -- grub_find_root_btrfs_mount_path_hook = mount_path_hook; -+ grub_find_root_btrfs_mount_path_hook = btrfs_mount_path_hook; - grub_free (grub_find_root_devices_from_mountinfo (path, NULL)); - grub_find_root_btrfs_mount_path_hook = NULL; - diff --git a/0110-Do-not-allow-stack-trampolines-anywhere.patch b/0110-Do-not-allow-stack-trampolines-anywhere.patch deleted file mode 100644 index 2a3247a..0000000 --- a/0110-Do-not-allow-stack-trampolines-anywhere.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 12 Jul 2019 10:06:50 +0200 -Subject: [PATCH] Do not allow stack trampolines, anywhere. - -Signed-off-by: Peter Jones ---- - configure.ac | 3 +++ - conf/Makefile.common | 2 +- - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 6eb297fdbf6..c6bd965f1f9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2055,6 +2055,9 @@ if test x"$enable_wextra" != xno ; then - HOST_CFLAGS="$HOST_CFLAGS -Wextra" - fi - -+TARGET_CFLAGS="$TARGET_CFLAGS -Werror=trampolines -fno-trampolines" -+HOST_CFLAGS="$HOST_CFLAGS -Werror=trampolines -fno-trampolines" -+ - TARGET_CPP="$TARGET_CC -E" - TARGET_CCAS=$TARGET_CC - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 35e14ff017e..0647c53b916 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -66,7 +66,7 @@ grubconfdir = $(sysconfdir)/grub.d - platformdir = $(pkglibdir)/$(target_cpu)-$(platform) - starfielddir = $(pkgdatadir)/themes/starfield - --CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -+CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Werror=trampolines -fno-trampolines - CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib - - CFLAGS_POSIX = -fno-builtin diff --git a/0111-Reimplement-boot_counter.patch b/0111-Reimplement-boot_counter.patch deleted file mode 100644 index a203929..0000000 --- a/0111-Reimplement-boot_counter.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 4 Oct 2018 14:22:09 -0400 -Subject: [PATCH] Reimplement boot_counter - -This adds "increment" and "decrement" commands, and uses them to maintain our -variables in 01_fallback_counter. It also simplifies the counter logic, so -that there are no nested tests that conflict with each other. - -Apparently, this *really* wasn't tested well enough. - -Resolves: rhbz#1614637 -Signed-off-by: Peter Jones -[lorbus: add comments and revert logic changes in 01_fallback_counting] -Signed-off-by: Christian Glombek ---- - Makefile.util.def | 6 +++ - grub-core/Makefile.core.def | 5 ++ - grub-core/commands/increment.c | 105 ++++++++++++++++++++++++++++++++++++ - util/grub.d/01_fallback_counting.in | 22 ++++++++ - 4 files changed, 138 insertions(+) - create mode 100644 grub-core/commands/increment.c - create mode 100644 util/grub.d/01_fallback_counting.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 0b85a7fce4a..27a13bc734e 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -458,6 +458,12 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = '01_fallback_counting'; -+ common = util/grub.d/01_fallback_counting.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '01_menu_auto_hide'; - common = util/grub.d/01_menu_auto_hide.in; -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 498ca11762a..1e15345107e 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -398,6 +398,11 @@ kernel = { - extra_dist = kern/mips/cache_flush.S; - }; - -+module = { -+ name = increment; -+ common = commands/increment.c; -+}; -+ - program = { - name = grub-emu; - mansection = 1; -diff --git a/grub-core/commands/increment.c b/grub-core/commands/increment.c -new file mode 100644 -index 00000000000..79cf137656c ---- /dev/null -+++ b/grub-core/commands/increment.c -@@ -0,0 +1,105 @@ -+/* increment.c - Commands to increment and decrement variables. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+typedef enum { -+ INCREMENT, -+ DECREMENT, -+} operation; -+ -+static grub_err_t -+incr_decr(operation op, int argc, char **args) -+{ -+ const char *old; -+ char *new; -+ long value; -+ -+ if (argc < 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no variable specified")); -+ if (argc > 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("too many arguments")); -+ -+ old = grub_env_get (*args); -+ if (!old) -+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("No such variable \"%s\""), -+ *args); -+ -+ value = grub_strtol (old, NULL, 0); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ -+ switch (op) -+ { -+ case INCREMENT: -+ value += 1; -+ break; -+ case DECREMENT: -+ value -= 1; -+ break; -+ } -+ -+ new = grub_xasprintf ("%ld", value); -+ if (!new) -+ return grub_errno; -+ -+ grub_env_set (*args, new); -+ grub_free (new); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_incr(struct grub_command *cmd UNUSED, -+ int argc, char **args) -+{ -+ return incr_decr(INCREMENT, argc, args); -+} -+ -+static grub_err_t -+grub_cmd_decr(struct grub_command *cmd UNUSED, -+ int argc, char **args) -+{ -+ return incr_decr(DECREMENT, argc, args); -+} -+ -+static grub_command_t cmd_incr, cmd_decr; -+ -+GRUB_MOD_INIT(increment) -+{ -+ cmd_incr = grub_register_command ("increment", grub_cmd_incr, N_("VARIABLE"), -+ N_("increment VARIABLE")); -+ cmd_decr = grub_register_command ("decrement", grub_cmd_decr, N_("VARIABLE"), -+ N_("decrement VARIABLE")); -+} -+ -+GRUB_MOD_FINI(increment) -+{ -+ grub_unregister_command (cmd_incr); -+ grub_unregister_command (cmd_decr); -+} -diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/01_fallback_counting.in -new file mode 100644 -index 00000000000..be0e770ea82 ---- /dev/null -+++ b/util/grub.d/01_fallback_counting.in -@@ -0,0 +1,22 @@ -+#! /bin/sh -e -+ -+# Boot Counting -+# The boot_counter env var can be used to count down boot attempts after an -+# OSTree upgrade and choose the rollback deployment when 0 is reached. Both -+# boot_counter and boot_success need to be (re-)set from userspace. -+cat << EOF -+insmod increment -+# Check if boot_counter exists and boot_success=0 to activate this behaviour. -+if [ -n "\${boot_counter}" -a "\${boot_success}" = "0" ]; then -+ # if countdown has ended, choose to boot rollback deployment (default=1 on -+ # OSTree-based systems) -+ if [ "\${boot_counter}" = "0" -o "\${boot_counter}" = "-1" ]; then -+ set default=1 -+ set boot_counter=-1 -+ # otherwise decrement boot_counter -+ else -+ decrement boot_counter -+ fi -+ save_env boot_counter -+fi -+EOF diff --git a/0112-Fix-menu-entry-selection-based-on-ID-and-title.patch b/0112-Fix-menu-entry-selection-based-on-ID-and-title.patch deleted file mode 100644 index 957fda3..0000000 --- a/0112-Fix-menu-entry-selection-based-on-ID-and-title.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 19 Oct 2018 10:57:52 -0400 -Subject: [PATCH] Fix menu entry selection based on ID and title - -Currently if grub_strtoul(saved_entry_value, NULL, 0) does not return an -error, we assume the value it has produced is a correct index into our -menu entry list, and do not try to interpret the value as the "id" or -"title" . In cases where "id" or "title" start with a numeral, this -makes them impossible to use as selection criteria. - -This patch splits the search into three phases - matching id, matching -title, and only once those have been exhausted, trying to interpret the -ID as a numeral. In that case, we also require that the entire string -is numeric, not merely a string with leading numeric characters. - -Resolves: rhbz#1640979 - -Signed-off-by: Peter Jones -[javierm: fix menu entry selection based on title] -Signed-off-by: Javier Martinez Canillas ---- - grub-core/normal/menu.c | 141 ++++++++++++++++++++++++------------------------ - 1 file changed, 71 insertions(+), 70 deletions(-) - -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index d7a222e681b..4a02aadb01c 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -164,12 +164,12 @@ grub_menu_set_timeout (int timeout) - } - - static int --menuentry_eq (const char *id, const char *spec) -+menuentry_eq (const char *id, const char *spec, int limit) - { - const char *ptr1, *ptr2; - ptr1 = id; - ptr2 = spec; -- while (1) -+ while (limit == -1 || ptr1 - id <= limit) - { - if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) - return ptr2 - spec; -@@ -178,7 +178,11 @@ menuentry_eq (const char *id, const char *spec) - if (*ptr2 == '>') - ptr2++; - if (*ptr1 != *ptr2) -- return 0; -+ { -+ if (limit > -1 && ptr1 - id == limit && !*ptr1 && grub_isspace(*ptr2)) -+ return ptr1 -id -1; -+ return 0; -+ } - if (*ptr1 == 0) - return ptr1 - id; - ptr1++; -@@ -187,6 +191,58 @@ menuentry_eq (const char *id, const char *spec) - return 0; - } - -+static int -+get_entry_number_helper(grub_menu_t menu, -+ const char * const val, const char ** const tail) -+{ -+ /* See if the variable matches the title of a menu entry. */ -+ int entry = -1; -+ grub_menu_entry_t e; -+ int i; -+ -+ for (i = 0, e = menu->entry_list; e; i++) -+ { -+ int l = 0; -+ while (val[l] && !grub_isspace(val[l])) -+ l++; -+ -+ if (menuentry_eq (e->id, val, l)) -+ { -+ if (tail) -+ *tail = val + l; -+ return i; -+ } -+ e = e->next; -+ } -+ -+ for (i = 0, e = menu->entry_list; e; i++) -+ { -+ -+ if (menuentry_eq (e->title, val, -1)) -+ { -+ if (tail) -+ *tail = NULL; -+ return i; -+ } -+ e = e->next; -+ } -+ -+ if (tail) -+ *tail = NULL; -+ -+ entry = (int) grub_strtoul (val, tail, 0); -+ if (grub_errno == GRUB_ERR_BAD_NUMBER || -+ (*tail && **tail && !grub_isspace(**tail))) -+ { -+ entry = -1; -+ if (tail) -+ *tail = NULL; -+ grub_errno = GRUB_ERR_NONE; -+ } -+ -+ return entry; -+} -+ - /* Get the first entry number from the value of the environment variable NAME, - which is a space-separated list of non-negative integers. The entry number - which is returned is stripped from the value of NAME. If no entry number -@@ -196,7 +252,6 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) - { - const char *val, *tail; - int entry; -- int sz = 0; - - val = grub_env_get (name); - if (! val) -@@ -204,50 +259,24 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) - - grub_error_push (); - -- entry = (int) grub_strtoul (val, &tail, 0); -+ entry = get_entry_number_helper(menu, val, &tail); -+ if (!(*tail == 0 || grub_isspace(*tail))) -+ entry = -1; - -- if (grub_errno == GRUB_ERR_BAD_NUMBER) -+ if (entry >= 0) - { -- /* See if the variable matches the title of a menu entry. */ -- grub_menu_entry_t e = menu->entry_list; -- int i; -- -- for (i = 0; e; i++) -- { -- sz = menuentry_eq (e->title, val); -- if (sz < 1) -- sz = menuentry_eq (e->id, val); -- -- if (sz >= 1) -- { -- entry = i; -- break; -- } -- e = e->next; -- } -- -- if (sz > 0) -- grub_errno = GRUB_ERR_NONE; -- -- if (! e) -- entry = -1; -- } -- -- if (grub_errno == GRUB_ERR_NONE) -- { -- if (sz > 0) -- tail += sz; -- - /* Skip whitespace to find the next entry. */ - while (*tail && grub_isspace (*tail)) - tail++; -- grub_env_set (name, tail); -+ if (*tail) -+ grub_env_set (name, tail); -+ else -+ grub_env_unset (name); - } - else - { - grub_env_unset (name); - grub_errno = GRUB_ERR_NONE; -- entry = -1; - } - - grub_error_pop (); -@@ -524,6 +553,7 @@ static int - get_entry_number (grub_menu_t menu, const char *name) - { - const char *val; -+ const char *tail; - int entry; - - val = grub_env_get (name); -@@ -531,38 +561,9 @@ get_entry_number (grub_menu_t menu, const char *name) - return -1; - - grub_error_push (); -- -- entry = (int) grub_strtoul (val, 0, 0); -- -- if (grub_errno == GRUB_ERR_BAD_NUMBER) -- { -- /* See if the variable matches the title of a menu entry. */ -- grub_menu_entry_t e = menu->entry_list; -- int i; -- -- grub_errno = GRUB_ERR_NONE; -- -- for (i = 0; e; i++) -- { -- if (menuentry_eq (e->title, val) -- || menuentry_eq (e->id, val)) -- { -- entry = i; -- break; -- } -- e = e->next; -- } -- -- if (! e) -- entry = -1; -- } -- -- if (grub_errno != GRUB_ERR_NONE) -- { -- grub_errno = GRUB_ERR_NONE; -- entry = -1; -- } -- -+ entry = get_entry_number_helper(menu, val, &tail); -+ if (tail && *tail != '\0') -+ entry = -1; - grub_error_pop (); - - return entry; diff --git a/0113-Make-the-menu-entry-users-option-argument-to-be-opti.patch b/0113-Make-the-menu-entry-users-option-argument-to-be-opti.patch deleted file mode 100644 index e0d36db..0000000 --- a/0113-Make-the-menu-entry-users-option-argument-to-be-opti.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 26 Nov 2018 10:06:42 +0100 -Subject: [PATCH] Make the menu entry users option argument to be optional - -The --users option is used to restrict the access to specific menu entries -only to a set of users. But the option requires an argument to either be a -constant or a variable that has been set. So for example the following: - - menuentry "May be run by superusers or users in $users" --users $users { - linux /vmlinuz - } - -Would fail if $users is not defined and grub would discard the menu entry. -Instead, allow the --users option to have an optional argument and ignore -the option if the argument was not set. - -Related: rhbz#1652434 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/commands/menuentry.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c -index b194123eb67..b175a1b43b7 100644 ---- a/grub-core/commands/menuentry.c -+++ b/grub-core/commands/menuentry.c -@@ -29,7 +29,7 @@ static const struct grub_arg_option options[] = - { - {"class", 1, GRUB_ARG_OPTION_REPEATABLE, - N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING}, -- {"users", 2, 0, -+ {"users", 2, GRUB_ARG_OPTION_OPTIONAL, - N_("List of users allowed to boot this entry."), N_("USERNAME[,USERNAME]"), - ARG_TYPE_STRING}, - {"hotkey", 3, 0, -@@ -281,7 +281,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) - if (! ctxt->state[3].set && ! ctxt->script) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition"); - -- if (ctxt->state[1].set) -+ if (ctxt->state[1].set && ctxt->state[1].arg) - users = ctxt->state[1].arg; - else if (ctxt->state[5].set) - users = NULL; diff --git a/0114-Add-efi-export-env-and-efi-load-env-commands.patch b/0114-Add-efi-export-env-and-efi-load-env-commands.patch deleted file mode 100644 index 73456bc..0000000 --- a/0114-Add-efi-export-env-and-efi-load-env-commands.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 16 Jan 2019 13:21:46 -0500 -Subject: [PATCH] Add efi-export-env and efi-load-env commands - -This adds "efi-export-env VARIABLE" and "efi-load-env", which manipulate the -environment block stored in the EFI variable -GRUB_ENV-91376aff-cba6-42be-949d-06fde81128e8. - -Signed-off-by: Peter Jones ---- - grub-core/Makefile.core.def | 6 ++ - grub-core/commands/efi/env.c | 168 +++++++++++++++++++++++++++++++++++++++++++ - grub-core/kern/efi/efi.c | 3 + - grub-core/kern/efi/init.c | 5 -- - grub-core/lib/envblk.c | 43 +++++++++++ - util/grub-set-bootflag.c | 1 + - include/grub/efi/efi.h | 5 ++ - include/grub/lib/envblk.h | 3 + - 8 files changed, 229 insertions(+), 5 deletions(-) - create mode 100644 grub-core/commands/efi/env.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 1e15345107e..81fc274148e 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -820,6 +820,12 @@ module = { - enable = efi; - }; - -+module = { -+ name = efienv; -+ common = commands/efi/env.c; -+ enable = efi; -+}; -+ - module = { - name = efifwsetup; - efi = commands/efi/efifwsetup.c; -diff --git a/grub-core/commands/efi/env.c b/grub-core/commands/efi/env.c -new file mode 100644 -index 00000000000..cbd13e03e81 ---- /dev/null -+++ b/grub-core/commands/efi/env.c -@@ -0,0 +1,168 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2012 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static const grub_efi_guid_t grub_env_guid = GRUB_EFI_GRUB_VARIABLE_GUID; -+ -+static grub_err_t -+grub_efi_export_env(grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ const char *value; -+ char *old_value; -+ struct grub_envblk envblk_s = { NULL, 0 }; -+ grub_envblk_t envblk = &envblk_s; -+ grub_err_t err; -+ int changed = 1; -+ grub_efi_status_t status; -+ -+ grub_dprintf ("efienv", "argc:%d\n", argc); -+ for (int i = 0; i < argc; i++) -+ grub_dprintf ("efienv", "argv[%d]: %s\n", i, argv[i]); -+ -+ if (argc != 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable name expected")); -+ -+ grub_efi_get_variable ("GRUB_ENV", &grub_env_guid, &envblk_s.size, -+ (void **) &envblk_s.buf); -+ if (!envblk_s.buf || envblk_s.size < 1) -+ { -+ char *buf = grub_malloc (1025); -+ if (!buf) -+ return grub_errno; -+ -+ grub_memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); -+ grub_memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', -+ DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); -+ buf[1024] = '\0'; -+ -+ envblk_s.buf = buf; -+ envblk_s.size = 1024; -+ } -+ else -+ { -+ char *buf = grub_realloc (envblk_s.buf, envblk_s.size + 1); -+ if (!buf) -+ return grub_errno; -+ -+ envblk_s.buf = buf; -+ envblk_s.buf[envblk_s.size] = '\0'; -+ } -+ -+ err = grub_envblk_get(envblk, argv[0], &old_value); -+ if (err != GRUB_ERR_NONE) -+ { -+ grub_dprintf ("efienv", "grub_envblk_get returned %d\n", err); -+ return err; -+ } -+ -+ value = grub_env_get(argv[0]); -+ if ((!value && !old_value) || -+ (value && old_value && !grub_strcmp(old_value, value))) -+ changed = 0; -+ -+ if (old_value) -+ grub_free(old_value); -+ -+ if (changed == 0) -+ { -+ grub_dprintf ("efienv", "No changes necessary\n"); -+ return 0; -+ } -+ -+ if (value) -+ { -+ grub_dprintf ("efienv", "setting \"%s\" to \"%s\"\n", argv[0], value); -+ grub_envblk_set(envblk, argv[0], value); -+ } -+ else -+ { -+ grub_dprintf ("efienv", "deleting \"%s\" from envblk\n", argv[0]); -+ grub_envblk_delete(envblk, argv[0]); -+ } -+ -+ grub_dprintf ("efienv", "envblk is %lu bytes:\n\"%s\"\n", envblk_s.size, envblk_s.buf); -+ -+ grub_dprintf ("efienv", "removing GRUB_ENV\n"); -+ status = grub_efi_set_variable ("GRUB_ENV", &grub_env_guid, NULL, 0); -+ if (status != GRUB_EFI_SUCCESS) -+ grub_dprintf ("efienv", "removal returned %ld\n", status); -+ -+ grub_dprintf ("efienv", "setting GRUB_ENV\n"); -+ status = grub_efi_set_variable ("GRUB_ENV", &grub_env_guid, -+ envblk_s.buf, envblk_s.size); -+ if (status != GRUB_EFI_SUCCESS) -+ grub_dprintf ("efienv", "setting GRUB_ENV returned %ld\n", status); -+ -+ return 0; -+} -+ -+static int -+set_var (const char *name, const char *value, -+ void *whitelist __attribute__((__unused__))) -+{ -+ grub_env_set (name, value); -+ return 0; -+} -+ -+static grub_err_t -+grub_efi_load_env(grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[] __attribute__((__unused__))) -+{ -+ struct grub_envblk envblk_s = { NULL, 0 }; -+ grub_envblk_t envblk = &envblk_s; -+ -+ grub_efi_get_variable ("GRUB_ENV", &grub_env_guid, &envblk_s.size, -+ (void **) &envblk_s.buf); -+ if (!envblk_s.buf || envblk_s.size < 1) -+ return 0; -+ -+ if (argc > 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected argument")); -+ -+ grub_envblk_iterate (envblk, NULL, set_var); -+ grub_free (envblk_s.buf); -+} -+ -+static grub_command_t export_cmd, loadenv_cmd; -+ -+GRUB_MOD_INIT(lsefi) -+{ -+ export_cmd = grub_register_command ("efi-export-env", grub_efi_export_env, -+ N_("VARIABLE_NAME"), N_("Export environment variable to UEFI.")); -+ loadenv_cmd = grub_register_command ("efi-load-env", grub_efi_load_env, -+ NULL, N_("Load the grub environment from UEFI.")); -+} -+ -+GRUB_MOD_FINI(lsefi) -+{ -+ grub_unregister_command (export_cmd); -+ grub_unregister_command (loadenv_cmd); -+} -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 2a446f5031b..14bc10eb564 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -225,6 +225,9 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, - if (status == GRUB_EFI_SUCCESS) - return GRUB_ERR_NONE; - -+ if (status == GRUB_EFI_NOT_FOUND && datasize == 0) -+ return GRUB_ERR_NONE; -+ - return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); - } - -diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c -index 2d12e6188fd..0574d8d6217 100644 ---- a/grub-core/kern/efi/init.c -+++ b/grub-core/kern/efi/init.c -@@ -85,11 +85,6 @@ stack_protector_init (void) - - grub_addr_t grub_modbase; - --#define GRUB_EFI_GRUB_VARIABLE_GUID \ -- { 0x91376aff, 0xcba6, 0x42be, \ -- { 0x94, 0x9d, 0x06, 0xfd, 0xe8, 0x11, 0x28, 0xe8 } \ -- } -- - /* Helper for grub_efi_env_init */ - static int - set_var (const char *name, const char *value, -diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c -index 2e4e78b132d..874506da169 100644 ---- a/grub-core/lib/envblk.c -+++ b/grub-core/lib/envblk.c -@@ -223,6 +223,49 @@ grub_envblk_delete (grub_envblk_t envblk, const char *name) - } - } - -+struct get_var_state { -+ const char * const name; -+ char * value; -+ int found; -+}; -+ -+static int -+get_var (const char * const name, const char * const value, void *statep) -+{ -+ struct get_var_state *state = (struct get_var_state *)statep; -+ -+ if (!grub_strcmp(state->name, name)) -+ { -+ state->found = 1; -+ state->value = grub_strdup(value); -+ if (!state->value) -+ grub_errno = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+grub_err_t -+grub_envblk_get (grub_envblk_t envblk, const char * const name, char ** const value) -+{ -+ struct get_var_state state = { -+ .name = name, -+ .value = NULL, -+ .found = 0, -+ }; -+ -+ grub_envblk_iterate(envblk, (void *)&state, get_var); -+ -+ *value = state.value; -+ -+ if (state.found && !state.value) -+ return grub_errno; -+ -+ return GRUB_ERR_NONE; -+} -+ - void - grub_envblk_iterate (grub_envblk_t envblk, - void *hook_data, -diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c -index bb198f02351..6a79ee67444 100644 ---- a/util/grub-set-bootflag.c -+++ b/util/grub-set-bootflag.c -@@ -25,6 +25,7 @@ - - #include /* For *_DIR_NAME defines */ - #include -+#include - #include /* For GRUB_ENVBLK_DEFCFG define */ - #include - #include -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 2e0691454b1..8dfc89a33b9 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -24,6 +24,11 @@ - #include - #include - -+#define GRUB_EFI_GRUB_VARIABLE_GUID \ -+ { 0x91376aff, 0xcba6, 0x42be, \ -+ { 0x94, 0x9d, 0x06, 0xfd, 0xe8, 0x11, 0x28, 0xe8 } \ -+ } -+ - /* Variables. */ - extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); - extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); -diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h -index c3e65592170..ab969af2461 100644 ---- a/include/grub/lib/envblk.h -+++ b/include/grub/lib/envblk.h -@@ -22,6 +22,8 @@ - #define GRUB_ENVBLK_SIGNATURE "# GRUB Environment Block\n" - #define GRUB_ENVBLK_DEFCFG "grubenv" - -+#define DEFAULT_ENVBLK_SIZE 1024 -+ - #ifndef ASM_FILE - - struct grub_envblk -@@ -33,6 +35,7 @@ typedef struct grub_envblk *grub_envblk_t; - - grub_envblk_t grub_envblk_open (char *buf, grub_size_t size); - int grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value); -+grub_err_t grub_envblk_get (grub_envblk_t envblk, const char * const name, char ** const value); - void grub_envblk_delete (grub_envblk_t envblk, const char *name); - void grub_envblk_iterate (grub_envblk_t envblk, - void *hook_data, diff --git a/0115-Make-it-possible-to-subtract-conditions-from-debug.patch b/0115-Make-it-possible-to-subtract-conditions-from-debug.patch deleted file mode 100644 index fce51ea..0000000 --- a/0115-Make-it-possible-to-subtract-conditions-from-debug.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 17 Jan 2019 13:10:39 -0500 -Subject: [PATCH] Make it possible to subtract conditions from debug= - -This makes it so you can do set debug to "all,-scripting,-lexer" and get the -obvious outcome. Any negation present will take preference over that -conditional, so "all,-scripting,scripting" is the same thing as -"all,-scripting". - -Signed-off-by: Peter Jones ---- - grub-core/kern/misc.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 9a2fae6398e..578bf51a5fc 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -164,12 +164,24 @@ int - grub_debug_enabled (const char * condition) - { - const char *debug; -+ char *negcond; -+ int negated = 0; - - debug = grub_env_get ("debug"); - if (!debug) - return 0; - -- if (grub_strword (debug, "all") || grub_strword (debug, condition)) -+ negcond = grub_zalloc (grub_strlen (condition) + 2); -+ if (negcond) -+ { -+ grub_strcpy (negcond, "-"); -+ grub_strcpy (negcond+1, condition); -+ negated = grub_strword (debug, negcond); -+ grub_free (negcond); -+ } -+ -+ if (!negated && -+ (grub_strword (debug, "all") || grub_strword (debug, condition))) - return 1; - - return 0; diff --git a/0116-Export-all-variables-from-the-initial-context-when-c.patch b/0116-Export-all-variables-from-the-initial-context-when-c.patch deleted file mode 100644 index 4e32260..0000000 --- a/0116-Export-all-variables-from-the-initial-context-when-c.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 22 Jan 2019 15:40:25 +0100 -Subject: [PATCH] Export all variables from the initial context when creating a - submenu - -When a submenu is created, only the exported variables are copied to the -new menu context. But we want the variables to be global, so export lets -export all variables to the new created submenu. - -Also, don't unset the default variable when a new submenu is created. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/normal/context.c | 2 +- - grub-core/normal/menu.c | 2 -- - 2 files changed, 1 insertion(+), 3 deletions(-) - -diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c -index ee53d4a68e5..87edd254c44 100644 ---- a/grub-core/normal/context.c -+++ b/grub-core/normal/context.c -@@ -99,7 +99,7 @@ grub_env_new_context (int export_all) - grub_err_t - grub_env_context_open (void) - { -- return grub_env_new_context (0); -+ return grub_env_new_context (1); - } - - int grub_extractor_level = 0; -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index 4a02aadb01c..fe2e77a43e2 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -375,8 +375,6 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - - if (ptr && ptr[0] && ptr[1]) - grub_env_set ("default", ptr + 1); -- else -- grub_env_unset ("default"); - - grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args); - diff --git a/0117-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch b/0117-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch deleted file mode 100644 index 92f259d..0000000 --- a/0117-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Christian Glombek -Date: Tue, 2 Apr 2019 16:22:21 +0200 -Subject: [PATCH] grub.d: Split out boot success reset from menu auto hide - script - -Also rename fallback and menu auto hide script to be executed -before and after boot success reset script. -In menu auto hide script, rename last_boot_ok var to menu_hide_ok - -Signed-off-by: Christian Glombek -Signed-off-by: Robbie Harwood ---- - Makefile.util.def | 14 ++++++++---- - ...allback_counting.in => 08_fallback_counting.in} | 14 ++++++------ - util/grub.d/10_reset_boot_success.in | 25 ++++++++++++++++++++++ - .../{01_menu_auto_hide.in => 12_menu_auto_hide.in} | 23 +++++--------------- - 4 files changed, 48 insertions(+), 28 deletions(-) - rename util/grub.d/{01_fallback_counting.in => 08_fallback_counting.in} (65%) - create mode 100644 util/grub.d/10_reset_boot_success.in - rename util/grub.d/{01_menu_auto_hide.in => 12_menu_auto_hide.in} (58%) - -diff --git a/Makefile.util.def b/Makefile.util.def -index 27a13bc734e..2e6ad979c3e 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -459,14 +459,14 @@ script = { - }; - - script = { -- name = '01_fallback_counting'; -- common = util/grub.d/01_fallback_counting.in; -+ name = '08_fallback_counting'; -+ common = util/grub.d/08_fallback_counting.in; - installdir = grubconf; - }; - - script = { -- name = '01_menu_auto_hide'; -- common = util/grub.d/01_menu_auto_hide.in; -+ name = '12_menu_auto_hide'; -+ common = util/grub.d/12_menu_auto_hide.in; - installdir = grubconf; - }; - -@@ -518,6 +518,12 @@ script = { - condition = COND_HOST_LINUX; - }; - -+script = { -+ name = '10_reset_boot_success'; -+ common = util/grub.d/10_reset_boot_success.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '10_xnu'; - common = util/grub.d/10_xnu.in; -diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/08_fallback_counting.in -similarity index 65% -rename from util/grub.d/01_fallback_counting.in -rename to util/grub.d/08_fallback_counting.in -index be0e770ea82..2e2c3ff7d31 100644 ---- a/util/grub.d/01_fallback_counting.in -+++ b/util/grub.d/08_fallback_counting.in -@@ -1,15 +1,17 @@ - #! /bin/sh -e -- --# Boot Counting -+# Fallback Countdown -+# -+# This snippet depends on 10_reset_boot_success and needs to be kept in sync. -+# - # The boot_counter env var can be used to count down boot attempts after an --# OSTree upgrade and choose the rollback deployment when 0 is reached. Both --# boot_counter and boot_success need to be (re-)set from userspace. -+# OSTree upgrade and choose the rollback deployment when 0 is reached. -+# Both boot_counter=X and boot_success=1 need to be set from userspace. - cat << EOF - insmod increment - # Check if boot_counter exists and boot_success=0 to activate this behaviour. - if [ -n "\${boot_counter}" -a "\${boot_success}" = "0" ]; then -- # if countdown has ended, choose to boot rollback deployment (default=1 on -- # OSTree-based systems) -+ # if countdown has ended, choose to boot rollback deployment, -+ # i.e. default=1 on OSTree-based systems. - if [ "\${boot_counter}" = "0" -o "\${boot_counter}" = "-1" ]; then - set default=1 - set boot_counter=-1 -diff --git a/util/grub.d/10_reset_boot_success.in b/util/grub.d/10_reset_boot_success.in -new file mode 100644 -index 00000000000..6c88d933dde ---- /dev/null -+++ b/util/grub.d/10_reset_boot_success.in -@@ -0,0 +1,25 @@ -+#! /bin/sh -e -+# Reset Boot Success -+# -+# The 08_fallback_counting and 12_menu_auto_hide snippets rely on this one -+# and need to be kept in sync. -+# -+# The boot_success var needs to be set to 1 from userspace to mark a boot successful. -+cat << EOF -+insmod increment -+# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry -+if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then -+ set menu_hide_ok=1 -+else -+ set menu_hide_ok=0 -+fi -+# Reset boot_indeterminate after a successful boot, increment otherwise -+if [ "\${boot_success}" = "1" ] ; then -+ set boot_indeterminate=0 -+else -+ increment boot_indeterminate -+fi -+# Reset boot_success for current boot -+set boot_success=0 -+save_env boot_success boot_indeterminate -+EOF -diff --git a/util/grub.d/01_menu_auto_hide.in b/util/grub.d/12_menu_auto_hide.in -similarity index 58% -rename from util/grub.d/01_menu_auto_hide.in -rename to util/grub.d/12_menu_auto_hide.in -index ad175870a54..6a7c0fa0d43 100644 ---- a/util/grub.d/01_menu_auto_hide.in -+++ b/util/grub.d/12_menu_auto_hide.in -@@ -1,5 +1,8 @@ - #! /bin/sh -- -+# Menu Auto Hide -+# -+# This snippet depends on 10_reset_boot_success and needs to be kept in sync. -+# - # Disable / skip generating menu-auto-hide config parts on serial terminals - for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do - case "$x" in -@@ -10,29 +13,13 @@ for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do - done - - cat << EOF --if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then -- set last_boot_ok=1 --else -- set last_boot_ok=0 --fi -- --# Reset boot_indeterminate after a successful boot --if [ "\${boot_success}" = "1" ] ; then -- set boot_indeterminate=0 --# Avoid boot_indeterminate causing the menu to be hidden more then once --elif [ "\${boot_indeterminate}" = "1" ]; then -- set boot_indeterminate=2 --fi --set boot_success=0 --save_env boot_success boot_indeterminate -- - if [ x\$feature_timeout_style = xy ] ; then - if [ "\${menu_show_once}" ]; then - unset menu_show_once - save_env menu_show_once - set timeout_style=menu - set timeout=60 -- elif [ "\${menu_auto_hide}" -a "\${last_boot_ok}" = "1" ]; then -+ elif [ "\${menu_auto_hide}" -a "\${menu_hide_ok}" = "1" ]; then - set orig_timeout_style=\${timeout_style} - set orig_timeout=\${timeout} - if [ "\${fastboot}" = "1" ]; then diff --git a/0118-Fix-systemctl-kexec-exit-status-check.patch b/0118-Fix-systemctl-kexec-exit-status-check.patch deleted file mode 100644 index 74ecedc..0000000 --- a/0118-Fix-systemctl-kexec-exit-status-check.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 9 Apr 2019 12:30:38 +0200 -Subject: [PATCH] Fix systemctl kexec exit status check - -There's always an error printed even when the systemctl kexec command does -succeed. That's because systemctl executes it asynchronously, but the emu -loader seems to expect it to be synchronous and that should never return. - -Also, it's wrong to test if kexecute == 1 since we already know that's the -case or otherwise the function wouldn't had called grub_fatal() earlier. - -Finally, systemctl kexec failing shouldn't be a fatal error since the emu -loader fallbacks to executing the kexec command in case of a failure. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/loader/emu/linux.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c -index fda9e00d24c..5b85b225eed 100644 ---- a/grub-core/loader/emu/linux.c -+++ b/grub-core/loader/emu/linux.c -@@ -71,8 +71,10 @@ grub_linux_boot (void) - (kexecute==1) ? "do-or-die" : "just-in-case"); - rc = grub_util_exec (systemctl); - -- if (kexecute == 1) -- grub_fatal (N_("Error trying to perform 'systemctl kexec'")); -+ if (rc == GRUB_ERR_NONE) -+ return rc; -+ -+ grub_error (rc, N_("Error trying to perform 'systemctl kexec'")); - - /* need to check read-only root before resetting hard!? */ - grub_printf("Performing 'kexec -e'"); diff --git a/0119-Print-grub-emu-linux-loader-messages-as-debug.patch b/0119-Print-grub-emu-linux-loader-messages-as-debug.patch deleted file mode 100644 index a49ec44..0000000 --- a/0119-Print-grub-emu-linux-loader-messages-as-debug.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 9 Apr 2019 12:42:37 +0200 -Subject: [PATCH] Print grub-emu linux loader messages as debug - -They just polute the output and should better be debug messages instead. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/loader/emu/linux.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c -index 5b85b225eed..22ab6af1727 100644 ---- a/grub-core/loader/emu/linux.c -+++ b/grub-core/loader/emu/linux.c -@@ -50,7 +50,7 @@ grub_linux_boot (void) - initrd_param = grub_xasprintf("%s", ""); - } - -- grub_printf("%serforming 'kexec -l %s %s %s'\n", -+ grub_dprintf ("linux", "%serforming 'kexec -l %s %s %s'\n", - (kexecute) ? "P" : "Not p", - kernel_path, initrd_param, boot_cmdline); - -@@ -67,7 +67,7 @@ grub_linux_boot (void) - if (kexecute < 1) - grub_fatal (N_("Use '"PACKAGE"-emu --kexec' to force a system restart.")); - -- grub_printf("Performing 'systemctl kexec' (%s) ", -+ grub_dprintf ("linux", "Performing 'systemctl kexec' (%s) ", - (kexecute==1) ? "do-or-die" : "just-in-case"); - rc = grub_util_exec (systemctl); - diff --git a/0120-Don-t-assume-that-boot-commands-will-only-return-on-.patch b/0120-Don-t-assume-that-boot-commands-will-only-return-on-.patch deleted file mode 100644 index bd7b2c1..0000000 --- a/0120-Don-t-assume-that-boot-commands-will-only-return-on-.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 9 Apr 2019 13:12:40 +0200 -Subject: [PATCH] Don't assume that boot commands will only return on fail - -While it's true that for most loaders the boot command never returns, it -may be the case that it does. For example the GRUB emulator boot command -calls to systemctl kexec which in turn does an asynchonous call to kexec. - -So in this case GRUB will wrongly assume that the boot command fails and -print a "Failed to boot both default and fallback entries" even when the -kexec call later succeeds. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/normal/menu.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index fe2e77a43e2..ec0c92bade0 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -285,7 +285,7 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) - } - - /* Run a menu entry. */ --static void -+static grub_err_t - grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - { - grub_err_t err = GRUB_ERR_NONE; -@@ -302,7 +302,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; -- return; -+ return grub_errno; - } - - errs_before = grub_err_printed_errors; -@@ -315,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - grub_env_context_open (); - menu = grub_zalloc (sizeof (*menu)); - if (! menu) -- return; -+ return grub_errno; - grub_env_set_menu (menu); - if (auto_boot) - grub_env_set ("timeout", "0"); -@@ -385,7 +385,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - - if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) - /* Implicit execution of boot, only if something is loaded. */ -- grub_command_execute ("boot", 0, 0); -+ err = grub_command_execute ("boot", 0, 0); - - if (errs_before != grub_err_printed_errors) - grub_wait_after_message (); -@@ -408,6 +408,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - else - grub_env_unset ("default"); - grub_env_unset ("timeout"); -+ -+ return err; - } - - /* Execute ENTRY from the menu MENU, falling back to entries specified -@@ -422,10 +424,13 @@ grub_menu_execute_with_fallback (grub_menu_t menu, - void *callback_data) - { - int fallback_entry; -+ grub_err_t err; - - callback->notify_booting (entry, callback_data); - -- grub_menu_execute_entry (entry, 1); -+ err = grub_menu_execute_entry (entry, 1); -+ if (err == GRUB_ERR_NONE) -+ return; - - /* Deal with fallback entries. */ - while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback")) -@@ -436,11 +441,9 @@ grub_menu_execute_with_fallback (grub_menu_t menu, - - entry = grub_menu_get_entry (menu, fallback_entry); - callback->notify_fallback (entry, callback_data); -- grub_menu_execute_entry (entry, 1); -- /* If the function call to execute the entry returns at all, then this is -- taken to indicate a boot failure. For menu entries that do something -- other than actually boot an operating system, this could assume -- incorrectly that something failed. */ -+ err = grub_menu_execute_entry (entry, 1); -+ if (err == GRUB_ERR_NONE) -+ return; - } - - if (!autobooted) diff --git a/0121-Do-better-in-bootstrap.conf.patch b/0121-Do-better-in-bootstrap.conf.patch deleted file mode 100644 index ec9d8ec..0000000 --- a/0121-Do-better-in-bootstrap.conf.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 29 Jul 2019 10:58:52 -0400 -Subject: [PATCH] Do better in bootstrap.conf - ---- - bootstrap.conf | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/bootstrap.conf b/bootstrap.conf -index 186be9c48ce..9259526e891 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -16,7 +16,13 @@ - # along with this program. If not, see . - - --GNULIB_REVISION=d271f868a8df9bbec29049d01e056481b7a1a263 -+# GNULIB_REVISION=d271f868a8df9bbec29049d01e056481b7a1a263 -+if [[ -z "${GNULIB_REVISION}" ]] ;then -+ GNULIB_REVISION=fixes -+fi -+if [[ -z "${GNULIB_URL}" ]] ;then -+ GNULIB_URL=https://github.com/rhboot/gnulib.git -+fi - - # gnulib modules used by this package. - # mbswidth is used by gnulib-fix-width.diff's changes to argp rather than diff --git a/0122-Use-git-to-apply-gnulib-patches.patch b/0122-Use-git-to-apply-gnulib-patches.patch deleted file mode 100644 index 7654648..0000000 --- a/0122-Use-git-to-apply-gnulib-patches.patch +++ /dev/null @@ -1,631 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 29 Jul 2019 11:21:27 -0400 -Subject: [PATCH] Use git to apply gnulib patches. - -Signed-off-by: Peter Jones ---- - bootstrap.conf | 6 - - conf/Makefile.extra-dist | 10 - - grub-core/lib/gnulib-patches/fix-base64.patch | 21 -- - grub-core/lib/gnulib-patches/fix-null-deref.patch | 13 -- - .../lib/gnulib-patches/fix-null-state-deref.patch | 12 -- - .../gnulib-patches/fix-regcomp-uninit-token.patch | 15 -- - .../gnulib-patches/fix-regexec-null-deref.patch | 12 -- - .../gnulib-patches/fix-sign-compare-errors.patch | 161 --------------- - .../lib/gnulib-patches/fix-uninit-structure.patch | 11 -- - .../lib/gnulib-patches/fix-unused-value.patch | 14 -- - grub-core/lib/gnulib-patches/fix-width.patch | 217 --------------------- - grub-core/lib/gnulib-patches/no-abort.patch | 26 --- - 12 files changed, 518 deletions(-) - delete mode 100644 grub-core/lib/gnulib-patches/fix-base64.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-null-deref.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-null-state-deref.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-sign-compare-errors.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-uninit-structure.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-unused-value.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-width.patch - delete mode 100644 grub-core/lib/gnulib-patches/no-abort.patch - -diff --git a/bootstrap.conf b/bootstrap.conf -index 9259526e891..452f4d79b0d 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -85,12 +85,6 @@ cp -a INSTALL INSTALL.grub - - bootstrap_post_import_hook () { - set -e -- for patchname in fix-base64 fix-null-deref fix-null-state-deref fix-regcomp-uninit-token \ -- fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width no-abort \ -- fix-sign-compare-errors; do -- patch -d grub-core/lib/gnulib -p2 \ -- < "grub-core/lib/gnulib-patches/$patchname.patch" -- done - for patchname in \ - 0001-Support-POTFILES-shell \ - 0002-Handle-gettext_printf-shell-function \ -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index ea58362b555..8ddf22e6c99 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -30,16 +30,6 @@ EXTRA_DIST += grub-core/gensymlist.sh - EXTRA_DIST += grub-core/genemuinit.sh - EXTRA_DIST += grub-core/genemuinitheader.sh - --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-base64.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-deref.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-state-deref.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-uninit-structure.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-unused-value.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/no-abort.patch -- - EXTRA_DIST += grub-core/lib/libgcrypt - EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic - EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') -diff --git a/grub-core/lib/gnulib-patches/fix-base64.patch b/grub-core/lib/gnulib-patches/fix-base64.patch -deleted file mode 100644 -index 985db127971..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-base64.patch -+++ /dev/null -@@ -1,21 +0,0 @@ --diff --git a/lib/base64.h b/lib/base64.h --index 9cd0183b8..185a2afa1 100644 ----- a/lib/base64.h --+++ b/lib/base64.h --@@ -21,8 +21,14 @@ -- /* Get size_t. */ -- # include -- ---/* Get bool. */ ---# include --+#ifndef GRUB_POSIX_BOOL_DEFINED --+typedef enum { false = 0, true = 1 } bool; --+#define GRUB_POSIX_BOOL_DEFINED 1 --+#endif --+ --+#ifndef _GL_ATTRIBUTE_CONST --+# define _GL_ATTRIBUTE_CONST /* empty */ --+#endif -- -- # ifdef __cplusplus -- extern "C" { -diff --git a/grub-core/lib/gnulib-patches/fix-null-deref.patch b/grub-core/lib/gnulib-patches/fix-null-deref.patch -deleted file mode 100644 -index 8fafa153a47..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-null-deref.patch -+++ /dev/null -@@ -1,13 +0,0 @@ --diff --git a/lib/argp-parse.c b/lib/argp-parse.c --index 6dec57310..900adad54 100644 ----- a/lib/argp-parse.c --+++ b/lib/argp-parse.c --@@ -940,7 +940,7 @@ weak_alias (__argp_parse, argp_parse) -- void * -- __argp_input (const struct argp *argp, const struct argp_state *state) -- { --- if (state) --+ if (state && state->pstate) -- { -- struct group *group; -- struct parser *parser = state->pstate; -diff --git a/grub-core/lib/gnulib-patches/fix-null-state-deref.patch b/grub-core/lib/gnulib-patches/fix-null-state-deref.patch -deleted file mode 100644 -index 813ec09c8a1..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-null-state-deref.patch -+++ /dev/null -@@ -1,12 +0,0 @@ ----- a/lib/argp-help.c 2020-10-28 14:32:19.189215988 +0000 --+++ b/lib/argp-help.c 2020-10-28 14:38:21.204673940 +0000 --@@ -145,7 +145,8 @@ -- if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) -- { -- __argp_failure (state, 0, 0, --- dgettext (state->root_argp->argp_domain, --+ dgettext (state == NULL ? NULL --+ : state->root_argp->argp_domain, -- "\ -- ARGP_HELP_FMT: %s value is less than or equal to %s"), -- "rmargin", up->name); -diff --git a/grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch b/grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch -deleted file mode 100644 -index 02e06315dff..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch -+++ /dev/null -@@ -1,15 +0,0 @@ ----- a/lib/regcomp.c 2020-11-24 17:06:08.159223858 +0000 --+++ b/lib/regcomp.c 2020-11-24 17:06:15.630253923 +0000 --@@ -3808,11 +3808,7 @@ -- create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, -- re_token_type_t type) -- { --- re_token_t t; ---#if defined GCC_LINT || defined lint --- memset (&t, 0, sizeof t); ---#endif --- t.type = type; --+ re_token_t t = { .type = type }; -- return create_token_tree (dfa, left, right, &t); -- } -- -diff --git a/grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch b/grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch -deleted file mode 100644 -index db6dac9c9e3..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch -+++ /dev/null -@@ -1,12 +0,0 @@ ----- a/lib/regexec.c 2020-10-21 14:25:35.310195912 +0000 --+++ b/lib/regexec.c 2020-11-05 10:55:09.621542984 +0000 --@@ -1692,6 +1692,9 @@ -- { -- Idx top = mctx->state_log_top; -- --+ if (mctx->state_log == NULL) --+ return REG_NOERROR; --+ -- if ((next_state_log_idx >= mctx->input.bufs_len -- && mctx->input.bufs_len < mctx->input.len) -- || (next_state_log_idx >= mctx->input.valid_len -diff --git a/grub-core/lib/gnulib-patches/fix-sign-compare-errors.patch b/grub-core/lib/gnulib-patches/fix-sign-compare-errors.patch -deleted file mode 100644 -index 479029c0565..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-sign-compare-errors.patch -+++ /dev/null -@@ -1,161 +0,0 @@ --diff --git a/lib/regcomp.c b/lib/regcomp.c --index cc85f35ac58..361079d82d6 100644 ----- a/lib/regcomp.c --+++ b/lib/regcomp.c --@@ -322,7 +322,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, -- *p++ = dfa->nodes[node].opr.c; -- memset (&state, '\0', sizeof (state)); -- if (__mbrtowc (&wc, (const char *) buf, p - buf, --- &state) == p - buf --+ &state) == (size_t)(p - buf) -- && (__wcrtomb ((char *) buf, __towlower (wc), &state) -- != (size_t) -1)) -- re_set_fastmap (fastmap, false, buf[0]); --@@ -3778,7 +3778,7 @@ fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) -- num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2) -- ? -2 -- : num == -1 --- ? c - '0' --+ ? (Idx)(c - '0') -- : MIN (RE_DUP_MAX + 1, num * 10 + c - '0')); -- } -- return num; --diff --git a/lib/regex_internal.c b/lib/regex_internal.c --index 9004ce809eb..193a1e3d332 100644 ----- a/lib/regex_internal.c --+++ b/lib/regex_internal.c --@@ -233,7 +233,7 @@ build_wcs_buffer (re_string_t *pstr) -- /* Apply the translation if we need. */ -- if (__glibc_unlikely (pstr->trans != NULL)) -- { --- int i, ch; --+ unsigned int i, ch; -- -- for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) -- { --@@ -376,7 +376,7 @@ build_wcs_upper_buffer (re_string_t *pstr) -- prev_st = pstr->cur_state; -- if (__glibc_unlikely (pstr->trans != NULL)) -- { --- int i, ch; --+ unsigned int i, ch; -- -- for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) -- { --@@ -754,7 +754,7 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags) -- memset (&cur_state, 0, sizeof (cur_state)); -- mbclen = __mbrtowc (&wc2, (const char *) pp, mlen, -- &cur_state); --- if (raw + offset - p <= mbclen --+ if ((size_t)(raw + offset - p) <= mbclen -- && mbclen < (size_t) -2) -- { -- memset (&pstr->cur_state, '\0', --diff --git a/lib/regex_internal.h b/lib/regex_internal.h --index 5462419b787..e0f8292395d 100644 ----- a/lib/regex_internal.h --+++ b/lib/regex_internal.h --@@ -425,7 +425,7 @@ struct re_string_t -- unsigned char offsets_needed; -- unsigned char newline_anchor; -- unsigned char word_ops_used; --- int mb_cur_max; --+ unsigned int mb_cur_max; -- }; -- typedef struct re_string_t re_string_t; -- --@@ -702,7 +702,7 @@ struct re_dfa_t -- unsigned int is_utf8 : 1; -- unsigned int map_notascii : 1; -- unsigned int word_ops_used : 1; --- int mb_cur_max; --+ unsigned int mb_cur_max; -- bitset_t word_char; -- reg_syntax_t syntax; -- Idx *subexp_map; --diff --git a/lib/regexec.c b/lib/regexec.c --index 0a7a27b772e..b57d4f9141d 100644 ----- a/lib/regexec.c --+++ b/lib/regexec.c --@@ -443,7 +443,7 @@ re_search_stub (struct re_pattern_buffer *bufp, const char *string, Idx length, -- { -- if (ret_len) -- { --- assert (pmatch[0].rm_so == start); --+ assert (pmatch[0].rm_so == (long)start); -- rval = pmatch[0].rm_eo - start; -- } -- else --@@ -877,11 +877,11 @@ re_search_internal (const regex_t *preg, const char *string, Idx length, -- if (__glibc_unlikely (mctx.input.offsets_needed != 0)) -- { -- pmatch[reg_idx].rm_so = --- (pmatch[reg_idx].rm_so == mctx.input.valid_len --+ (pmatch[reg_idx].rm_so == (long)mctx.input.valid_len -- ? mctx.input.valid_raw_len -- : mctx.input.offsets[pmatch[reg_idx].rm_so]); -- pmatch[reg_idx].rm_eo = --- (pmatch[reg_idx].rm_eo == mctx.input.valid_len --+ (pmatch[reg_idx].rm_eo == (long)mctx.input.valid_len -- ? mctx.input.valid_raw_len -- : mctx.input.offsets[pmatch[reg_idx].rm_eo]); -- } --@@ -1418,11 +1418,11 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, -- } -- memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); -- --- for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;) --+ for (idx = pmatch[0].rm_so; idx <= (long)pmatch[0].rm_eo ;) -- { -- update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); -- --- if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) --+ if (idx == (long)pmatch[0].rm_eo && cur_node == mctx->last_node) -- { -- Idx reg_idx; -- if (fs) --@@ -1519,7 +1519,7 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, -- if (reg_num < nmatch) -- { -- /* We are at the last node of this sub expression. */ --- if (pmatch[reg_num].rm_so < cur_idx) --+ if (pmatch[reg_num].rm_so < (long)cur_idx) -- { -- pmatch[reg_num].rm_eo = cur_idx; -- /* This is a non-empty match or we are not inside an optional --@@ -2938,7 +2938,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node, -- mctx->state_log[str_idx] = cur_state; -- } -- --- for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;) --+ for (null_cnt = 0; str_idx < last_str && null_cnt <= (long)mctx->max_mb_elem_len;) -- { -- re_node_set_empty (&next_nodes); -- if (mctx->state_log[str_idx + 1]) --@@ -3718,7 +3718,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx, -- const re_string_t *input, Idx str_idx) -- { -- const re_token_t *node = dfa->nodes + node_idx; --- int char_len, elem_len; --+ unsigned int char_len, elem_len; -- Idx i; -- -- if (__glibc_unlikely (node->type == OP_UTF8_PERIOD)) --@@ -4066,7 +4066,7 @@ extend_buffers (re_match_context_t *mctx, int min_len) -- /* Double the lengths of the buffers, but allocate at least MIN_LEN. */ -- ret = re_string_realloc_buffers (pstr, -- MAX (min_len, --- MIN (pstr->len, pstr->bufs_len * 2))); --+ MIN ((long)pstr->len, pstr->bufs_len * 2))); -- if (__glibc_unlikely (ret != REG_NOERROR)) -- return ret; -- --@@ -4236,7 +4236,7 @@ match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from, -- = (from == to ? -1 : 0); -- -- mctx->bkref_ents[mctx->nbkref_ents++].more = 0; --- if (mctx->max_mb_elem_len < to - from) --+ if (mctx->max_mb_elem_len < (long)(to - from)) -- mctx->max_mb_elem_len = to - from; -- return REG_NOERROR; -- } -diff --git a/grub-core/lib/gnulib-patches/fix-uninit-structure.patch b/grub-core/lib/gnulib-patches/fix-uninit-structure.patch -deleted file mode 100644 -index 7b4d9f67af4..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-uninit-structure.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/lib/regcomp.c 2020-10-22 13:49:06.770168928 +0000 --+++ b/lib/regcomp.c 2020-10-22 13:50:37.026528298 +0000 --@@ -3662,7 +3662,7 @@ -- Idx alloc = 0; -- #endif /* not RE_ENABLE_I18N */ -- reg_errcode_t ret; --- re_token_t br_token; --+ re_token_t br_token = {0}; -- bin_tree_t *tree; -- -- sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -diff --git a/grub-core/lib/gnulib-patches/fix-unused-value.patch b/grub-core/lib/gnulib-patches/fix-unused-value.patch -deleted file mode 100644 -index ba51f1bf223..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-unused-value.patch -+++ /dev/null -@@ -1,14 +0,0 @@ ----- a/lib/regexec.c 2020-10-21 14:25:35.310195912 +0000 --+++ b/lib/regexec.c 2020-10-21 14:32:07.961765604 +0000 --@@ -828,7 +828,11 @@ -- break; -- if (__glibc_unlikely (err != REG_NOMATCH)) -- goto free_return; --+#ifdef DEBUG --+ /* Only used for assertion below when DEBUG is set, otherwise --+ it will be over-written when we loop around. */ -- match_last = -1; --+#endif -- } -- else -- break; /* We found a match. */ -diff --git a/grub-core/lib/gnulib-patches/fix-width.patch b/grub-core/lib/gnulib-patches/fix-width.patch -deleted file mode 100644 -index 0a208ad08b5..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-width.patch -+++ /dev/null -@@ -1,217 +0,0 @@ --diff --git a/lib/argp-fmtstream.c b/lib/argp-fmtstream.c --index ba6a407f7..d0685b3d4 100644 ----- a/lib/argp-fmtstream.c --+++ b/lib/argp-fmtstream.c --@@ -28,9 +28,11 @@ -- #include -- #include -- #include --+#include -- -- #include "argp-fmtstream.h" -- #include "argp-namefrob.h" --+#include "mbswidth.h" -- -- #ifndef ARGP_FMTSTREAM_USE_LINEWRAP -- --@@ -115,6 +117,51 @@ weak_alias (__argp_fmtstream_free, argp_fmtstream_free) -- #endif -- #endif -- --+ --+/* Return the pointer to the first character that doesn't fit in l columns. */ --+static inline const ptrdiff_t --+add_width (const char *ptr, const char *end, size_t l) --+{ --+ mbstate_t ps; --+ const char *ptr0 = ptr; --+ --+ memset (&ps, 0, sizeof (ps)); --+ --+ while (ptr < end) --+ { --+ wchar_t wc; --+ size_t s, k; --+ --+ s = mbrtowc (&wc, ptr, end - ptr, &ps); --+ if (s == (size_t) -1) --+ break; --+ if (s == (size_t) -2) --+ { --+ if (1 >= l) --+ break; --+ l--; --+ ptr++; --+ continue; --+ } --+ --+ if (wc == '\e' && ptr + 3 < end --+ && ptr[1] == '[' && (ptr[2] == '0' || ptr[2] == '1') --+ && ptr[3] == 'm') --+ { --+ ptr += 4; --+ continue; --+ } --+ --+ k = wcwidth (wc); --+ --+ if (k >= l) --+ break; --+ l -= k; --+ ptr += s; --+ } --+ return ptr - ptr0; --+} --+ -- /* Process FS's buffer so that line wrapping is done from POINT_OFFS to the -- end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ -- void --@@ -168,13 +215,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs) -- if (!nl) -- { -- /* The buffer ends in a partial line. */ --+ size_t display_width = mbsnwidth (buf, fs->p - buf, --+ MBSW_STOP_AT_NUL); -- --- if (fs->point_col + len < fs->rmargin) --+ if (fs->point_col + display_width < fs->rmargin) -- { -- /* The remaining buffer text is a partial line and fits -- within the maximum line width. Advance point for the -- characters to be written and stop scanning. */ --- fs->point_col += len; --+ fs->point_col += display_width; -- break; -- } -- else --@@ -182,14 +231,18 @@ __argp_fmtstream_update (argp_fmtstream_t fs) -- the end of the buffer. */ -- nl = fs->p; -- } --- else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin) --- { --- /* The buffer contains a full line that fits within the maximum --- line width. Reset point and scan the next line. */ --- fs->point_col = 0; --- buf = nl + 1; --- continue; --- } --+ else --+ { --+ size_t display_width = mbsnwidth (buf, nl - buf, MBSW_STOP_AT_NUL); --+ if (display_width < (ssize_t) fs->rmargin) --+ { --+ /* The buffer contains a full line that fits within the maximum --+ line width. Reset point and scan the next line. */ --+ fs->point_col = 0; --+ buf = nl + 1; --+ continue; --+ } --+ } -- -- /* This line is too long. */ -- r = fs->rmargin - 1; --@@ -225,7 +278,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) -- char *p, *nextline; -- int i; -- --- p = buf + (r + 1 - fs->point_col); --+ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); -- while (p >= buf && !isblank ((unsigned char) *p)) -- --p; -- nextline = p + 1; /* This will begin the next line. */ --@@ -243,7 +296,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs) -- { -- /* A single word that is greater than the maximum line width. -- Oh well. Put it on an overlong line by itself. */ --- p = buf + (r + 1 - fs->point_col); --+ p = buf + add_width (buf, fs->p, (r + 1 - fs->point_col)); -- /* Find the end of the long word. */ -- if (p < nl) -- do --@@ -277,7 +330,8 @@ __argp_fmtstream_update (argp_fmtstream_t fs) -- && fs->p > nextline) -- { -- /* The margin needs more blanks than we removed. */ --- if (fs->end - fs->p > fs->wmargin + 1) --+ if (mbsnwidth (fs->p, fs->end - fs->p, MBSW_STOP_AT_NUL) --+ > fs->wmargin + 1) -- /* Make some space for them. */ -- { -- size_t mv = fs->p - nextline; --diff --git a/lib/argp-help.c b/lib/argp-help.c --index e5375a0f0..5d8f451ec 100644 ----- a/lib/argp-help.c --+++ b/lib/argp-help.c --@@ -51,6 +51,7 @@ -- #include "argp.h" -- #include "argp-fmtstream.h" -- #include "argp-namefrob.h" --+#include "mbswidth.h" -- -- #ifndef SIZE_MAX -- # define SIZE_MAX ((size_t) -1) --@@ -1432,7 +1433,7 @@ argp_args_usage (const struct argp *argp, const struct argp_state *state, -- -- /* Manually do line wrapping so that it (probably) won't get wrapped at -- any embedded spaces. */ --- space (stream, 1 + nl - cp); --+ space (stream, 1 + mbsnwidth (cp, nl - cp, MBSW_STOP_AT_NUL)); -- -- __argp_fmtstream_write (stream, cp, nl - cp); -- } --diff --git a/lib/mbswidth.c b/lib/mbswidth.c --index 408a15e34..b3fb7f83a 100644 ----- a/lib/mbswidth.c --+++ b/lib/mbswidth.c --@@ -38,6 +38,14 @@ -- /* Get INT_MAX. */ -- #include -- --+#ifndef FALLTHROUGH --+# if __GNUC__ < 7 --+# define FALLTHROUGH ((void) 0) --+# else --+# define FALLTHROUGH __attribute__ ((__fallthrough__)) --+# endif --+#endif --+ -- /* Returns the number of columns needed to represent the multibyte -- character string pointed to by STRING. If a non-printable character -- occurs, and MBSW_REJECT_UNPRINTABLE is specified, -1 is returned. --@@ -90,6 +98,10 @@ mbsnwidth (const char *string, size_t nbytes, int flags) -- p++; -- width++; -- break; --+ case '\0': --+ if (flags & MBSW_STOP_AT_NUL) --+ return width; --+ FALLTHROUGH; -- default: -- /* If we have a multibyte sequence, scan it up to its end. */ -- { --@@ -168,6 +180,9 @@ mbsnwidth (const char *string, size_t nbytes, int flags) -- { -- unsigned char c = (unsigned char) *p++; -- --+ if (c == 0 && (flags & MBSW_STOP_AT_NUL)) --+ return width; --+ -- if (isprint (c)) -- { -- if (width == INT_MAX) --diff --git a/lib/mbswidth.h b/lib/mbswidth.h --index 2b5c53c37..45a123e63 100644 ----- a/lib/mbswidth.h --+++ b/lib/mbswidth.h --@@ -45,6 +45,10 @@ extern "C" { -- control characters and 1 otherwise. */ -- #define MBSW_REJECT_UNPRINTABLE 2 -- --+/* If this bit is set \0 is treated as the end of string. --+ Otherwise it's treated as a normal one column width character. */ --+#define MBSW_STOP_AT_NUL 4 --+ -- -- /* Returns the number of screen columns needed for STRING. */ -- #define mbswidth gnu_mbswidth /* avoid clash with UnixWare 7.1.1 function */ -diff --git a/grub-core/lib/gnulib-patches/no-abort.patch b/grub-core/lib/gnulib-patches/no-abort.patch -deleted file mode 100644 -index e469c4762eb..00000000000 ---- a/grub-core/lib/gnulib-patches/no-abort.patch -+++ /dev/null -@@ -1,26 +0,0 @@ --diff --git a/lib/regcomp.c b/lib/regcomp.c --index cc85f35ac..de45ebb5c 100644 ----- a/lib/regcomp.c --+++ b/lib/regcomp.c --@@ -528,9 +528,9 @@ regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf, -- to this routine. If we are given anything else, or if other regex -- code generates an invalid error code, then the program has a bug. -- Dump core so we can fix it. */ --- abort (); --- --- msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); --+ msg = gettext ("unknown regexp error"); --+ else --+ msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); -- -- msg_size = strlen (msg) + 1; /* Includes the null. */ -- --@@ -1136,7 +1136,7 @@ optimize_utf8 (re_dfa_t *dfa) -- } -- break; -- default: --- abort (); --+ break; -- } -- -- if (mb_chars || has_period) diff --git a/0123-grub-set-bootflag-Update-comment-about-running-as-ro.patch b/0123-grub-set-bootflag-Update-comment-about-running-as-ro.patch deleted file mode 100644 index cd4ef77..0000000 --- a/0123-grub-set-bootflag-Update-comment-about-running-as-ro.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 13 Nov 2019 12:15:43 +0100 -Subject: [PATCH] grub-set-bootflag: Update comment about running as root - through pkexec - -We have stopped using pkexec for grub-set-bootflag, instead it is now -installed suid root, update the comment accordingly. - -Signed-off-by: Hans de Goede ---- - util/grub-set-bootflag.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c -index 6a79ee67444..65d74ce010f 100644 ---- a/util/grub-set-bootflag.c -+++ b/util/grub-set-bootflag.c -@@ -18,7 +18,7 @@ - */ - - /* -- * NOTE this gets run by users as root (through pkexec), so this does not -+ * NOTE this gets run by users as root (its suid root), so this does not - * use any grub library / util functions to allow for easy auditing. - * The grub headers are only included to get certain defines. - */ diff --git a/0124-grub-set-bootflag-Write-new-env-to-tmpfile-and-then-.patch b/0124-grub-set-bootflag-Write-new-env-to-tmpfile-and-then-.patch deleted file mode 100644 index 122bf68..0000000 --- a/0124-grub-set-bootflag-Write-new-env-to-tmpfile-and-then-.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 13 Nov 2019 13:02:01 +0100 -Subject: [PATCH] grub-set-bootflag: Write new env to tmpfile and then rename - -Make the grubenv writing code in grub-set-bootflag more robust by -writing the modified grubenv to a tmpfile first and then renaming the -tmpfile over the old grubenv (following symlinks). - -Signed-off-by: Hans de Goede ---- - util/grub-set-bootflag.c | 87 +++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 78 insertions(+), 9 deletions(-) - -diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c -index 65d74ce010f..d1c5e28862b 100644 ---- a/util/grub-set-bootflag.c -+++ b/util/grub-set-bootflag.c -@@ -28,7 +28,9 @@ - #include - #include /* For GRUB_ENVBLK_DEFCFG define */ - #include -+#include - #include -+#include - #include - #include - -@@ -54,8 +56,10 @@ int main(int argc, char *argv[]) - { - /* NOTE buf must be at least the longest bootflag length + 4 bytes */ - char env[GRUBENV_SIZE + 1], buf[64], *s; -+ /* +1 for 0 termination, +6 for "XXXXXX" in tmp filename */ -+ char env_filename[PATH_MAX + 1], tmp_filename[PATH_MAX + 6 + 1]; - const char *bootflag; -- int i, len, ret; -+ int i, fd, len, ret; - FILE *f; - - if (argc != 2) -@@ -77,7 +81,32 @@ int main(int argc, char *argv[]) - bootflag = bootflags[i]; - len = strlen (bootflag); - -- f = fopen (GRUBENV, "r"); -+ /* -+ * Really become root. setuid avoids an user killing us, possibly leaking -+ * the tmpfile. setgid avoids the new grubenv's gid being that of the user. -+ */ -+ ret = setuid(0); -+ if (ret) -+ { -+ perror ("Error setuid(0) failed"); -+ return 1; -+ } -+ -+ ret = setgid(0); -+ if (ret) -+ { -+ perror ("Error setgid(0) failed"); -+ return 1; -+ } -+ -+ /* Canonicalize GRUBENV filename, resolving symlinks, etc. */ -+ if (!realpath(GRUBENV, env_filename)) -+ { -+ perror ("Error canonicalizing " GRUBENV " filename"); -+ return 1; -+ } -+ -+ f = fopen (env_filename, "r"); - if (!f) - { - perror ("Error opening " GRUBENV " for reading"); -@@ -132,30 +161,70 @@ int main(int argc, char *argv[]) - snprintf(buf, sizeof(buf), "%s=1\n", bootflag); - memcpy(s, buf, len + 3); - -- /* "r+", don't truncate so that the diskspace stays reserved */ -- f = fopen (GRUBENV, "r+"); -+ -+ /* -+ * Create a tempfile for writing the new env. Use the canonicalized filename -+ * for the template so that the tmpfile is in the same dir / on same fs. -+ */ -+ snprintf(tmp_filename, sizeof(tmp_filename), "%sXXXXXX", env_filename); -+ fd = mkstemp(tmp_filename); -+ if (fd == -1) -+ { -+ perror ("Creating tmpfile failed"); -+ return 1; -+ } -+ -+ f = fdopen (fd, "w"); - if (!f) - { -- perror ("Error opening " GRUBENV " for writing"); -+ perror ("Error fdopen of tmpfile failed"); -+ unlink(tmp_filename); - return 1; - } - - ret = fwrite (env, 1, GRUBENV_SIZE, f); - if (ret != GRUBENV_SIZE) - { -- perror ("Error writing to " GRUBENV); -+ perror ("Error writing tmpfile"); -+ unlink(tmp_filename); - return 1; - } - - ret = fflush (f); - if (ret) - { -- perror ("Error flushing " GRUBENV); -+ perror ("Error flushing tmpfile"); -+ unlink(tmp_filename); - return 1; - } - -- fsync (fileno (f)); -- fclose (f); -+ ret = fsync (fileno (f)); -+ if (ret) -+ { -+ perror ("Error syncing tmpfile"); -+ unlink(tmp_filename); -+ return 1; -+ } -+ -+ ret = fclose (f); -+ if (ret) -+ { -+ perror ("Error closing tmpfile"); -+ unlink(tmp_filename); -+ return 1; -+ } -+ -+ /* -+ * And finally rename the tmpfile with the new env over the old env, the -+ * linux kernel guarantees that this is atomic (from a syscall pov). -+ */ -+ ret = rename(tmp_filename, env_filename); -+ if (ret) -+ { -+ perror ("Error renaming tmpfile to " GRUBENV " failed"); -+ unlink(tmp_filename); -+ return 1; -+ } - - return 0; - } diff --git a/0125-grub.d-Fix-boot_indeterminate-getting-set-on-boot_su.patch b/0125-grub.d-Fix-boot_indeterminate-getting-set-on-boot_su.patch deleted file mode 100644 index a32c146..0000000 --- a/0125-grub.d-Fix-boot_indeterminate-getting-set-on-boot_su.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 26 Nov 2019 09:51:41 +0100 -Subject: [PATCH] grub.d: Fix boot_indeterminate getting set on boot_success=0 - boot -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The "grub.d: Split out boot success reset from menu auto hide script" -not only moved the code to clear boot_success and boot_indeterminate -but for some reason also mixed in some broken changes to the -boot_indeterminate handling. - -The boot_indeterminate var is meant to suppress the boot menu after -a reboot from either a selinux-relabel or offline-updates. These -2 special boot scenarios do not set boot_success since there is no -successfull interaction with the user. Instead they increment -boot_indeterminate, and if it is 1 and only when it is 1, so the -first reboot after a "special" boot we suppress the menu. - -To ensure that we do show the menu if we somehow get stuck in a -"special" boot loop where we do special-boots without them -incrementing boot_indeterminate, the code before the -"grub.d: Split out boot success reset from menu auto hide script" -commit would increment boot_indeterminate once when it is 1, so that -even if the "special" boot reboot-loop immediately we would show the -menu on the next boot. - -That commit broke this however, because it not only moves the code, -it also changes it from only "incrementing" boot_indeterminate once to -always incrementing it, except when boot_success == 1 (and we reset it). - -This broken behavior causes the following problem: - -1. Boot a broken kernel, system hangs, power-cycle -2. boot_success now != 1, so we increment boot_indeterminate from 0 - (unset!) to 1. User either simply tries again, or makes some changes - but the end-result still is a system hang, power-cycle -3. Now boot_indeterminate==1 so we do not show the menu even though the - previous boot failed -> BAD - -This commit fixes this by restoring the behavior of setting -boot_indeterminate to 2 when it was 1 before. - -Fixes: "grub.d: Split out boot success reset from menu auto hide script" -Signed-off-by: Hans de Goede -[jpokorny: 01_menu_auto_hide.in: fix a then/than typo] -Signed-off-by: Jan Pokorný -Signed-off-by: Robbie Harwood ---- - util/grub.d/10_reset_boot_success.in | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/util/grub.d/10_reset_boot_success.in b/util/grub.d/10_reset_boot_success.in -index 6c88d933dde..e73f4137b36 100644 ---- a/util/grub.d/10_reset_boot_success.in -+++ b/util/grub.d/10_reset_boot_success.in -@@ -6,18 +6,18 @@ - # - # The boot_success var needs to be set to 1 from userspace to mark a boot successful. - cat << EOF --insmod increment - # Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry - if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then - set menu_hide_ok=1 - else - set menu_hide_ok=0 - fi --# Reset boot_indeterminate after a successful boot, increment otherwise -+# Reset boot_indeterminate after a successful boot - if [ "\${boot_success}" = "1" ] ; then - set boot_indeterminate=0 --else -- increment boot_indeterminate -+# Avoid boot_indeterminate causing the menu to be hidden more than once -+elif [ "\${boot_indeterminate}" = "1" ]; then -+ set boot_indeterminate=2 - fi - # Reset boot_success for current boot - set boot_success=0 diff --git a/0126-Add-start-symbol-for-RISC-V.patch b/0126-Add-start-symbol-for-RISC-V.patch deleted file mode 100644 index 677efae..0000000 --- a/0126-Add-start-symbol-for-RISC-V.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: David Abdurachmanov -Date: Sat, 9 Nov 2019 19:51:57 +0000 -Subject: [PATCH] Add start symbol for RISC-V - -All other architectures have start symbol. - -Hopefully this resolves: - - BUILDSTDERR: ././grub-mkimage: error: undefined symbol start. - -Signed-off-by: David Abdurachmanov ---- - grub-core/kern/riscv/efi/startup.S | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/kern/riscv/efi/startup.S b/grub-core/kern/riscv/efi/startup.S -index f2a7b2b1ede..781773136e8 100644 ---- a/grub-core/kern/riscv/efi/startup.S -+++ b/grub-core/kern/riscv/efi/startup.S -@@ -29,6 +29,7 @@ - - .file "startup.S" - .text -+FUNCTION(start) - FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. diff --git a/0127-bootstrap.conf-Force-autogen.sh-to-use-python3.patch b/0127-bootstrap.conf-Force-autogen.sh-to-use-python3.patch deleted file mode 100644 index 5c3b968..0000000 --- a/0127-bootstrap.conf-Force-autogen.sh-to-use-python3.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 15 Jan 2020 12:47:46 +0100 -Subject: [PATCH] bootstrap.conf: Force autogen.sh to use python3 - -The python-unversioned-command package is not installed in the buildroot, -but the bootstrap script expects the python command to be present if one -is not defined. So building the package leads to the following error: - -./autogen.sh: line 20: python: command not found - -This is harmless since gnulib is included as a source anyways, because the -builders can't download. But still the issue should be fixed by forcing to -use python3 that's the default in Fedora now. - -Signed-off-by: Javier Martinez Canillas ---- - bootstrap.conf | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/bootstrap.conf b/bootstrap.conf -index 452f4d79b0d..03f10930230 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -93,7 +93,7 @@ bootstrap_post_import_hook () { - patch -d po -p3 \ - < "po/gettext-patches/$patchname.patch" - done -- FROM_BOOTSTRAP=1 ./autogen.sh -+ PYTHON=python3 FROM_BOOTSTRAP=1 ./autogen.sh - set +e # bootstrap expects this - } - diff --git a/0128-efi-http-Export-fw-http-_path-variables-to-make-them.patch b/0128-efi-http-Export-fw-http-_path-variables-to-make-them.patch deleted file mode 100644 index 74183bc..0000000 --- a/0128-efi-http-Export-fw-http-_path-variables-to-make-them.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Thu, 5 Mar 2020 16:21:47 +0100 -Subject: [PATCH] efi/http: Export {fw,http}_path variables to make them global - -The fw_path environment variable is used by http_configure() function to -determine the HTTP path that should be used as prefix when using relative -HTTP paths. And this is stored in the http_path environment variable. - -Later, that variable is looked up by grub_efihttp_open() to generate the -complete path to be used in the HTTP request. - -But these variables are not exported, which means that are not global and -so are only found in the initial context. - -This can cause commands like configfile that create a new context to fail -because the fw_path and http_path variables will not be found. - -Resolves: rhbz#1616395 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/kern/main.c | 1 + - grub-core/net/efi/http.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index 1c540fc8c26..b573be6650d 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -143,6 +143,7 @@ grub_set_prefix_and_root (void) - if (fw_path) - { - grub_env_set ("fw_path", fw_path); -+ grub_env_export ("fw_path"); - grub_dprintf ("fw_path", "fw_path:\"%s\"\n", fw_path); - grub_free (fw_path); - } -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index de351b2cd03..755b7a6d054 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -39,6 +39,7 @@ http_configure (struct grub_efi_net_device *dev, int prefer_ip6) - http_path++; - grub_env_unset ("http_path"); - grub_env_set ("http_path", http_path); -+ grub_env_export ("http_path"); - } - } - diff --git a/0129-efi-http-Enclose-literal-IPv6-addresses-in-square-br.patch b/0129-efi-http-Enclose-literal-IPv6-addresses-in-square-br.patch deleted file mode 100644 index c394549..0000000 --- a/0129-efi-http-Enclose-literal-IPv6-addresses-in-square-br.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Thu, 5 Mar 2020 16:21:58 +0100 -Subject: [PATCH] efi/http: Enclose literal IPv6 addresses in square brackets - -According to RFC 2732 (https://www.ietf.org/rfc/rfc2732.txt), literal IPv6 -addresses must be enclosed in square brackets. But GRUB currently does not -do this and is causing HTTP servers to send Bad Request (400) responses. - -For example, the following is the HTTP stream when fetching a config file: - -HEAD /EFI/BOOT/grub.cfg HTTP/1.1 -Host: 2000:dead:beef:a::1 -Accept: */* -User-Agent: UefiHttpBoot/1.0 - -HTTP/1.1 400 Bad Request -Date: Thu, 05 Mar 2020 14:46:02 GMT -Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1d -Connection: close -Content-Type: text/html; charset=iso-8859-1 - -and after enclosing the IPv6 address the HTTP request is successful: - -HEAD /EFI/BOOT/grub.cfg HTTP/1.1 -Host: [2000:dead:beef:a::1] -Accept: */* -User-Agent: UefiHttpBoot/1.0 - -HTTP/1.1 200 OK -Date: Thu, 05 Mar 2020 14:48:04 GMT -Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1d -Last-Modified: Thu, 27 Feb 2020 17:45:58 GMT -ETag: "206-59f924b24b1da" -Accept-Ranges: bytes -Content-Length: 518 - -Resolves: rhbz#1732765 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/efi/http.c | 37 ++++++++++++++++++++++++++++--------- - 1 file changed, 28 insertions(+), 9 deletions(-) - -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index 755b7a6d054..fc8cb25ae0a 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -158,13 +158,7 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - grub_efi_status_t status; - grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; - char *url = NULL; -- -- request_headers[0].field_name = (grub_efi_char8_t *)"Host"; -- request_headers[0].field_value = (grub_efi_char8_t *)server; -- request_headers[1].field_name = (grub_efi_char8_t *)"Accept"; -- request_headers[1].field_value = (grub_efi_char8_t *)"*/*"; -- request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent"; -- request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0"; -+ char *hostname = NULL; - - { - grub_efi_ipv6_address_t address; -@@ -174,9 +168,24 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - const char *protocol = (use_https == 1) ? "https" : "http"; - - if (grub_efi_string_to_ip6_address (server, &address, &rest) && *rest == 0) -- url = grub_xasprintf ("%s://[%s]%s", protocol, server, name); -+ { -+ hostname = grub_xasprintf ("[%s]", server); -+ if (!hostname) -+ return GRUB_ERR_OUT_OF_MEMORY; -+ -+ server = hostname; -+ -+ url = grub_xasprintf ("%s://%s%s", protocol, server, name); -+ if (!url) -+ { -+ grub_free (hostname); -+ return GRUB_ERR_OUT_OF_MEMORY; -+ } -+ } - else -- url = grub_xasprintf ("%s://%s%s", protocol, server, name); -+ { -+ url = grub_xasprintf ("%s://%s%s", protocol, server, name); -+ } - - if (!url) - { -@@ -199,6 +208,13 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - request_data.url = ucs2_url; - } - -+ request_headers[0].field_name = (grub_efi_char8_t *)"Host"; -+ request_headers[0].field_value = (grub_efi_char8_t *)server; -+ request_headers[1].field_name = (grub_efi_char8_t *)"Accept"; -+ request_headers[1].field_value = (grub_efi_char8_t *)"*/*"; -+ request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent"; -+ request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0"; -+ - request_data.method = (headeronly > 0) ? GRUB_EFI_HTTPMETHODHEAD : GRUB_EFI_HTTPMETHODGET; - - request_message.data.request = &request_data; -@@ -228,6 +244,9 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - - status = efi_call_2 (http->request, http, &request_token); - -+ if (hostname) -+ grub_free (hostname); -+ - if (status != GRUB_EFI_SUCCESS) - { - efi_call_1 (b->close_event, request_token.event); diff --git a/0130-efi-net-Allow-to-specify-a-port-number-in-addresses.patch b/0130-efi-net-Allow-to-specify-a-port-number-in-addresses.patch deleted file mode 100644 index 209aed8..0000000 --- a/0130-efi-net-Allow-to-specify-a-port-number-in-addresses.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 9 Mar 2020 15:29:45 +0100 -Subject: [PATCH] efi/net: Allow to specify a port number in addresses - -The grub_efi_net_parse_address() function is not covering the case where a -port number is specified in an IPv4 or IPv6 address, so will fail to parse -the network address. - -For most cases the issue is harmless, because the function is only used to -match an address with a network interface and if fails the default is used. - -But still is a bug that has to be fixed and it causes error messages to be -printed like the following: - -error: net/efi/net.c:782:unrecognised network address '192.168.122.1:8080' - -error: net/efi/net.c:781:unrecognised network address '[2000:dead:beef:a::1]:8080' - -Resolves: rhbz#1732765 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/efi/net.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 6603cd83edc..84573937b18 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -742,7 +742,7 @@ grub_efi_net_parse_address (const char *address, - return GRUB_ERR_NONE; - } - } -- else if (*rest == 0) -+ else if (*rest == 0 || *rest == ':') - { - grub_uint32_t subnet_mask = 0xffffffffU; - grub_memcpy (ip4->subnet_mask, &subnet_mask, sizeof (ip4->subnet_mask)); -@@ -768,7 +768,7 @@ grub_efi_net_parse_address (const char *address, - return GRUB_ERR_NONE; - } - } -- else if (*rest == 0) -+ else if (*rest == 0 || *rest == ':') - { - ip6->prefix_length = 128; - ip6->is_anycast = 0; diff --git a/0131-efi-ip4_config-Improve-check-to-detect-literal-IPv6-.patch b/0131-efi-ip4_config-Improve-check-to-detect-literal-IPv6-.patch deleted file mode 100644 index f92dee4..0000000 --- a/0131-efi-ip4_config-Improve-check-to-detect-literal-IPv6-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 9 Mar 2020 15:30:05 +0100 -Subject: [PATCH] efi/ip4_config: Improve check to detect literal IPv6 - addresses - -The grub_efi_string_to_ip4_address() function wrongly assumes that an IPv6 -address is an IPv4 address, because it doesn't take into account the case -of a caller passing an IPv6 address as a string. - -This leads to the grub_efi_net_parse_address() function to fail and print -the following error message: - -error: net/efi/net.c:785:unrecognised network address '2000:dead:beef:a::1' - -Resolves: rhbz#1732765 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/efi/ip4_config.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c -index b711a5d9457..313c818b184 100644 ---- a/grub-core/net/efi/ip4_config.c -+++ b/grub-core/net/efi/ip4_config.c -@@ -56,9 +56,20 @@ int - grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *address, const char **rest) - { - grub_uint32_t newip = 0; -- int i; -+ int i, ncolon = 0; - const char *ptr = val; - -+ /* Check that is not an IPv6 address */ -+ for (i = 0; i < grub_strlen(ptr); i++) -+ { -+ if (ptr[i] == '[' && i == 0) -+ return 0; -+ -+ if (ptr[i] == ':') -+ if (i == 0 || ++ncolon == 2) -+ return 0; -+ } -+ - for (i = 0; i < 4; i++) - { - unsigned long t; diff --git a/0132-efi-net-Print-a-debug-message-if-parsing-the-address.patch b/0132-efi-net-Print-a-debug-message-if-parsing-the-address.patch deleted file mode 100644 index 33d8f88..0000000 --- a/0132-efi-net-Print-a-debug-message-if-parsing-the-address.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 10 Mar 2020 11:23:49 +0100 -Subject: [PATCH] efi/net: Print a debug message if parsing the address fails - -Currently if parsing the address fails an error message is printed. But in -most cases this isn't a fatal error since the grub_efi_net_parse_address() -function is only used to match an address with a network interface to use. - -And if this fails, the default interface is used which is good enough for -most cases. So instead of printing an error that would pollute the console -just print a debug message if the address is not parsed correctly. - -A user can enable debug messages for the efinet driver to have information -about the failure and the fact that the default interface is being used. - -Related: rhbz#1732765 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/efi/net.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 84573937b18..a3f0535d43c 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -778,9 +778,9 @@ grub_efi_net_parse_address (const char *address, - } - } - -- return grub_error (GRUB_ERR_NET_BAD_ADDRESS, -- N_("unrecognised network address `%s'"), -- address); -+ grub_dprintf ("efinet", "unrecognised network address '%s'\n", address); -+ -+ return GRUB_ERR_NET_BAD_ADDRESS; - } - - static grub_efi_net_interface_t * -@@ -795,10 +795,7 @@ match_route (const char *server) - err = grub_efi_net_parse_address (server, &ip4, &ip6, &is_ip6, 0); - - if (err) -- { -- grub_print_error (); - return NULL; -- } - - if (is_ip6) - { -@@ -1233,8 +1230,15 @@ grub_net_open_real (const char *name __attribute__ ((unused))) - /*FIXME: Use DNS translate name to address */ - net_interface = match_route (server); - -+ if (!net_interface && net_default_interface) -+ { -+ net_interface = net_default_interface; -+ grub_dprintf ("efinet", "interface lookup failed, using default '%s'\n", -+ net_interface->name); -+ } -+ - /*XXX: should we check device with default gateway ? */ -- if (!net_interface && !(net_interface = net_default_interface)) -+ if (!net_interface) - { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' no route found"), - name); diff --git a/0133-kern-term-Also-accept-F8-as-a-user-interrupt-key.patch b/0133-kern-term-Also-accept-F8-as-a-user-interrupt-key.patch deleted file mode 100644 index 3dd525a..0000000 --- a/0133-kern-term-Also-accept-F8-as-a-user-interrupt-key.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 22 Apr 2020 12:41:52 +0200 -Subject: [PATCH] kern/term: Also accept F8 as a user interrupt key - -Make F8, which used to be the hotkey to show the Windows boot menu during -boot for a long long time, also interrupt sleeps / stop the menu countdown. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/kern/term.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c -index 14d59649832..4d61f4e9790 100644 ---- a/grub-core/kern/term.c -+++ b/grub-core/kern/term.c -@@ -144,9 +144,10 @@ grub_key_is_interrupt (int key) - /* - * ESC sometimes is the BIOS setup hotkey and may be hard to discover, also - * check F4, which was chosen because is not used as a hotkey to enter the -- * BIOS setup by any vendor. -+ * BIOS setup by any vendor. Also, F8 which was the key to get the Windows -+ * bootmenu for a long time. - */ -- if (key == GRUB_TERM_ESC || key == GRUB_TERM_KEY_F4) -+ if (key == GRUB_TERM_ESC || key == GRUB_TERM_KEY_F4 || key == GRUB_TERM_KEY_F8) - return 1; - - /* diff --git a/0134-efi-Set-image-base-address-before-jumping-to-the-PE-.patch b/0134-efi-Set-image-base-address-before-jumping-to-the-PE-.patch deleted file mode 100644 index 336bcf1..0000000 --- a/0134-efi-Set-image-base-address-before-jumping-to-the-PE-.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Thu, 23 Apr 2020 15:06:46 +0200 -Subject: [PATCH] efi: Set image base address before jumping to the PE/COFF - entry point - -Upstream GRUB uses the EFI LoadImage() and StartImage() to boot the Linux -kernel. But our custom EFI loader that supports Secure Boot instead uses -the EFI handover protocol (for x86) or jumping directly to the PE/COFF -entry point (for aarch64). - -This is done to allow the bootloader to verify the images using the shim -lock protocol to avoid booting untrusted binaries. - -Since the bootloader loads the kernel from the boot media instead of using -LoadImage(), it is responsible to set the Loaded Image base address before -booting the kernel. - -Otherwise the kernel EFI stub will complain that it was not set correctly -and print the following warning message: - -EFI stub: ERROR: FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value - -Resolves: rhbz#1814690 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/loader/efi/linux.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index 0622dfa48d4..e8b9ecb17f6 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -72,6 +72,7 @@ grub_err_t - grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, - void *kernel_params) - { -+ grub_efi_loaded_image_t *loaded_image = NULL; - handover_func hf; - int offset = 0; - -@@ -79,6 +80,19 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, - offset = 512; - #endif - -+ /* -+ * Since the EFI loader is not calling the LoadImage() and StartImage() -+ * services for loading the kernel and booting respectively, it has to -+ * set the Loaded Image base address. -+ */ -+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); -+ if (loaded_image) -+ loaded_image->image_base = kernel_addr; -+ else -+ grub_dprintf ("linux", "Loaded Image base address could not be set\n"); -+ -+ grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n", -+ kernel_addr, (void *)(grub_efi_uintn_t)handover_offset, kernel_params); - hf = (handover_func)((char *)kernel_addr + handover_offset + offset); - hf (grub_efi_image_handle, grub_efi_system_table, kernel_params); - diff --git a/0135-tpm-Don-t-propagate-TPM-measurement-errors-to-the-ve.patch b/0135-tpm-Don-t-propagate-TPM-measurement-errors-to-the-ve.patch deleted file mode 100644 index 747773d..0000000 --- a/0135-tpm-Don-t-propagate-TPM-measurement-errors-to-the-ve.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Sat, 16 May 2020 11:33:18 +0200 -Subject: [PATCH] tpm: Don't propagate TPM measurement errors to the verifiers - layer - -Currently if the EFI firmware fails to do a TPM measurement for a file, -the error will be propagated to the verifiers framework and so opening -the file will not succeed. - -This mean that buggy firmwares will prevent the system to boot since the -loader won't be able to open any file. But failing to do TPM measurements -shouldn't be a fatal error and the system should still be able to boot. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/commands/tpm.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c -index 2052c36eaba..e287d042e6b 100644 ---- a/grub-core/commands/tpm.c -+++ b/grub-core/commands/tpm.c -@@ -42,7 +42,8 @@ grub_tpm_verify_init (grub_file_t io, - static grub_err_t - grub_tpm_verify_write (void *context, void *buf, grub_size_t size) - { -- return grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context); -+ grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context); -+ return GRUB_ERR_NONE; - } - - static grub_err_t -@@ -50,7 +51,6 @@ grub_tpm_verify_string (char *str, enum grub_verify_string_type type) - { - const char *prefix = NULL; - char *description; -- grub_err_t status; - - switch (type) - { -@@ -66,15 +66,15 @@ grub_tpm_verify_string (char *str, enum grub_verify_string_type type) - } - description = grub_malloc (grub_strlen (str) + grub_strlen (prefix) + 1); - if (!description) -- return grub_errno; -+ return GRUB_ERR_NONE; - grub_memcpy (description, prefix, grub_strlen (prefix)); - grub_memcpy (description + grub_strlen (prefix), str, - grub_strlen (str) + 1); -- status = -- grub_tpm_measure ((unsigned char *) str, grub_strlen (str), -- GRUB_STRING_PCR, description); -+ -+ grub_tpm_measure ((unsigned char *) str, grub_strlen (str), GRUB_STRING_PCR, -+ description); - grub_free (description); -- return status; -+ return GRUB_ERR_NONE; - } - - struct grub_file_verifier grub_tpm_verifier = { diff --git a/0136-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch b/0136-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch deleted file mode 100644 index 825d0f7..0000000 --- a/0136-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 26 May 2020 16:59:28 +0200 -Subject: [PATCH] x86-efi: Reduce maximum bounce buffer size to 16 MiB - -The EFI linux loader allocates a bounce buffer to copy the initrd since in -some machines doing DMA on addresses above 4GB is not possible during EFI. - -But the verifiers framework also allocates a buffer to copy the initrd in -its grub_file_open() handler. It does this since the data to verify has to -be passed as a single chunk to modules that use the verifiers framework. - -If the initrd image size is big there may not be enough memory in the heap -to allocate two buffers of that size. This causes an allocation failure in -the verifiers framework and leads to the initrd not being read. - -To prevent these allocation failures, let's reduce the maximum size of the -bounce buffer used in the EFI loader. Since the data read can be copied to -the actual initrd address in multilple chunks. - -Resolves: rhbz#1838633 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/loader/i386/efi/linux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 6bc18d5aef5..15d40d6e35b 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -144,7 +144,7 @@ grub_linuxefi_unload (void) - return GRUB_ERR_NONE; - } - --#define BOUNCE_BUFFER_MAX 0x10000000ull -+#define BOUNCE_BUFFER_MAX 0x1000000ull - - static grub_ssize_t - read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) diff --git a/0137-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch b/0137-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch deleted file mode 100644 index 97d2e06..0000000 --- a/0137-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 2 Jun 2020 13:25:01 +0200 -Subject: [PATCH] http: Prepend prefix when the HTTP path is relative as done - in efi/http - -There are two different HTTP drivers that can be used when requesting an -HTTP resource: the efi/http that uses the EFI_HTTP_PROTOCOL and the http -that uses GRUB's HTTP and TCP/IP implementation. - -The efi/http driver appends a prefix that is defined in the variable -http_path, but the http driver doesn't. - -So using this driver and attempting to fetch a resource using a relative -path fails. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/http.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index b52b558d631..7f878b56157 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -501,13 +501,20 @@ http_open (struct grub_file *file, const char *filename) - { - grub_err_t err; - struct http_data *data; -+ const char *http_path; - - data = grub_zalloc (sizeof (*data)); - if (!data) - return grub_errno; - file->size = GRUB_FILE_SIZE_UNKNOWN; - -- data->filename = grub_strdup (filename); -+ /* If path is relative, prepend http_path */ -+ http_path = grub_env_get ("http_path"); -+ if (http_path && filename[0] != '/') -+ data->filename = grub_xasprintf ("%s/%s", http_path, filename); -+ else -+ data->filename = grub_strdup (filename); -+ - if (!data->filename) - { - grub_free (data); diff --git a/0138-Fix-a-missing-return-in-efi-export-env-and-efi-load-.patch b/0138-Fix-a-missing-return-in-efi-export-env-and-efi-load-.patch deleted file mode 100644 index 1657d7a..0000000 --- a/0138-Fix-a-missing-return-in-efi-export-env-and-efi-load-.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 16 Jan 2019 13:21:46 -0500 -Subject: [PATCH] Fix a missing return in efi-export-env and efi-load-env - commands - -Somewhere along the way this got mis-merged to include a return without -a value. Fix it up. - -Signed-off-by: Peter Jones ---- - grub-core/commands/efi/env.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/commands/efi/env.c b/grub-core/commands/efi/env.c -index cbd13e03e81..977edb6b065 100644 ---- a/grub-core/commands/efi/env.c -+++ b/grub-core/commands/efi/env.c -@@ -149,6 +149,8 @@ grub_efi_load_env(grub_command_t cmd __attribute__ ((unused)), - - grub_envblk_iterate (envblk, NULL, set_var); - grub_free (envblk_s.buf); -+ -+ return GRUB_ERR_NONE; - } - - static grub_command_t export_cmd, loadenv_cmd; diff --git a/0139-efi-dhcp-fix-some-allocation-error-checking.patch b/0139-efi-dhcp-fix-some-allocation-error-checking.patch deleted file mode 100644 index 7549733..0000000 --- a/0139-efi-dhcp-fix-some-allocation-error-checking.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sun, 19 Jul 2020 17:11:06 -0400 -Subject: [PATCH] efi+dhcp: fix some allocation error checking. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/dhcp.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/grub-core/net/efi/dhcp.c b/grub-core/net/efi/dhcp.c -index dbef63d8c08..e5c79b748b0 100644 ---- a/grub-core/net/efi/dhcp.c -+++ b/grub-core/net/efi/dhcp.c -@@ -80,7 +80,7 @@ grub_efi_dhcp4_parse_dns (grub_efi_dhcp4_protocol_t *dhcp4, grub_efi_dhcp4_packe - if (status != GRUB_EFI_BUFFER_TOO_SMALL) - return NULL; - -- option_list = grub_malloc (option_count * sizeof(*option_list)); -+ option_list = grub_calloc (option_count, sizeof(*option_list)); - if (!option_list) - return NULL; - -@@ -360,8 +360,11 @@ grub_cmd_efi_bootp6 (struct grub_command *cmd __attribute__ ((unused)), - - if (status == GRUB_EFI_BUFFER_TOO_SMALL && count) - { -- options = grub_malloc (count * sizeof(*options)); -- status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options); -+ options = grub_calloc (count, sizeof(*options)); -+ if (options) -+ status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options); -+ else -+ status = GRUB_EFI_OUT_OF_RESOURCES; - } - - if (status != GRUB_EFI_SUCCESS) diff --git a/0140-efi-http-fix-some-allocation-error-checking.patch b/0140-efi-http-fix-some-allocation-error-checking.patch deleted file mode 100644 index 4dffab9..0000000 --- a/0140-efi-http-fix-some-allocation-error-checking.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sun, 19 Jul 2020 17:14:15 -0400 -Subject: [PATCH] efi+http: fix some allocation error checking. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/http.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index fc8cb25ae0a..26647a50fa4 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -412,8 +412,8 @@ grub_efihttp_open (struct grub_efi_net_device *dev, - int type) - { - grub_err_t err; -- grub_off_t size; -- char *buf; -+ grub_off_t size = 0; -+ char *buf = NULL; - char *file_name = NULL; - const char *http_path; - -@@ -441,8 +441,11 @@ grub_efihttp_open (struct grub_efi_net_device *dev, - return err; - } - -- buf = grub_malloc (size); -- efihttp_read (dev, buf, size); -+ if (size) -+ { -+ buf = grub_malloc (size); -+ efihttp_read (dev, buf, size); -+ } - - file->size = size; - file->data = buf; diff --git a/0141-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch b/0141-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch deleted file mode 100644 index 30c21a5..0000000 --- a/0141-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sun, 19 Jul 2020 17:27:00 -0400 -Subject: [PATCH] efi/ip[46]_config.c: fix some potential allocation overflows - -In theory all of this data comes from the firmware stack and it should -be safe, but it's better to be paranoid. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/ip4_config.c | 25 ++++++++++++++++++------- - grub-core/net/efi/ip6_config.c | 13 ++++++++++--- - 2 files changed, 28 insertions(+), 10 deletions(-) - -diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c -index 313c818b184..9725e928f7e 100644 ---- a/grub-core/net/efi/ip4_config.c -+++ b/grub-core/net/efi/ip4_config.c -@@ -4,15 +4,20 @@ - #include - #include - #include -+#include - - char * - grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_address_t hw_address) - { - char *hw_addr, *p; -- int sz, s; -- int i; -+ grub_size_t sz, s, i; - -- sz = (int)hw_address_size * (sizeof ("XX:") - 1) + 1; -+ if (grub_mul (hw_address_size, sizeof ("XX:") - 1, &sz) || -+ grub_add (sz, 1, &sz)) -+ { -+ grub_errno = GRUB_ERR_OUT_OF_RANGE; -+ return NULL; -+ } - - hw_addr = grub_malloc (sz); - if (!hw_addr) -@@ -20,7 +25,7 @@ grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_a - - p = hw_addr; - s = sz; -- for (i = 0; i < (int)hw_address_size; i++) -+ for (i = 0; i < hw_address_size; i++) - { - grub_snprintf (p, sz, "%02x:", hw_address[i]); - p += sizeof ("XX:") - 1; -@@ -238,14 +243,20 @@ grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev) - { - grub_efi_ip4_config2_interface_info_t *interface_info; - char **ret; -- int i, id; -+ int id; -+ grub_size_t i, nmemb; - - interface_info = efi_ip4_config_interface_info (dev->ip4_config); - if (!interface_info) - return NULL; - -- ret = grub_malloc (sizeof (*ret) * (interface_info->route_table_size + 1)); -+ if (grub_add (interface_info->route_table_size, 1, &nmemb)) -+ { -+ grub_errno = GRUB_ERR_OUT_OF_RANGE; -+ return NULL; -+ } - -+ ret = grub_calloc (nmemb, sizeof (*ret)); - if (!ret) - { - grub_free (interface_info); -@@ -253,7 +264,7 @@ grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev) - } - - id = 0; -- for (i = 0; i < (int)interface_info->route_table_size; i++) -+ for (i = 0; i < interface_info->route_table_size; i++) - { - char *subnet, *gateway, *mask; - grub_uint32_t u32_subnet, u32_gateway; -diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c -index 017c4d05bc7..a46f6f9b685 100644 ---- a/grub-core/net/efi/ip6_config.c -+++ b/grub-core/net/efi/ip6_config.c -@@ -3,6 +3,7 @@ - #include - #include - #include -+#include - - char * - grub_efi_ip6_address_to_string (grub_efi_pxe_ipv6_address_t *address) -@@ -228,14 +229,20 @@ grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev) - { - grub_efi_ip6_config_interface_info_t *interface_info; - char **ret; -- int i, id; -+ int id; -+ grub_size_t i, nmemb; - - interface_info = efi_ip6_config_interface_info (dev->ip6_config); - if (!interface_info) - return NULL; - -- ret = grub_malloc (sizeof (*ret) * (interface_info->route_count + 1)); -+ if (grub_add (interface_info->route_count, 1, &nmemb)) -+ { -+ grub_errno = GRUB_ERR_OUT_OF_RANGE; -+ return NULL; -+ } - -+ ret = grub_calloc (nmemb, sizeof (*ret)); - if (!ret) - { - grub_free (interface_info); -@@ -243,7 +250,7 @@ grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev) - } - - id = 0; -- for (i = 0; i < (int)interface_info->route_count ; i++) -+ for (i = 0; i < interface_info->route_count ; i++) - { - char *gateway, *destination; - grub_uint64_t u64_gateway[2]; diff --git a/0142-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch b/0142-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch deleted file mode 100644 index 95f7e20..0000000 --- a/0142-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Colin Watson -Date: Fri, 24 Jul 2020 17:18:09 +0100 -Subject: [PATCH] efilinux: Fix integer overflows in grub_cmd_initrd - -These could be triggered by an extremely large number of arguments to -the initrd command on 32-bit architectures, or a crafted filesystem with -very large files on any architecture. - -Signed-off-by: Colin Watson ---- - grub-core/loader/i386/efi/linux.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 15d40d6e35b..f992ceeef20 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -28,6 +28,8 @@ - #include - #include - #include -+#include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -206,7 +208,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- files = grub_zalloc (argc * sizeof (files[0])); -+ files = grub_calloc (argc, sizeof (files[0])); - if (!files) - goto fail; - -@@ -216,7 +218,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - if (! files[i]) - goto fail; - nfiles++; -- size += ALIGN_UP (grub_file_size (files[i]), 4); -+ if (grub_add (size, ALIGN_UP (grub_file_size (files[i]), 4), &size)) -+ { -+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); -+ goto fail; -+ } - } - - initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); diff --git a/0143-linuxefi-fail-kernel-validation-without-shim-protoco.patch b/0143-linuxefi-fail-kernel-validation-without-shim-protoco.patch deleted file mode 100644 index 20fc786..0000000 --- a/0143-linuxefi-fail-kernel-validation-without-shim-protoco.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitri John Ledkov -Date: Wed, 22 Jul 2020 11:31:43 +0100 -Subject: [PATCH] linuxefi: fail kernel validation without shim protocol. - -If certificates that signed grub are installed into db, grub can be -booted directly. It will then boot any kernel without signature -validation. The booted kernel will think it was booted in secureboot -mode and will implement lockdown, yet it could have been tampered. - -This version of the patch skips calling verification, when booted -without secureboot. And is indented with gnu ident. - -CVE-2020-15705 - -Reported-by: Mathieu Trudel-Lapierre -Signed-off-by: Dimitri John Ledkov ---- - grub-core/loader/arm64/linux.c | 13 +++++++++---- - grub-core/loader/efi/chainloader.c | 1 + - grub-core/loader/efi/linux.c | 1 + - grub-core/loader/i386/efi/linux.c | 17 +++++++++++------ - 4 files changed, 22 insertions(+), 10 deletions(-) - -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index 70a0075ec5e..47f8cf0d84b 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -363,11 +364,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); - -- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size); -- if (rc < 0) -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { -- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]); -- goto fail; -+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size); -+ if (rc <= 0) -+ { -+ grub_error (GRUB_ERR_INVALID_COMMAND, -+ N_("%s has invalid signature"), argv[0]); -+ goto fail; -+ } - } - - pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset); -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index ac8dfd40c61..d41e8ea14a8 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -1084,6 +1084,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - - return 0; - } -+ // -1 fall-through to fail - - fail: - if (dev) -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index e8b9ecb17f6..9260731c107 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -33,6 +33,7 @@ struct grub_efi_shim_lock - }; - typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; - -+// Returns 1 on success, -1 on error, 0 when not available - int - grub_linuxefi_secure_validate (void *data, grub_uint32_t size) - { -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index f992ceeef20..3cf0f9b330b 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -101,7 +102,7 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) - - pages = BYTES_TO_PAGES(size); - grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n", -- pages, (void *)max); -+ (unsigned long)pages, (void *)(unsigned long)max); - - prev_max = max; - addr = grub_efi_allocate_pages_real (max, pages, -@@ -307,12 +308,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- rc = grub_linuxefi_secure_validate (kernel, filelen); -- if (rc < 0) -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { -- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), -- argv[0]); -- goto fail; -+ rc = grub_linuxefi_secure_validate (kernel, filelen); -+ if (rc <= 0) -+ { -+ grub_error (GRUB_ERR_INVALID_COMMAND, -+ N_("%s has invalid signature"), argv[0]); -+ goto fail; -+ } - } - - lh = (struct linux_i386_kernel_header *)kernel; -@@ -386,6 +390,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); - grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", -+ (unsigned long) - MIN((grub_size_t)0x202+setup_header_end_offset, - sizeof (*params)) - 0x1f1, - (grub_uint8_t *)kernel + 0x1f1, diff --git a/0144-Fix-const-char-pointers-in-grub-core-net-bootp.c.patch b/0144-Fix-const-char-pointers-in-grub-core-net-bootp.c.patch deleted file mode 100644 index 9b0db5f..0000000 --- a/0144-Fix-const-char-pointers-in-grub-core-net-bootp.c.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/bootp.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/bootp.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index 8fb8918ae7e..7baf3540c81 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -329,7 +329,7 @@ grub_net_configure_by_dhcp_ack (const char *name, - struct grub_net_network_level_interface *inter; - int mask = -1; - char server_ip[sizeof ("xxx.xxx.xxx.xxx")]; -- const grub_uint8_t *opt; -+ const char *opt; - grub_uint8_t opt_len, overload = 0; - const char *boot_file = 0, *server_name = 0; - grub_size_t boot_file_len, server_name_len; -@@ -505,7 +505,7 @@ grub_net_configure_by_dhcp_ack (const char *name, - if (opt && opt_len) - { - grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len); -- if (opt && grub_strcmp (opt, "HTTPClient") == 0) -+ if (opt && grub_strcmp ((char *)opt, "HTTPClient") == 0) - { - char *proto, *ip, *pa; - diff --git a/0145-Fix-const-char-pointers-in-grub-core-net-efi-ip4_con.patch b/0145-Fix-const-char-pointers-in-grub-core-net-efi-ip4_con.patch deleted file mode 100644 index 6c16e9e..0000000 --- a/0145-Fix-const-char-pointers-in-grub-core-net-efi-ip4_con.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/ip4_config.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/ip4_config.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c -index 9725e928f7e..cb880fc3e8f 100644 ---- a/grub-core/net/efi/ip4_config.c -+++ b/grub-core/net/efi/ip4_config.c -@@ -61,7 +61,8 @@ int - grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *address, const char **rest) - { - grub_uint32_t newip = 0; -- int i, ncolon = 0; -+ grub_size_t i; -+ int ncolon = 0; - const char *ptr = val; - - /* Check that is not an IPv6 address */ -@@ -78,7 +79,7 @@ grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *addres - for (i = 0; i < 4; i++) - { - unsigned long t; -- t = grub_strtoul (ptr, (char **) &ptr, 0); -+ t = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; diff --git a/0146-Fix-const-char-pointers-in-grub-core-net-efi-ip6_con.patch b/0146-Fix-const-char-pointers-in-grub-core-net-efi-ip6_con.patch deleted file mode 100644 index 7c29683..0000000 --- a/0146-Fix-const-char-pointers-in-grub-core-net-efi-ip6_con.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/ip6_config.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/ip6_config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c -index a46f6f9b685..1c5415d7185 100644 ---- a/grub-core/net/efi/ip6_config.c -+++ b/grub-core/net/efi/ip6_config.c -@@ -85,7 +85,7 @@ grub_efi_string_to_ip6_address (const char *val, grub_efi_ipv6_address_t *addres - ptr++; - continue; - } -- t = grub_strtoul (ptr, (char **) &ptr, 16); -+ t = grub_strtoul (ptr, &ptr, 16); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; diff --git a/0147-Fix-const-char-pointers-in-grub-core-net-efi-net.c.patch b/0147-Fix-const-char-pointers-in-grub-core-net-efi-net.c.patch deleted file mode 100644 index 0fe90c8..0000000 --- a/0147-Fix-const-char-pointers-in-grub-core-net-efi-net.c.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/net.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/net.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index a3f0535d43c..78e5442fc52 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -729,7 +729,7 @@ grub_efi_net_parse_address (const char *address, - { - grub_uint32_t subnet_mask_size; - -- subnet_mask_size = grub_strtoul (rest + 1, (char **) &rest, 0); -+ subnet_mask_size = grub_strtoul (rest + 1, &rest, 0); - - if (!grub_errno && subnet_mask_size <= 32 && *rest == 0) - { -@@ -758,7 +758,7 @@ grub_efi_net_parse_address (const char *address, - { - grub_efi_uint8_t prefix_length; - -- prefix_length = grub_strtoul (rest + 1, (char **) &rest, 0); -+ prefix_length = grub_strtoul (rest + 1, &rest, 0); - if (!grub_errno && prefix_length <= 128 && *rest == 0) - { - ip6->prefix_length = prefix_length; diff --git a/0148-Fix-const-char-pointers-in-grub-core-net-efi-pxe.c.patch b/0148-Fix-const-char-pointers-in-grub-core-net-efi-pxe.c.patch deleted file mode 100644 index 59f29e4..0000000 --- a/0148-Fix-const-char-pointers-in-grub-core-net-efi-pxe.c.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/pxe.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/pxe.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/grub-core/net/efi/pxe.c b/grub-core/net/efi/pxe.c -index 531949cba5c..73e2bb01c1b 100644 ---- a/grub-core/net/efi/pxe.c -+++ b/grub-core/net/efi/pxe.c -@@ -187,7 +187,7 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) - ptr++; - continue; - } -- t = grub_strtoul (ptr, (char **) &ptr, 16); -+ t = grub_strtoul (ptr, &ptr, 16); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; -@@ -225,7 +225,7 @@ pxe_open (struct grub_efi_net_device *dev, - int type __attribute__((unused))) - { - int i; -- char *p; -+ const char *p; - grub_efi_status_t status; - grub_efi_pxe_ip_address_t server_ip; - grub_efi_uint64_t file_size = 0; -@@ -313,7 +313,7 @@ pxe_read (struct grub_efi_net_device *dev, - grub_size_t len) - { - int i; -- char *p; -+ const char *p; - grub_efi_status_t status; - grub_efi_pxe_t *pxe = (prefer_ip6) ? dev->ip6_pxe : dev->ip4_pxe; - grub_efi_uint64_t bufsz = len; diff --git a/0149-Add-systemd-integration-scripts-to-make-systemctl-re.patch b/0149-Add-systemd-integration-scripts-to-make-systemctl-re.patch deleted file mode 100644 index 8e2481e..0000000 --- a/0149-Add-systemd-integration-scripts-to-make-systemctl-re.patch +++ /dev/null @@ -1,190 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 22 Jul 2020 14:03:42 +0200 -Subject: [PATCH] Add systemd integration scripts to make "systemctl reboot - --boot-loader-menu=xxx" work with grub - -This commit adds a number of scripts / config files to make -"systemctl reboot --boot-loader-menu=xxx" work with grub: - -1. /lib/systemd/system/systemd-logind.service.d/10-grub.conf -This sets SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU in the env. for logind, -indicating that the boot-loader which is used supports this feature, see: -https://github.com/systemd/systemd/blob/master/docs/ENVIRONMENT.md - -2. /lib/systemd/system/grub-systemd-integration.service - /lib/systemd/system/reboot.target.wants/grub-systemd-integration.service -> - ../grub-systemd-integration.service - /usr/libexec/grub/grub-systemd-integration.sh - -The symlink in the .wants dir causes the added service file to be started -by systemd just before rebooting the system. -If /run/systemd/reboot-to-boot-loader-menu exist then the service will run -the grub-systemd-integration.sh script. -This script sets the new menu_show_once_timeout grubenv variable to the -requested timeout in seconds. - -3. /etc/grub.d/14_menu_show_once - -This new grub-mkconfig snippet adds the necessary code to the generated -grub.conf to honor the new menu_show_once_timeout variable, and to -automatically clear it after consuming it. - -Note the service and libexec script use grub-systemd-integration as name -because in the future they may be used to add further integration with -systemctl reboot --foo options, e.g. support for --boot-loader-entry=NAME. - -A few notes about upstreaming this patch from the rhboot grub2 fork: -1. I have deliberately put the grub.conf bits for this in a new / separate - grub-mkconfig snippet generator for easy upstreaming -2. Even though the commit message mentions the .wants symlink for the .service - I have been unable to come up with a clean way to do this at "make install" - time, this should be fixed before upstreaming. - -Downstream notes: -1. Since make install does not add the .wants symlink, this needs to be done - in grub2.spec %install -2. This is keeping support for the "old" Fedora specific menu_show_once env - variable, which has a hardcoded timeout of 60 sec in 12_menu_auto_hide in - place for now. This can be dropped (eventually) in a follow-up patch once - GNOME has been converted to use the systemd dbus API equivalent of - "systemctl reboot --boot-loader-menu=xxx". - -Signed-off-by: Hans de Goede ---- - Makefile.util.def | 27 ++++++++++++++++++++++++ - conf/Makefile.common | 6 ++++++ - util/grub.d/14_menu_show_once.in | 13 ++++++++++++ - util/systemd/10-grub-logind-service.conf.in | 2 ++ - util/systemd/grub-systemd-integration.service.in | 8 +++++++ - util/systemd/systemd-integration.sh.in | 6 ++++++ - 6 files changed, 62 insertions(+) - create mode 100755 util/grub.d/14_menu_show_once.in - create mode 100644 util/systemd/10-grub-logind-service.conf.in - create mode 100644 util/systemd/grub-systemd-integration.service.in - create mode 100644 util/systemd/systemd-integration.sh.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 2e6ad979c3e..9927c2cfd6a 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -470,6 +470,12 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = '14_menu_show_once'; -+ common = util/grub.d/14_menu_show_once.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '01_users'; - common = util/grub.d/01_users.in; -@@ -569,6 +575,27 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = 'grub-systemd-integration.service'; -+ common = util/systemd/grub-systemd-integration.service.in; -+ installdir = systemdunit; -+ condition = COND_HOST_LINUX; -+}; -+ -+script = { -+ name = 'systemd-integration.sh'; -+ common = util/systemd/systemd-integration.sh.in; -+ installdir = grublibexec; -+ condition = COND_HOST_LINUX; -+}; -+ -+script = { -+ name = '10-grub-logind-service.conf'; -+ common = util/systemd/10-grub-logind-service.conf.in; -+ installdir = systemd_logind_service_d; -+ condition = COND_HOST_LINUX; -+}; -+ - program = { - mansection = 1; - name = grub-mkrescue; -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 0647c53b916..9fe5863b2d9 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -63,8 +63,11 @@ CCASFLAGS_LIBRARY = $(UTILS_CCASFLAGS) - # Other variables - - grubconfdir = $(sysconfdir)/grub.d -+grublibexecdir = $(libexecdir)/$(grubdirname) - platformdir = $(pkglibdir)/$(target_cpu)-$(platform) - starfielddir = $(pkgdatadir)/themes/starfield -+systemdunitdir = ${prefix}/lib/systemd/system -+systemd_logind_service_ddir = $(systemdunitdir)/systemd-logind.service.d - - CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Werror=trampolines -fno-trampolines - CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib -@@ -121,6 +124,9 @@ noinst_LIBRARIES = - dist_noinst_DATA = - platform_SCRIPTS = - platform_PROGRAMS = -+grublibexec_SCRIPTS = -+systemdunit_SCRIPTS = -+systemd_logind_service_d_SCRIPTS = - - TESTS = - EXTRA_DIST = -diff --git a/util/grub.d/14_menu_show_once.in b/util/grub.d/14_menu_show_once.in -new file mode 100755 -index 00000000000..1cd7f36142b ---- /dev/null -+++ b/util/grub.d/14_menu_show_once.in -@@ -0,0 +1,13 @@ -+#! /bin/sh -+# Force the menu to be shown once, with a timeout of ${menu_show_once_timeout} -+# if requested by ${menu_show_once_timeout} being set in the env. -+cat << EOF -+if [ x\$feature_timeout_style = xy ]; then -+ if [ "\${menu_show_once_timeout}" ]; then -+ set timeout_style=menu -+ set timeout="\${menu_show_once_timeout}" -+ unset menu_show_once_timeout -+ save_env menu_show_once_timeout -+ fi -+fi -+EOF -diff --git a/util/systemd/10-grub-logind-service.conf.in b/util/systemd/10-grub-logind-service.conf.in -new file mode 100644 -index 00000000000..f2d4ac00732 ---- /dev/null -+++ b/util/systemd/10-grub-logind-service.conf.in -@@ -0,0 +1,2 @@ -+[Service] -+Environment=SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU=true -diff --git a/util/systemd/grub-systemd-integration.service.in b/util/systemd/grub-systemd-integration.service.in -new file mode 100644 -index 00000000000..c81fb594ce1 ---- /dev/null -+++ b/util/systemd/grub-systemd-integration.service.in -@@ -0,0 +1,8 @@ -+[Unit] -+Description=Grub2 systemctl reboot --boot-loader-menu=... support -+Before=umount.target systemd-reboot.service -+DefaultDependencies=no -+ConditionPathExists=/run/systemd/reboot-to-boot-loader-menu -+ -+[Service] -+ExecStart=@libexecdir@/@grubdirname@/systemd-integration.sh -diff --git a/util/systemd/systemd-integration.sh.in b/util/systemd/systemd-integration.sh.in -new file mode 100644 -index 00000000000..dc1218597bc ---- /dev/null -+++ b/util/systemd/systemd-integration.sh.in -@@ -0,0 +1,6 @@ -+#!/bin/sh -+ -+TIMEOUT_USEC=$(cat /run/systemd/reboot-to-boot-loader-menu) -+TIMEOUT=$(((TIMEOUT_USEC + 500000) / 1000000)) -+ -+@grub_editenv@ - set menu_show_once_timeout=$TIMEOUT diff --git a/0150-systemd-integration.sh-Also-set-old-menu_show_once-g.patch b/0150-systemd-integration.sh-Also-set-old-menu_show_once-g.patch deleted file mode 100644 index 9021de5..0000000 --- a/0150-systemd-integration.sh-Also-set-old-menu_show_once-g.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 23 Jul 2020 09:27:36 +0200 -Subject: [PATCH] systemd-integration.sh: Also set old menu_show_once grubenv - var - -Downstream RH / Fedora patch for compatibility with old, not (yet) -regenerated grub.cfg files which miss the menu_show_once_timeout check. -This older grubenv variable leads to a fixed timeout of 60 seconds. - -Note that the new menu_show_once_timeout will overrule these 60 seconds -if both are set and the grub.cfg does have the menu_show_once_timeout -check. - -Signed-off-by: Hans de Goede ---- - util/systemd/systemd-integration.sh.in | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/util/systemd/systemd-integration.sh.in b/util/systemd/systemd-integration.sh.in -index dc1218597bc..a4c071c5b0c 100644 ---- a/util/systemd/systemd-integration.sh.in -+++ b/util/systemd/systemd-integration.sh.in -@@ -4,3 +4,8 @@ TIMEOUT_USEC=$(cat /run/systemd/reboot-to-boot-loader-menu) - TIMEOUT=$(((TIMEOUT_USEC + 500000) / 1000000)) - - @grub_editenv@ - set menu_show_once_timeout=$TIMEOUT -+ -+# Downstream RH / Fedora patch for compatibility with old, not (yet) -+# regenerated grub.cfg files which miss the menu_show_once_timeout check -+# this older grubenv variable leads to a fixed timeout of 60 seconds -+@grub_editenv@ - set menu_show_once=1 diff --git a/0151-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch b/0151-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch deleted file mode 100644 index c338840..0000000 --- a/0151-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Thu, 3 Dec 2020 09:13:24 +0100 -Subject: [PATCH] at_keyboard: use set 1 when keyboard is in Translate mode -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When keyboard controller acts in Translate mode (0x40 mask), then use -set 1 since translation is done. -Otherwise use the mode queried from the controller (usually set 2). - -Added "atkeyb" debugging messages in at_keyboard module as well. - -Resolves: rhbz#1897587 - -Tested on: -- Asus N53SN (set 1 used) -- Dell Precision (set 1 used) -- HP Elitebook (set 2 used) -- HP G5430 (set 1 used, keyboard in XT mode!) -- Lenovo P71 & Lenovo T460s (set 2 used) -- QEMU/KVM (set 1 used) - -Signed-off-by: Renaud Métrich ---- - grub-core/term/at_keyboard.c | 29 ++++++++++++++++++++++++----- - include/grub/at_keyboard.h | 4 ++++ - 2 files changed, 28 insertions(+), 5 deletions(-) - -diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c -index 597111077bd..26014382608 100644 ---- a/grub-core/term/at_keyboard.c -+++ b/grub-core/term/at_keyboard.c -@@ -135,20 +135,28 @@ query_mode (void) - int e; - - e = write_mode (0); -- if (!e) -+ if (!e) { -+ grub_dprintf("atkeyb", "query_mode: write_mode(0) failed\n"); - return 0; -+ } - - do { - keyboard_controller_wait_until_ready (); - ret = grub_inb (KEYBOARD_REG_DATA); - } while (ret == GRUB_AT_ACK); - /* QEMU translates the set even in no-translate mode. */ -- if (ret == 0x43 || ret == 1) -+ if (ret == 0x43 || ret == 1) { -+ grub_dprintf("atkeyb", "query_mode: returning 1 (ret=0x%x)\n", ret); - return 1; -- if (ret == 0x41 || ret == 2) -+ } -+ if (ret == 0x41 || ret == 2) { -+ grub_dprintf("atkeyb", "query_mode: returning 2 (ret=0x%x)\n", ret); - return 2; -- if (ret == 0x3f || ret == 3) -+ } -+ if (ret == 0x3f || ret == 3) { -+ grub_dprintf("atkeyb", "query_mode: returning 3 (ret=0x%x)\n", ret); - return 3; -+ } - return 0; - } - -@@ -165,7 +173,13 @@ set_scancodes (void) - } - - #if !USE_SCANCODE_SET -- ps2_state.current_set = 1; -+ if ((grub_keyboard_controller_orig & KEYBOARD_AT_TRANSLATE) == KEYBOARD_AT_TRANSLATE) { -+ grub_dprintf ("atkeyb", "queried set is %d but keyboard in Translate mode, so actually in set 1\n", grub_keyboard_orig_set); -+ ps2_state.current_set = 1; -+ } else { -+ grub_dprintf ("atkeyb", "using queried set %d\n", grub_keyboard_orig_set); -+ ps2_state.current_set = grub_keyboard_orig_set; -+ } - return; - #else - -@@ -266,6 +280,7 @@ grub_keyboard_controller_init (void) - grub_keyboard_orig_set = 2; - #else - grub_keyboard_controller_orig = grub_keyboard_controller_read (); -+ grub_dprintf ("atkeyb", "grub_keyboard_controller_orig = 0x%x\n", grub_keyboard_controller_orig); - grub_keyboard_orig_set = query_mode (); - #endif - set_scancodes (); -@@ -275,11 +290,15 @@ grub_keyboard_controller_init (void) - static grub_err_t - grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) - { -+/* In !USE_SCANCODE_SET mode, we didn't change anything, so nothing to restore */ -+#if USE_SCANCODE_SET - if (ps2_state.current_set == 0) - return GRUB_ERR_NONE; -+ grub_dprintf ("atkeyb", "restoring set %d, controller 0x%x\n", grub_keyboard_orig_set, grub_keyboard_controller_orig); - if (grub_keyboard_orig_set) - write_mode (grub_keyboard_orig_set); - grub_keyboard_controller_write (grub_keyboard_controller_orig); -+#endif - return GRUB_ERR_NONE; - } - -diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h -index bcb4d9ba78f..9414dc1b996 100644 ---- a/include/grub/at_keyboard.h -+++ b/include/grub/at_keyboard.h -@@ -19,6 +19,10 @@ - #ifndef GRUB_AT_KEYBOARD_HEADER - #define GRUB_AT_KEYBOARD_HEADER 1 - -+/* -+ * Refer to https://wiki.osdev.org/%228042%22_PS/2_Controller for details. -+ */ -+ - /* Used for sending commands to the controller. */ - #define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) - #define KEYBOARD_COMMAND_READ 0x20 diff --git a/0152-grub-install-disable-support-for-EFI-platforms.patch b/0152-grub-install-disable-support-for-EFI-platforms.patch deleted file mode 100644 index 41003e2..0000000 --- a/0152-grub-install-disable-support-for-EFI-platforms.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Hlavac -Date: Fri, 20 Nov 2020 23:51:47 +0100 -Subject: [PATCH] grub-install: disable support for EFI platforms - -For each platform, GRUB is shipped as a kernel image and a set of -modules. These files are then used by the grub-install utility to -install GRUB on a specific device. However, in order to support UEFI -Secure Boot, the resulting EFI binary must be signed by a recognized -private key. For this reason, for EFI platforms, most distributions also -ship prebuilt EFI binaries signed by a distribution-specific private -key. In this case, however, the grub-install utility should not be used -because it would overwrite the signed EFI binary. - -The current fix is suboptimal because it preserves all EFI-related code. -A better solution could be to modularize the code and provide a -build-time option. - -Resolves: rhbz#1737444 - -Signed-off-by: Jan Hlavac ---- - util/grub-install.c | 37 ++++++++++++++++--------------------- - docs/grub.texi | 7 +++++++ - util/grub-install.8 | 4 +++- - 3 files changed, 26 insertions(+), 22 deletions(-) - -diff --git a/util/grub-install.c b/util/grub-install.c -index a2bec7446cb..5babc7af551 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -899,6 +899,22 @@ main (int argc, char *argv[]) - - platform = grub_install_get_target (grub_install_source_directory); - -+ switch (platform) -+ { -+ case GRUB_INSTALL_PLATFORM_ARM_EFI: -+ case GRUB_INSTALL_PLATFORM_ARM64_EFI: -+ case GRUB_INSTALL_PLATFORM_I386_EFI: -+ case GRUB_INSTALL_PLATFORM_IA64_EFI: -+ case GRUB_INSTALL_PLATFORM_X86_64_EFI: -+ is_efi = 1; -+ grub_util_error (_("this utility cannot be used for EFI platforms" -+ " because it does not support UEFI Secure Boot")); -+ break; -+ default: -+ is_efi = 0; -+ break; -+ } -+ - { - char *platname = grub_install_get_platform_name (platform); - fprintf (stderr, _("Installing for %s platform.\n"), platname); -@@ -1011,28 +1027,7 @@ main (int argc, char *argv[]) - grub_hostfs_init (); - grub_host_init (); - -- switch (platform) -- { -- case GRUB_INSTALL_PLATFORM_I386_EFI: -- case GRUB_INSTALL_PLATFORM_X86_64_EFI: -- case GRUB_INSTALL_PLATFORM_ARM_EFI: -- case GRUB_INSTALL_PLATFORM_ARM64_EFI: -- case GRUB_INSTALL_PLATFORM_RISCV32_EFI: -- case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -- case GRUB_INSTALL_PLATFORM_IA64_EFI: -- is_efi = 1; -- break; -- default: -- is_efi = 0; -- break; -- -- /* pacify warning. */ -- case GRUB_INSTALL_PLATFORM_MAX: -- break; -- } -- - /* Find the EFI System Partition. */ -- - if (is_efi) - { - grub_fs_t fs; -diff --git a/docs/grub.texi b/docs/grub.texi -index 04ed6ac1f07..4870faaa00a 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -6509,6 +6509,13 @@ grub2-install @var{install_device} - The device name @var{install_device} is an OS device name or a GRUB - device name. - -+In order to support UEFI Secure Boot, the resulting GRUB EFI binary must -+be signed by a recognized private key. For this reason, for EFI -+platforms, most distributions also ship prebuilt GRUB EFI binaries -+signed by a distribution-specific private key. In this case, however, -+@command{grub2-install} should not be used because it would overwrite -+the signed EFI binary. -+ - @command{grub2-install} accepts the following options: - - @table @option -diff --git a/util/grub-install.8 b/util/grub-install.8 -index 1db89e94b3b..811d441b16c 100644 ---- a/util/grub-install.8 -+++ b/util/grub-install.8 -@@ -1,4 +1,4 @@ --.TH GRUB-INSTALL 1 "Wed Feb 26 2014" -+.TH GRUB-INSTALL 1 "Fri Nov 20 2020" - .SH NAME - \fBgrub-install\fR \(em Install GRUB on a device. - -@@ -31,6 +31,8 @@ - .SH DESCRIPTION - \fBgrub-install\fR installs GRUB onto a device. This includes copying GRUB images into the target directory (generally \fI/boot/grub\fR), and on some platforms may also include installing GRUB onto a boot sector. - -+In order to support UEFI Secure Boot, the resulting GRUB EFI binary must be signed by a recognized private key. For this reason, for EFI platforms, most distributions also ship prebuilt GRUB EFI binaries signed by a distribution-specific private key. In this case, however, the \fBgrub-install\fR utility should not be used because it would overwrite the signed EFI binary. -+ - .SH OPTIONS - .TP - \fB--modules\fR=\fIMODULES\fR\! diff --git a/0153-New-with-debug-timestamps-configure-flag-to-prepend-.patch b/0153-New-with-debug-timestamps-configure-flag-to-prepend-.patch deleted file mode 100644 index d216284..0000000 --- a/0153-New-with-debug-timestamps-configure-flag-to-prepend-.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Sat, 23 Nov 2019 14:57:41 +0100 -Subject: [PATCH] New --with-debug-timestamps configure flag to prepend debug - traces with absolute and relative timestamp -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich ---- - configure.ac | 18 ++++++++++++++++++ - grub-core/kern/misc.c | 20 ++++++++++++++++++++ - config.h.in | 1 + - 3 files changed, 39 insertions(+) - -diff --git a/configure.ac b/configure.ac -index c6bd965f1f9..3c808a72230 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1613,6 +1613,17 @@ else - fi - AC_SUBST([BOOT_TIME_STATS]) - -+AC_ARG_WITH([debug-timestamps], -+ AS_HELP_STRING([--with-debug-timestamps], -+ [prepend debug traces with absolute and relative timestamps])) -+ -+if test x$with_debug_timestamps = xyes; then -+ DEBUG_WITH_TIMESTAMPS=1 -+else -+ DEBUG_WITH_TIMESTAMPS=0 -+fi -+AC_SUBST([DEBUG_WITH_TIMESTAMPS]) -+ - AC_ARG_ENABLE([grub-emu-sdl], - [AS_HELP_STRING([--enable-grub-emu-sdl], - [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) -@@ -2194,6 +2205,7 @@ AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1]) - AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) - AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1]) - AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1]) -+AM_CONDITIONAL([COND_DEBUG_WITH_TIMESTAMPS], [test x$DEBUG_WITH_TIMESTAMPS = x1]) - - AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes]) - -@@ -2289,6 +2301,12 @@ else - echo With boot time statistics: No - fi - -+if [ x"$with_debug_timestamps" = xyes ]; then -+echo Debug traces with timestamps: Yes -+else -+echo Debug traces with timestamps: No -+fi -+ - if [ x"$efiemu_excuse" = x ]; then - echo efiemu runtime: Yes - else -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 578bf51a5fc..9f54b6b7d2d 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -25,6 +25,9 @@ - #include - #include - #include -+#if DEBUG_WITH_TIMESTAMPS -+#include -+#endif - - union printf_arg - { -@@ -192,9 +195,26 @@ grub_real_dprintf (const char *file, const int line, const char *condition, - const char *fmt, ...) - { - va_list args; -+#if DEBUG_WITH_TIMESTAMPS -+ static long unsigned int last_time = 0; -+ static int last_had_cr = 1; -+#endif - - if (grub_debug_enabled (condition)) - { -+#if DEBUG_WITH_TIMESTAMPS -+ /* Don't print timestamp if last printed message isn't terminated yet */ -+ if (last_had_cr) { -+ long unsigned int tmabs = (long unsigned int) grub_get_time_ms(); -+ long unsigned int tmrel = tmabs - last_time; -+ last_time = tmabs; -+ grub_printf ("%3lu.%03lus +%2lu.%03lus ", tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000); -+ } -+ if (fmt[grub_strlen(fmt)-1] == '\n') -+ last_had_cr = 1; -+ else -+ last_had_cr = 0; -+#endif - grub_printf ("%s:%d: ", file, line); - va_start (args, fmt); - grub_vprintf (fmt, args); -diff --git a/config.h.in b/config.h.in -index c7e316f0f1f..c80e3e0aba3 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -12,6 +12,7 @@ - /* Define to 1 to enable disk cache statistics. */ - #define DISK_CACHE_STATS @DISK_CACHE_STATS@ - #define BOOT_TIME_STATS @BOOT_TIME_STATS@ -+#define DEBUG_WITH_TIMESTAMPS @DEBUG_WITH_TIMESTAMPS@ - - /* We don't need those. */ - #define MINILZO_CFG_SKIP_LZO_PTR 1 diff --git a/0154-Added-debug-statements-to-grub_disk_open-and-grub_di.patch b/0154-Added-debug-statements-to-grub_disk_open-and-grub_di.patch deleted file mode 100644 index cbb1a38..0000000 --- a/0154-Added-debug-statements-to-grub_disk_open-and-grub_di.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Sat, 23 Nov 2019 15:22:16 +0100 -Subject: [PATCH] Added debug statements to grub_disk_open() and - grub_disk_close() on success -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich ---- - grub-core/kern/disk.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c -index e1b0e073e09..05a28ab1429 100644 ---- a/grub-core/kern/disk.c -+++ b/grub-core/kern/disk.c -@@ -285,6 +285,8 @@ grub_disk_open (const char *name) - return 0; - } - -+ grub_dprintf ("disk", "Opening `%s' succeeded.\n", name); -+ - return disk; - } - -@@ -292,7 +294,7 @@ void - grub_disk_close (grub_disk_t disk) - { - grub_partition_t part; -- grub_dprintf ("disk", "Closing `%s'.\n", disk->name); -+ grub_dprintf ("disk", "Closing `%s'...\n", disk->name); - - if (disk->dev && disk->dev->disk_close) - (disk->dev->disk_close) (disk); -@@ -306,8 +308,10 @@ grub_disk_close (grub_disk_t disk) - grub_free (disk->partition); - disk->partition = part; - } -+ grub_dprintf ("disk", "Closing `%s' succeeded.\n", disk->name); - grub_free ((void *) disk->name); - grub_free (disk); -+ - } - - /* Small read (less than cache size and not pass across cache unit boundaries). diff --git a/0155-Introduce-function-grub_debug_is_enabled-void-return.patch b/0155-Introduce-function-grub_debug_is_enabled-void-return.patch deleted file mode 100644 index 4e4718b..0000000 --- a/0155-Introduce-function-grub_debug_is_enabled-void-return.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Mon, 25 Nov 2019 09:29:53 +0100 -Subject: [PATCH] Introduce function grub_debug_is_enabled(void) returning 1 if - 'debug' is in the environment and not empty -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich ---- - grub-core/kern/misc.c | 13 +++++++++++++ - include/grub/misc.h | 1 + - 2 files changed, 14 insertions(+) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 9f54b6b7d2d..a186ad3dd41 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -163,6 +163,19 @@ int grub_err_printf (const char *fmt, ...) - __attribute__ ((alias("grub_printf"))); - #endif - -+/* Return 1 if 'debug' is set and not empty */ -+int -+grub_debug_is_enabled (void) -+{ -+ const char *debug; -+ -+ debug = grub_env_get ("debug"); -+ if (!debug || debug[0] == '\0') -+ return 0; -+ -+ return 1; -+} -+ - int - grub_debug_enabled (const char * condition) - { -diff --git a/include/grub/misc.h b/include/grub/misc.h -index 3adc4036e3b..6c4aa85ac50 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -340,6 +340,7 @@ grub_puts (const char *s) - } - - int EXPORT_FUNC(grub_puts_) (const char *s); -+int EXPORT_FUNC(grub_debug_is_enabled) (void); - int EXPORT_FUNC(grub_debug_enabled) (const char *condition); - void EXPORT_FUNC(grub_real_dprintf) (const char *file, - const int line, diff --git a/0156-Don-t-clear-screen-when-debugging-is-enabled.patch b/0156-Don-t-clear-screen-when-debugging-is-enabled.patch deleted file mode 100644 index d17b080..0000000 --- a/0156-Don-t-clear-screen-when-debugging-is-enabled.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Sat, 23 Nov 2019 16:23:54 +0100 -Subject: [PATCH] Don't clear screen when debugging is enabled -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich -[rharwood@redhat.com: rebase fuzz] -Signed-off-by: Robbie Harwood ---- - grub-core/normal/main.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 1970e4816a8..4ebdbd228d4 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -215,8 +215,9 @@ grub_normal_init_page (struct grub_term_output *term, - char *msg_formatted; - grub_uint32_t *unicode_msg; - grub_uint32_t *last_position; -- -- grub_term_cls (term); -+ -+ if (! grub_debug_is_enabled ()) -+ grub_term_cls (term); - - msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION); - if (!msg_formatted) diff --git a/0157-grub_file_-instrumentation-new-file-debug-tag.patch b/0157-grub_file_-instrumentation-new-file-debug-tag.patch deleted file mode 100644 index 0cc6b8c..0000000 --- a/0157-grub_file_-instrumentation-new-file-debug-tag.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Fri, 29 Nov 2019 11:02:00 +0100 -Subject: [PATCH] grub_file_* instrumentation (new 'file' debug tag) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich ---- - grub-core/kern/file.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c -index 58454458c47..e19aea3e514 100644 ---- a/grub-core/kern/file.c -+++ b/grub-core/kern/file.c -@@ -66,6 +66,8 @@ grub_file_open (const char *name, enum grub_file_type type) - const char *file_name; - grub_file_filter_id_t filter; - -+ grub_dprintf ("file", "Opening `%s' ...\n", name); -+ - device_name = grub_file_get_device_name (name); - if (grub_errno) - goto fail; -@@ -128,6 +130,8 @@ grub_file_open (const char *name, enum grub_file_type type) - if (!file) - grub_file_close (last_file); - -+ grub_dprintf ("file", "Opening `%s' succeeded.\n", name); -+ - return file; - - fail: -@@ -138,6 +142,8 @@ grub_file_open (const char *name, enum grub_file_type type) - - grub_free (file); - -+ grub_dprintf ("file", "Opening `%s' failed.\n", name); -+ - return 0; - } - -@@ -169,6 +175,7 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) - - if (len == 0) - return 0; -+ - read_hook = file->read_hook; - read_hook_data = file->read_hook_data; - if (!file->read_hook) -@@ -189,11 +196,18 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) - grub_err_t - grub_file_close (grub_file_t file) - { -+ grub_dprintf ("file", "Closing `%s' ...\n", file->name); - if (file->fs->fs_close) - (file->fs->fs_close) (file); - - if (file->device) - grub_device_close (file->device); -+ -+ if (grub_errno == GRUB_ERR_NONE) -+ grub_dprintf ("file", "Closing `%s' succeeded.\n", file->name); -+ else -+ grub_dprintf ("file", "Closing `%s' failed with %d.\n", file->name, grub_errno); -+ - grub_free (file->name); - grub_free (file); - return grub_errno; diff --git a/0158-ieee1275-Avoiding-many-unecessary-open-close.patch b/0158-ieee1275-Avoiding-many-unecessary-open-close.patch deleted file mode 100644 index 6a0ad75..0000000 --- a/0158-ieee1275-Avoiding-many-unecessary-open-close.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Diego Domingos -Date: Mon, 14 Dec 2020 17:42:45 +0100 -Subject: [PATCH] ieee1275: Avoiding many unecessary open/close - -Signed-off-by: Diego Domingos ---- - grub-core/disk/ieee1275/ofdisk.c | 64 ++++++++++++++++++++++------------------ - 1 file changed, 35 insertions(+), 29 deletions(-) - -diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c -index 03674cb477e..ea7f78ac7d8 100644 ---- a/grub-core/disk/ieee1275/ofdisk.c -+++ b/grub-core/disk/ieee1275/ofdisk.c -@@ -44,7 +44,7 @@ struct ofdisk_hash_ent - }; - - static grub_err_t --grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size, -+grub_ofdisk_get_block_size (grub_uint32_t *block_size, - struct ofdisk_hash_ent *op); - - #define OFDISK_HASH_SZ 8 -@@ -461,6 +461,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) - grub_ssize_t actual; - grub_uint32_t block_size = 0; - grub_err_t err; -+ struct ofdisk_hash_ent *op; - - if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, -@@ -471,6 +472,35 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) - - grub_dprintf ("disk", "Opening `%s'.\n", devpath); - -+ op = ofdisk_hash_find (devpath); -+ if (!op) -+ op = ofdisk_hash_add (devpath, NULL); -+ if (!op) -+ { -+ grub_free (devpath); -+ return grub_errno; -+ } -+ -+ /* Check if the call to open is the same to the last disk already opened */ -+ if (last_devpath && !grub_strcmp(op->open_path,last_devpath)) -+ { -+ goto finish; -+ } -+ -+ /* If not, we need to close the previous disk and open the new one */ -+ else { -+ if (last_ihandle){ -+ grub_ieee1275_close (last_ihandle); -+ } -+ last_ihandle = 0; -+ last_devpath = NULL; -+ -+ grub_ieee1275_open (op->open_path, &last_ihandle); -+ if (! last_ihandle) -+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); -+ last_devpath = op->open_path; -+ } -+ - if (grub_ieee1275_finddevice (devpath, &dev)) - { - grub_free (devpath); -@@ -491,25 +521,18 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device"); - } - -+ -+ finish: - /* XXX: There is no property to read the number of blocks. There - should be a property `#blocks', but it is not there. Perhaps it - is possible to use seek for this. */ - disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; - - { -- struct ofdisk_hash_ent *op; -- op = ofdisk_hash_find (devpath); -- if (!op) -- op = ofdisk_hash_add (devpath, NULL); -- if (!op) -- { -- grub_free (devpath); -- return grub_errno; -- } - disk->id = (unsigned long) op; - disk->data = op->open_path; - -- err = grub_ofdisk_get_block_size (devpath, &block_size, op); -+ err = grub_ofdisk_get_block_size (&block_size, op); - if (err) - { - grub_free (devpath); -@@ -532,13 +555,6 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) - static void - grub_ofdisk_close (grub_disk_t disk) - { -- if (disk->data == last_devpath) -- { -- if (last_ihandle) -- grub_ieee1275_close (last_ihandle); -- last_ihandle = 0; -- last_devpath = NULL; -- } - disk->data = 0; - } - -@@ -685,7 +701,7 @@ grub_ofdisk_init (void) - } - - static grub_err_t --grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size, -+grub_ofdisk_get_block_size (grub_uint32_t *block_size, - struct ofdisk_hash_ent *op) - { - struct size_args_ieee1275 -@@ -698,16 +714,6 @@ grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size, - grub_ieee1275_cell_t size2; - } args_ieee1275; - -- if (last_ihandle) -- grub_ieee1275_close (last_ihandle); -- -- last_ihandle = 0; -- last_devpath = NULL; -- -- grub_ieee1275_open (device, &last_ihandle); -- if (! last_ihandle) -- return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); -- - *block_size = 0; - - if (op->block_size_fails >= 2) diff --git a/0159-ieee1275-powerpc-implements-fibre-channel-discovery-.patch b/0159-ieee1275-powerpc-implements-fibre-channel-discovery-.patch deleted file mode 100644 index 9fa02bb..0000000 --- a/0159-ieee1275-powerpc-implements-fibre-channel-discovery-.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Diego Domingos -Date: Mon, 14 Dec 2020 17:45:28 +0100 -Subject: [PATCH] ieee1275/powerpc: implements fibre channel discovery for - ofpathname - -grub-ofpathname doesn't work with fibre channel because there is no -function currently implemented for it. -This patch enables it by prividing a function that looks for the port -name, building the entire path for OF devices. - -Signed-off-by: Diego Domingos ---- - grub-core/osdep/linux/ofpath.c | 49 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 49 insertions(+) - -diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c -index a6153d35954..0f5d54e9f2d 100644 ---- a/grub-core/osdep/linux/ofpath.c -+++ b/grub-core/osdep/linux/ofpath.c -@@ -350,6 +350,38 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi - return ret; - } - -+ -+static void -+of_fc_port_name(const char *path, const char *subpath, char *port_name) -+{ -+ char *bname, *basepath, *p; -+ int fd; -+ -+ bname = xmalloc(sizeof(char)*150); -+ basepath = xmalloc(strlen(path)); -+ -+ /* Generate the path to get port name information from the drive */ -+ strncpy(basepath,path,subpath-path); -+ basepath[subpath-path-1] = '\0'; -+ p = get_basename(basepath); -+ snprintf(bname,sizeof(char)*150,"%s/fc_transport/%s/port_name",basepath,p); -+ -+ /* Read the information from the port name */ -+ fd = open (bname, O_RDONLY); -+ if (fd < 0) -+ grub_util_error (_("cannot open `%s': %s"), bname, strerror (errno)); -+ -+ if (read(fd,port_name,sizeof(char)*19) < 0) -+ grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno)); -+ -+ sscanf(port_name,"0x%s",port_name); -+ -+ close(fd); -+ -+ free(bname); -+ free(basepath); -+} -+ - #ifdef __sparc__ - static char * - of_path_of_nvme(const char *sys_devname __attribute__((unused)), -@@ -577,6 +609,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev - digit_string = trailing_digits (device); - if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0) - { -+ if(strstr(of_path,"vfc-client")) -+ { -+ char * port_name = xmalloc(sizeof(char)*17); -+ of_fc_port_name(sysfs_path, p, port_name); -+ -+ snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name); -+ free(port_name); -+ } -+ else -+ { - unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun; - if (*digit_string == '\0') - { -@@ -590,6 +632,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev - snprintf(disk, sizeof (disk), - "/%s@%04lx000000000000:%c", disk_name, id, 'a' + (part - 1)); - } -+ } -+ } else if (strstr(of_path,"fibre-channel")||(strstr(of_path,"vfc-client"))){ -+ char * port_name = xmalloc(sizeof(char)*17); -+ of_fc_port_name(sysfs_path, p, port_name); -+ -+ snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name); -+ free(port_name); - } - else - { diff --git a/0160-ieee1275-powerpc-enables-device-mapper-discovery.patch b/0160-ieee1275-powerpc-enables-device-mapper-discovery.patch deleted file mode 100644 index 6f1c21b..0000000 --- a/0160-ieee1275-powerpc-enables-device-mapper-discovery.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Diego Domingos -Date: Mon, 14 Dec 2020 17:47:16 +0100 -Subject: [PATCH] ieee1275/powerpc: enables device mapper discovery - -this patch enables the device mapper discovery on ofpath.c. Currently, -when we are dealing with a device like /dev/dm-* the ofpath returns null -since there is no function implemented to handle this case. - -This patch implements a function that will look into /sys/block/dm-* -devices and search recursively inside slaves directory to find the root -disk. - -Signed-off-by: Diego Domingos ---- - grub-core/osdep/linux/ofpath.c | 64 +++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 63 insertions(+), 1 deletion(-) - -diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c -index 0f5d54e9f2d..cc849d9c94c 100644 ---- a/grub-core/osdep/linux/ofpath.c -+++ b/grub-core/osdep/linux/ofpath.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #ifdef __sparc__ - typedef enum -@@ -755,13 +756,74 @@ strip_trailing_digits (const char *p) - return new; - } - -+static char * -+get_slave_from_dm(const char * device){ -+ char *curr_device, *tmp; -+ char *directory; -+ char *ret = NULL; -+ -+ directory = grub_strdup (device); -+ tmp = get_basename(directory); -+ curr_device = grub_strdup (tmp); -+ *tmp = '\0'; -+ -+ /* Recursively check for slaves devices so we can find the root device */ -+ while ((curr_device[0] == 'd') && (curr_device[1] == 'm') && (curr_device[2] == '-')){ -+ DIR *dp; -+ struct dirent *ep; -+ char* device_path; -+ -+ device_path = grub_xasprintf ("/sys/block/%s/slaves", curr_device); -+ dp = opendir(device_path); -+ free(device_path); -+ -+ if (dp != NULL) -+ { -+ ep = readdir (dp); -+ while (ep != NULL){ -+ -+ /* avoid some system directories */ -+ if (!strcmp(ep->d_name,".")) -+ goto next_dir; -+ if (!strcmp(ep->d_name,"..")) -+ goto next_dir; -+ -+ free (curr_device); -+ free (ret); -+ curr_device = grub_strdup (ep->d_name); -+ ret = grub_xasprintf ("%s%s", directory, curr_device); -+ break; -+ -+ next_dir: -+ ep = readdir (dp); -+ continue; -+ } -+ closedir (dp); -+ } -+ else -+ grub_util_warn (_("cannot open directory `%s'"), device_path); -+ } -+ -+ free (directory); -+ free (curr_device); -+ -+ return ret; -+} -+ - char * - grub_util_devname_to_ofpath (const char *sys_devname) - { -- char *name_buf, *device, *devnode, *devicenode, *ofpath; -+ char *name_buf, *device, *devnode, *devicenode, *ofpath, *realname; - - name_buf = xrealpath (sys_devname); - -+ realname = get_slave_from_dm (name_buf); -+ if (realname) -+ { -+ free (name_buf); -+ name_buf = realname; -+ } -+ - device = get_basename (name_buf); - devnode = strip_trailing_digits (name_buf); - devicenode = strip_trailing_digits (device); diff --git a/0161-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch b/0161-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch deleted file mode 100644 index 01e7e67..0000000 --- a/0161-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch +++ /dev/null @@ -1,245 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Fri, 18 Dec 2020 15:39:26 +0100 -Subject: [PATCH] Add 'at_keyboard_fallback_set' var to force the set manually -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This seems required with HP DL380p Gen 8 systems. -Indeed, with this system, we can see the following sequence: - -1. controller is queried to get current configuration (returns 0x30 which is quite standard) -2. controller is queried to get the current keyboard set in used, using code 0xf0 (first part) -3. controller answers with 0xfa which means "ACK" (== ok) -4. then we send "0" to tell "we want to know which set your are supporting" -5. controller answers with 0xfa ("ACK") -6. controller should then give us 1, 2, 3 or 0x43, 0x41, 0x3f, but here it gives us 0xfe which means "NACK" - -Since there seems no way to determine the current set, and in fact the -controller expects set2 to be used, we need to rely on an environment -variable. -Everything has been tested on this system: using 0xFE (resend command), -making sure we wait for ACK in the 2 steps "write_mode", etc. - -Below is litterature I used to come up with "there is no other -solution": -- https://wiki.osdev.org/%228042%22_PS/2_Controller -- http://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm -- http://www.s100computers.com/My%20System%20Pages/MSDOS%20Board/PC%20Keyboard.pdf - -Signed-off-by: Renaud Métrich -Signed-off-by: Robbie Harwood ---- - grub-core/term/at_keyboard.c | 121 ++++++++++++++++++++++++++++++++++--------- - 1 file changed, 96 insertions(+), 25 deletions(-) - -diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c -index 26014382608..dac0f946fe6 100644 ---- a/grub-core/term/at_keyboard.c -+++ b/grub-core/term/at_keyboard.c -@@ -31,6 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - static grub_uint8_t grub_keyboard_controller_orig; - static grub_uint8_t grub_keyboard_orig_set; - struct grub_ps2_state ps2_state; -+static int fallback_set; - - static int ping_sent; - -@@ -76,6 +77,8 @@ at_command (grub_uint8_t data) - break; - return 0; - } -+ if (i == GRUB_AT_TRIES) -+ grub_dprintf ("atkeyb", "at_command() timed out! (stopped after %d tries)\n", i); - return (i != GRUB_AT_TRIES); - } - -@@ -105,6 +108,21 @@ grub_keyboard_controller_read (void) - - #endif - -+static int -+resend_last_result (void) -+{ -+ grub_uint8_t ret; -+ keyboard_controller_wait_until_ready (); -+ grub_dprintf ("atkeyb", "resend_last_result: sending 0xfe\n"); -+ grub_outb (0xfe, KEYBOARD_REG_DATA); -+ ret = wait_ack (); -+ grub_dprintf ("atkeyb", "resend_last_result: wait_ack() returned 0x%x\n", ret); -+ keyboard_controller_wait_until_ready (); -+ ret = grub_inb (KEYBOARD_REG_DATA); -+ grub_dprintf ("atkeyb", "resend_last_result: read 0x%x from controller\n", ret); -+ return ret; -+} -+ - static int - write_mode (int mode) - { -@@ -113,11 +131,14 @@ write_mode (int mode) - { - grub_uint8_t ack; - keyboard_controller_wait_until_ready (); -+ grub_dprintf ("atkeyb", "write_mode: sending 0xf0\n"); - grub_outb (0xf0, KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); -+ grub_dprintf ("atkeyb", "write_mode: sending mode %d\n", mode); - grub_outb (mode, KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); - ack = wait_ack (); -+ grub_dprintf ("atkeyb", "write_mode: wait_ack() returned 0x%x\n", ack); - if (ack == GRUB_AT_NACK) - continue; - if (ack == GRUB_AT_ACK) -@@ -125,6 +146,9 @@ write_mode (int mode) - return 0; - } - -+ if (i == GRUB_AT_TRIES) -+ grub_dprintf ("atkeyb", "write_mode() timed out! (stopped after %d tries)\n", i); -+ - return (i != GRUB_AT_TRIES); - } - -@@ -132,31 +156,66 @@ static int - query_mode (void) - { - grub_uint8_t ret; -+ grub_uint64_t endtime; -+ unsigned i; - int e; -+ char *envvar; - -- e = write_mode (0); -- if (!e) { -- grub_dprintf("atkeyb", "query_mode: write_mode(0) failed\n"); -- return 0; -- } -+ for (i = 0; i < GRUB_AT_TRIES; i++) { -+ grub_dprintf ("atkeyb", "query_mode: sending command to controller\n"); -+ e = write_mode (0); -+ if (!e) { -+ grub_dprintf ("atkeyb", "query_mode: write_mode(0) failed\n"); -+ return 0; -+ } - -- do { -- keyboard_controller_wait_until_ready (); -- ret = grub_inb (KEYBOARD_REG_DATA); -- } while (ret == GRUB_AT_ACK); -- /* QEMU translates the set even in no-translate mode. */ -- if (ret == 0x43 || ret == 1) { -- grub_dprintf("atkeyb", "query_mode: returning 1 (ret=0x%x)\n", ret); -- return 1; -- } -- if (ret == 0x41 || ret == 2) { -- grub_dprintf("atkeyb", "query_mode: returning 2 (ret=0x%x)\n", ret); -- return 2; -+ endtime = grub_get_time_ms () + 20; -+ do { -+ keyboard_controller_wait_until_ready (); -+ ret = grub_inb (KEYBOARD_REG_DATA); -+ grub_dprintf ("atkeyb", "query_mode/loop: read 0x%x from controller\n", ret); -+ } while ((ret == GRUB_AT_ACK || ret == GRUB_AT_NACK) && grub_get_time_ms () < endtime); -+ if (ret == 0xfe) { -+ grub_dprintf ("atkeyb", "query_mode: asking controller to resend last result\n"); -+ ret = resend_last_result(); -+ grub_dprintf ("atkeyb", "query_mode: read 0x%x from controller\n", ret); -+ } -+ /* QEMU translates the set even in no-translate mode. */ -+ if (ret == 0x43 || ret == 1) { -+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 1\n", ret); -+ return 1; -+ } -+ if (ret == 0x41 || ret == 2) { -+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 2\n", ret); -+ return 2; -+ } -+ if (ret == 0x3f || ret == 3) { -+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 3\n", ret); -+ return 3; -+ } -+ grub_dprintf ("atkeyb", "query_mode: controller returned unexpected value 0x%x, retrying\n", ret); - } -- if (ret == 0x3f || ret == 3) { -- grub_dprintf("atkeyb", "query_mode: returning 3 (ret=0x%x)\n", ret); -- return 3; -+ -+ /* -+ * Falling here means we tried querying and the controller returned something -+ * we don't understand, try to use 'at_keyboard_fallback_set' if it exists, -+ * otherwise return 0. -+ */ -+ envvar = grub_env_get ("at_keyboard_fallback_set"); -+ if (envvar) { -+ fallback_set = grub_strtoul (envvar, 0, 10); -+ if ((grub_errno) || (fallback_set < 1) || (fallback_set > 3)) { -+ grub_dprintf ("atkeyb", "WARNING: ignoring unexpected value '%s' for '%s' variable\n", -+ envvar, "at_keyboard_fallback_set"); -+ fallback_set = 0; -+ } else { -+ grub_dprintf ("atkeyb", "query_mode: '%s' specified in environment, returning %d\n", -+ "at_keyboard_fallback_set", fallback_set); -+ } -+ return fallback_set; - } -+ grub_dprintf ("atkeyb", "WARNING: no '%s' specified in environment, returning 0\n", -+ "at_keyboard_fallback_set"); - return 0; - } - -@@ -165,14 +224,25 @@ set_scancodes (void) - { - /* You must have visited computer museum. Keyboard without scancode set - knowledge. Assume XT. */ -- if (!grub_keyboard_orig_set) -- { -- grub_dprintf ("atkeyb", "No sets support assumed\n"); -- ps2_state.current_set = 1; -+ if (!grub_keyboard_orig_set) { -+ if (fallback_set) { -+ grub_dprintf ("atkeyb", "No sets support assumed but set forced to %d\n", fallback_set); -+ ps2_state.current_set = fallback_set; - return; - } -+ grub_dprintf ("atkeyb", "No sets support assumed, forcing to set 1\n"); -+ ps2_state.current_set = 1; -+ return; -+ } - - #if !USE_SCANCODE_SET -+ if (fallback_set) { -+ grub_dprintf ("atkeyb", "queried set is %d but set forced to %d\n", -+ grub_keyboard_orig_set, fallback_set); -+ ps2_state.current_set = fallback_set; -+ return; -+ } -+ - if ((grub_keyboard_controller_orig & KEYBOARD_AT_TRANSLATE) == KEYBOARD_AT_TRANSLATE) { - grub_dprintf ("atkeyb", "queried set is %d but keyboard in Translate mode, so actually in set 1\n", grub_keyboard_orig_set); - ps2_state.current_set = 1; -@@ -261,6 +331,7 @@ grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) - static void - grub_keyboard_controller_init (void) - { -+ grub_dprintf ("atkeyb", "initializing the controller\n"); - ps2_state.at_keyboard_status = 0; - /* Drain input buffer. */ - while (1) -@@ -282,6 +353,7 @@ grub_keyboard_controller_init (void) - grub_keyboard_controller_orig = grub_keyboard_controller_read (); - grub_dprintf ("atkeyb", "grub_keyboard_controller_orig = 0x%x\n", grub_keyboard_controller_orig); - grub_keyboard_orig_set = query_mode (); -+ grub_dprintf ("atkeyb", "grub_keyboard_orig_set = %d\n", grub_keyboard_orig_set); - #endif - set_scancodes (); - keyboard_controller_led (ps2_state.led_status); -@@ -329,7 +401,6 @@ grub_at_restore_hw (void) - return GRUB_ERR_NONE; - } - -- - static struct grub_term_input grub_at_keyboard_term = - { - .name = "at_keyboard", diff --git a/0162-Add-suport-for-signing-grub-with-an-appended-signatu.patch b/0162-Add-suport-for-signing-grub-with-an-appended-signatu.patch deleted file mode 100644 index caab8d5..0000000 --- a/0162-Add-suport-for-signing-grub-with-an-appended-signatu.patch +++ /dev/null @@ -1,316 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Rashmica Gupta -Date: Thu, 11 Jun 2020 11:26:23 +1000 -Subject: [PATCH] Add suport for signing grub with an appended signature - -Add infrastructure to allow firmware to verify the integrity of grub -by use of a Linux-kernel-module-style appended signature. We initially -target powerpc-ieee1275, but the code should be extensible to other -platforms. - -Usually these signatures are appended to a file without modifying the -ELF file itself. (This is what the 'sign-file' tool does, for example.) -The verifier loads the signed file from the file system and looks at the -end of the file for the appended signature. However, on powerpc-ieee1275 -platforms, the bootloader is often stored directly in the PReP partition -as raw bytes without a file-system. This makes determining the location -of an appended signature more difficult. - -To address this, we add a new ELF note. - -The name field of shall be the string "Appended-Signature", zero-padded -to 4 byte alignment. The type field shall be 0x41536967 (the ASCII values -for the string "ASig"). It must be the final section in the ELF binary. - -The description shall contain the appended signature structure as defined -by the Linux kernel. The description will also be padded to be a multiple -of 4 bytes. The padding shall be added before the appended signature -structure (not at the end) so that the final bytes of a signed ELF file -are the appended signature magic. - -A subsequent patch documents how to create a grub core.img validly signed -under this scheme. - -Signed-off-by: Daniel Axtens -Signed-off-by: Rashmica Gupta - ---- - -You can experiment with this code with a patched version of SLOF -that verifies these signatures. You can find one at: - https://github.com/daxtens/SLOF - -I will be proposing this for inclusion in a future Power Architecture -Platform Reference (PAPR). ---- - util/grub-install-common.c | 18 ++++++++++++++++-- - util/grub-mkimage.c | 15 +++++++++++++-- - util/grub-mkimagexx.c | 39 ++++++++++++++++++++++++++++++++++++++- - util/mkimage.c | 13 +++++++------ - include/grub/util/install.h | 8 ++++++-- - include/grub/util/mkimage.h | 4 ++-- - 6 files changed, 82 insertions(+), 15 deletions(-) - -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index 4e212e690c5..aab2a941f85 100644 ---- a/util/grub-install-common.c -+++ b/util/grub-install-common.c -@@ -461,10 +461,12 @@ static size_t npubkeys; - static char *sbat; - static int disable_shim_lock; - static grub_compression_t compression; -+static size_t appsig_size; - - int - grub_install_parse (int key, char *arg) - { -+ const char *end; - switch (key) - { - case 'C': -@@ -562,6 +564,12 @@ grub_install_parse (int key, char *arg) - grub_util_error (_("Unrecognized compression `%s'"), arg); - case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE: - return 1; -+ case GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE: -+ grub_errno = 0; -+ appsig_size = grub_strtol(arg, &end, 10); -+ if (grub_errno) -+ return 0; -+ return 1; - default: - return 0; - } -@@ -665,7 +673,13 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, - dir, prefix, - outname, dtb ? : "", sbat ? : "", mkimage_target, - compnames[compression], note ? "--note" : "", -- disable_shim_lock ? "--disable-shim-lock" : "", s); -+ disable_shim_lock ? "--disable-shim-lock" : "", -+ "--format '%s' --compression '%s' " -+ "--appended-signature-size %zu %s %s\n", -+ dir, prefix, -+ outname, dtb ? : "", mkimage_target, -+ compnames[compression], appsig_size, -+ note ? "--note" : "", s); - free (s); - - tgt = grub_install_get_image_target (mkimage_target); -@@ -675,7 +689,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, - grub_install_generate_image (dir, prefix, fp, outname, - modules.entries, memdisk_path, - pubkeys, npubkeys, config_path, tgt, -- note, compression, dtb, sbat, -+ note, appsig_size, compression, dtb, sbat, - disable_shim_lock); - while (dc--) - grub_install_pop_module (); -diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c -index c0d55993702..8a53310548b 100644 ---- a/util/grub-mkimage.c -+++ b/util/grub-mkimage.c -@@ -84,6 +84,7 @@ static struct argp_option options[] = { - {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0}, - {"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0}, - {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, -+ {"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0}, - { 0, 0, 0, 0, 0, 0 } - }; - -@@ -128,6 +129,7 @@ struct arguments - char *sbat; - int note; - int disable_shim_lock; -+ size_t appsig_size; - const struct grub_install_image_target_desc *image_target; - grub_compression_t comp; - }; -@@ -138,6 +140,7 @@ argp_parser (int key, char *arg, struct argp_state *state) - /* Get the input argument from argp_parse, which we - know is a pointer to our arguments structure. */ - struct arguments *arguments = state->input; -+ const char* end; - - switch (key) - { -@@ -170,6 +173,13 @@ argp_parser (int key, char *arg, struct argp_state *state) - arguments->note = 1; - break; - -+ case 'S': -+ grub_errno = 0; -+ arguments->appsig_size = grub_strtol(arg, &end, 10); -+ if (grub_errno) -+ return 0; -+ break; -+ - case 'm': - if (arguments->memdisk) - free (arguments->memdisk); -@@ -324,8 +334,9 @@ main (int argc, char *argv[]) - arguments.memdisk, arguments.pubkeys, - arguments.npubkeys, arguments.config, - arguments.image_target, arguments.note, -- arguments.comp, arguments.dtb, -- arguments.sbat, arguments.disable_shim_lock); -+ arguments.appsig_size, arguments.comp, -+ arguments.dtb, arguments.sbat, -+ arguments.disable_shim_lock); - - if (grub_util_file_sync (fp) < 0) - grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout", -diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c -index d78fa3e5330..393119486d3 100644 ---- a/util/grub-mkimagexx.c -+++ b/util/grub-mkimagexx.c -@@ -84,6 +84,15 @@ struct grub_ieee1275_note - struct grub_ieee1275_note_desc descriptor; - }; - -+#define GRUB_APPENDED_SIGNATURE_NOTE_NAME "Appended-Signature" -+#define GRUB_APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */ -+ -+struct grub_appended_signature_note -+{ -+ Elf32_Nhdr header; -+ char name[ALIGN_UP(sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME), 4)]; -+}; -+ - #define GRUB_XEN_NOTE_NAME "Xen" - - struct fixup_block_list -@@ -207,7 +216,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr) - - void - SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target, -- int note, char **core_img, size_t *core_size, -+ int note, size_t appsig_size, char **core_img, size_t *core_size, - Elf_Addr target_addr, - struct grub_mkimage_layout *layout) - { -@@ -221,6 +230,12 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc - int shnum = 4; - int string_size = sizeof (".text") + sizeof ("mods") + 1; - -+ if (appsig_size) -+ { -+ phnum++; -+ footer_size += ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4); -+ } -+ - if (image_target->id != IMAGE_LOONGSON_ELF) - phnum += 2; - -@@ -484,6 +499,28 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc - phdr->p_offset = grub_host_to_target32 (header_size + program_size); - } - -+ if (appsig_size) { -+ int note_size = ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4); -+ struct grub_appended_signature_note *note_ptr = (struct grub_appended_signature_note *) -+ (elf_img + program_size + header_size + (note ? sizeof (struct grub_ieee1275_note) : 0)); -+ -+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME)); -+ /* needs to sit at the end, so we round this up and sign some zero padding */ -+ note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(appsig_size, 4)); -+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_APPENDED_SIGNATURE_NOTE_TYPE); -+ strcpy (note_ptr->name, GRUB_APPENDED_SIGNATURE_NOTE_NAME); -+ -+ phdr++; -+ phdr->p_type = grub_host_to_target32 (PT_NOTE); -+ phdr->p_flags = grub_host_to_target32 (PF_R); -+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); -+ phdr->p_vaddr = 0; -+ phdr->p_paddr = 0; -+ phdr->p_filesz = grub_host_to_target32 (note_size); -+ phdr->p_memsz = 0; -+ phdr->p_offset = grub_host_to_target32 (header_size + program_size + (note ? sizeof (struct grub_ieee1275_note) : 0)); -+ } -+ - { - char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr) - + shnum * sizeof (*shdr)); -diff --git a/util/mkimage.c b/util/mkimage.c -index a26cf76f72f..bab12276010 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -869,8 +869,9 @@ grub_install_generate_image (const char *dir, const char *prefix, - char *memdisk_path, char **pubkey_paths, - size_t npubkeys, char *config_path, - const struct grub_install_image_target_desc *image_target, -- int note, grub_compression_t comp, const char *dtb_path, -- const char *sbat_path, int disable_shim_lock) -+ int note, size_t appsig_size, grub_compression_t comp, -+ const char *dtb_path, const char *sbat_path, -+ int disable_shim_lock) - { - char *kernel_img, *core_img; - size_t total_module_size, core_size; -@@ -1773,11 +1774,11 @@ grub_install_generate_image (const char *dir, const char *prefix, - else - target_addr = image_target->link_addr; - if (image_target->voidp_sizeof == 4) -- grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size, -- target_addr, &layout); -+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img, -+ &core_size, target_addr, &layout); - else -- grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size, -- target_addr, &layout); -+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img, -+ &core_size, target_addr, &layout); - } - break; - } -diff --git a/include/grub/util/install.h b/include/grub/util/install.h -index 7df3191f47e..cf4531e02b6 100644 ---- a/include/grub/util/install.h -+++ b/include/grub/util/install.h -@@ -67,6 +67,9 @@ - N_("SBAT metadata"), 0 }, \ - { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \ - N_("disable shim_lock verifier"), 0 }, \ -+ { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\ -+ "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \ -+ 1}, \ - { "verbose", 'v', 0, 0, \ - N_("print verbose messages."), 1 } - -@@ -128,7 +131,8 @@ enum grub_install_options { - GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, - GRUB_INSTALL_OPTIONS_DTB, - GRUB_INSTALL_OPTIONS_SBAT, -- GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK -+ GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, -+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE - }; - - extern char *grub_install_source_directory; -@@ -188,7 +192,7 @@ grub_install_generate_image (const char *dir, const char *prefix, - size_t npubkeys, - char *config_path, - const struct grub_install_image_target_desc *image_target, -- int note, -+ int note, size_t appsig_size, - grub_compression_t comp, const char *dtb_file, - const char *sbat_path, const int disable_shim_lock); - -diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h -index 3819a67441c..6f1da89b9b6 100644 ---- a/include/grub/util/mkimage.h -+++ b/include/grub/util/mkimage.h -@@ -51,12 +51,12 @@ grub_mkimage_load_image64 (const char *kernel_path, - const struct grub_install_image_target_desc *image_target); - void - grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target, -- int note, char **core_img, size_t *core_size, -+ int note, size_t appsig_size, char **core_img, size_t *core_size, - Elf32_Addr target_addr, - struct grub_mkimage_layout *layout); - void - grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target, -- int note, char **core_img, size_t *core_size, -+ int note, size_t appsig_size, char **core_img, size_t *core_size, - Elf64_Addr target_addr, - struct grub_mkimage_layout *layout); - diff --git a/0163-docs-grub-Document-signing-grub-under-UEFI.patch b/0163-docs-grub-Document-signing-grub-under-UEFI.patch deleted file mode 100644 index 9b9b19a..0000000 --- a/0163-docs-grub-Document-signing-grub-under-UEFI.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Sat, 15 Aug 2020 02:00:57 +1000 -Subject: [PATCH] docs/grub: Document signing grub under UEFI - -Before adding information about how grub is signed with an appended -signature scheme, it's worth adding some information about how it -can currently be signed for UEFI. - -Signed-off-by: Daniel Axtens ---- - docs/grub.texi | 22 +++++++++++++++++++++- - 1 file changed, 21 insertions(+), 1 deletion(-) - -diff --git a/docs/grub.texi b/docs/grub.texi -index 4870faaa00a..365d1d6931b 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -5817,6 +5817,7 @@ environment variables and commands are listed in the same order. - * Secure Boot Advanced Targeting:: Embedded information for generation number based revocation - * Measured Boot:: Measuring boot components - * Lockdown:: Lockdown when booting on a secure setup -+* Signing GRUB itself:: Ensuring the integrity of the GRUB core image - @end menu - - @node Authentication and authorisation -@@ -5895,7 +5896,7 @@ commands. - - GRUB's @file{core.img} can optionally provide enforcement that all files - subsequently read from disk are covered by a valid digital signature. --This document does @strong{not} cover how to ensure that your -+This section does @strong{not} cover how to ensure that your - platform's firmware (e.g., Coreboot) validates @file{core.img}. - - If environment variable @code{check_signatures} -@@ -6067,6 +6068,25 @@ be restricted and some operations/commands cannot be executed. - The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. - Otherwise it does not exit. - -+@node Signing GRUB itself -+@section Signing GRUB itself -+ -+To ensure a complete secure-boot chain, there must be a way for the code that -+loads GRUB to verify the integrity of the core image. -+ -+This is ultimately platform-specific and individual platforms can define their -+own mechanisms. However, there are general-purpose mechanisms that can be used -+with GRUB. -+ -+@section Signing GRUB for UEFI secure boot -+ -+On UEFI platforms, @file{core.img} is a PE binary. Therefore, it can be signed -+with a tool such as @command{pesign} or @command{sbsign}. Refer to the -+suggestions in @pxref{UEFI secure boot and shim} to ensure that the final -+image works under UEFI secure boot and can maintain the secure-boot chain. It -+will also be necessary to enrol the public key used into a relevant firmware -+key database. -+ - @node Platform limitations - @chapter Platform limitations - diff --git a/0164-docs-grub-Document-signing-grub-with-an-appended-sig.patch b/0164-docs-grub-Document-signing-grub-with-an-appended-sig.patch deleted file mode 100644 index 4d85d93..0000000 --- a/0164-docs-grub-Document-signing-grub-with-an-appended-sig.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Sat, 15 Aug 2020 02:19:36 +1000 -Subject: [PATCH] docs/grub: Document signing grub with an appended signature - -Signing grub for firmware that verifies an appended signature is a -bit fiddly. I don't want people to have to figure it out from scratch -so document it here. - -Signed-off-by: Daniel Axtens ---- - docs/grub.texi | 42 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - -diff --git a/docs/grub.texi b/docs/grub.texi -index 365d1d6931b..afbde7c1f7b 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -6087,6 +6087,48 @@ image works under UEFI secure boot and can maintain the secure-boot chain. It - will also be necessary to enrol the public key used into a relevant firmware - key database. - -+@section Signing GRUB with an appended signature -+ -+The @file{core.elf} itself can be signed with a Linux kernel module-style -+appended signature. -+ -+To support IEEE1275 platforms where the boot image is often loaded directly -+from a disk partition rather than from a file system, the @file{core.elf} -+can specify the size and location of the appended signature with an ELF -+note added by @command{grub-install}. -+ -+An image can be signed this way using the @command{sign-file} command from -+the Linux kernel: -+ -+@example -+@group -+# grub.key is your private key and certificate.der is your public key -+ -+# Determine the size of the appended signature. It depends on the signing -+# certificate and the hash algorithm -+touch empty -+sign-file SHA256 grub.key certificate.der empty empty.sig -+SIG_SIZE=`stat -c '%s' empty.sig` -+rm empty empty.sig -+ -+# Build a grub image with $SIG_SIZE reserved for the signature -+grub-install --appended-signature-size $SIG_SIZE --modules="..." ... -+ -+# Replace the reserved size with a signature: -+# cut off the last $SIG_SIZE bytes with truncate's minus modifier -+truncate -s -$SIG_SIZE /boot/grub/powerpc-ieee1275/core.elf core.elf.unsigned -+# sign the trimmed file with an appended signature, restoring the correct size -+sign-file SHA256 grub.key certificate.der core.elf.unsigned core.elf.signed -+ -+# Don't forget to install the signed image as required -+# (e.g. on powerpc-ieee1275, to the PReP partition) -+@end group -+@end example -+ -+As with UEFI secure boot, it is necessary to build in the required modules, -+or sign them separately. -+ -+ - @node Platform limitations - @chapter Platform limitations - diff --git a/0165-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch b/0165-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch deleted file mode 100644 index 6e46db0..0000000 --- a/0165-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 30 Jul 2020 00:13:21 +1000 -Subject: [PATCH] dl: provide a fake grub_dl_set_persistent for the emu target - -Trying to start grub-emu with a module that calls grub_dl_set_persistent -will crash because grub-emu fakes modules and passes NULL to the module -init function. - -Provide an empty function for the emu case. - -Fixes: ee7808e2197c (dl: Add support for persistent modules) -Signed-off-by: Daniel Axtens ---- - include/grub/dl.h | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/include/grub/dl.h b/include/grub/dl.h -index 2f76e6b0437..20d870f2a47 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -245,11 +245,22 @@ grub_dl_get (const char *name) - return 0; - } - -+#ifdef GRUB_MACHINE_EMU -+/* -+ * Under grub-emu, modules are faked and NULL is passed to GRUB_MOD_INIT. -+ * So we fake this out to avoid a NULL deref. -+ */ -+static inline void -+grub_dl_set_persistent (grub_dl_t mod __attribute__((unused))) -+{ -+} -+#else - static inline void - grub_dl_set_persistent (grub_dl_t mod) - { - mod->persistent = 1; - } -+#endif - - static inline int - grub_dl_is_persistent (grub_dl_t mod) diff --git a/0166-pgp-factor-out-rsa_pad.patch b/0166-pgp-factor-out-rsa_pad.patch deleted file mode 100644 index a8154e7..0000000 --- a/0166-pgp-factor-out-rsa_pad.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 1 Oct 2020 20:23:48 +1000 -Subject: [PATCH] pgp: factor out rsa_pad - -rsa_pad does the PKCS#1 v1.5 padding for the RSA signature scheme. -We want to use it in other RSA signature verification applications. - -I considered and rejected putting it in lib/crypto.c. That file doesn't -currently require any MPI functions, but rsa_pad does. That's not so -much of a problem for the grub kernel and modules, but crypto.c also -gets built into all the grub utilities. So - despite the utils not -using any asymmetric ciphers - we would need to built the entire MPI -infrastructure in to them. - -A better and simpler solution is just to spin rsa_pad out into its own -PKCS#1 v1.5 module. - -Signed-off-by: Daniel Axtens ---- - grub-core/Makefile.core.def | 8 ++++++ - grub-core/commands/pgp.c | 28 ++------------------- - grub-core/lib/pkcs1_v15.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ - include/grub/pkcs1_v15.h | 27 +++++++++++++++++++++ - 4 files changed, 96 insertions(+), 26 deletions(-) - create mode 100644 grub-core/lib/pkcs1_v15.c - create mode 100644 include/grub/pkcs1_v15.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 81fc274148e..97347ae76f9 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2510,6 +2510,14 @@ module = { - cppflags = '$(CPPFLAGS_GCRY)'; - }; - -+module = { -+ name = pkcs1_v15; -+ common = lib/pkcs1_v15.c; -+ -+ cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare'; -+ cppflags = '$(CPPFLAGS_GCRY)'; -+}; -+ - module = { - name = all_video; - common = lib/fake_module.c; -diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c -index 5daa1e9d00c..2408db4994f 100644 ---- a/grub-core/commands/pgp.c -+++ b/grub-core/commands/pgp.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -411,32 +412,7 @@ static int - rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, - const gcry_md_spec_t *hash, struct grub_public_subkey *sk) - { -- grub_size_t tlen, emlen, fflen; -- grub_uint8_t *em, *emptr; -- unsigned nbits = gcry_mpi_get_nbits (sk->mpis[0]); -- int ret; -- tlen = hash->mdlen + hash->asnlen; -- emlen = (nbits + 7) / 8; -- if (emlen < tlen + 11) -- return 1; -- -- em = grub_malloc (emlen); -- if (!em) -- return 1; -- -- em[0] = 0x00; -- em[1] = 0x01; -- fflen = emlen - tlen - 3; -- for (emptr = em + 2; emptr < em + 2 + fflen; emptr++) -- *emptr = 0xff; -- *emptr++ = 0x00; -- grub_memcpy (emptr, hash->asnoid, hash->asnlen); -- emptr += hash->asnlen; -- grub_memcpy (emptr, hval, hash->mdlen); -- -- ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0); -- grub_free (em); -- return ret; -+ return grub_crypto_rsa_pad(hmpi, hval, hash, sk->mpis[0]); - } - - struct grub_pubkey_context -diff --git a/grub-core/lib/pkcs1_v15.c b/grub-core/lib/pkcs1_v15.c -new file mode 100644 -index 00000000000..dbacd563d01 ---- /dev/null -+++ b/grub-core/lib/pkcs1_v15.c -@@ -0,0 +1,59 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2013 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+/* -+ * Given a hash value 'hval', of hash specification 'hash', perform -+ * the EMSA-PKCS1-v1_5 padding suitable for a key with modulus 'mod' -+ * (see RFC 8017 s 9.2) and place the result in 'hmpi'. -+ */ -+gcry_err_code_t -+grub_crypto_rsa_pad (gcry_mpi_t * hmpi, grub_uint8_t * hval, -+ const gcry_md_spec_t * hash, gcry_mpi_t mod) -+{ -+ grub_size_t tlen, emlen, fflen; -+ grub_uint8_t *em, *emptr; -+ unsigned nbits = gcry_mpi_get_nbits (mod); -+ int ret; -+ tlen = hash->mdlen + hash->asnlen; -+ emlen = (nbits + 7) / 8; -+ if (emlen < tlen + 11) -+ return GPG_ERR_TOO_SHORT; -+ -+ em = grub_malloc (emlen); -+ if (!em) -+ return 1; -+ -+ em[0] = 0x00; -+ em[1] = 0x01; -+ fflen = emlen - tlen - 3; -+ for (emptr = em + 2; emptr < em + 2 + fflen; emptr++) -+ *emptr = 0xff; -+ *emptr++ = 0x00; -+ grub_memcpy (emptr, hash->asnoid, hash->asnlen); -+ emptr += hash->asnlen; -+ grub_memcpy (emptr, hval, hash->mdlen); -+ -+ ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0); -+ grub_free (em); -+ return ret; -+} -diff --git a/include/grub/pkcs1_v15.h b/include/grub/pkcs1_v15.h -new file mode 100644 -index 00000000000..5c338c84a15 ---- /dev/null -+++ b/include/grub/pkcs1_v15.h -@@ -0,0 +1,27 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2013 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+/* -+ * Given a hash value 'hval', of hash specification 'hash', perform -+ * the EMSA-PKCS1-v1_5 padding suitable for a key with modulus 'mod' -+ * (See RFC 8017 s 9.2) -+ */ -+gcry_err_code_t -+grub_crypto_rsa_pad (gcry_mpi_t * hmpi, grub_uint8_t * hval, -+ const gcry_md_spec_t * hash, gcry_mpi_t mod); -+ diff --git a/0167-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch b/0167-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch deleted file mode 100644 index 763cdc6..0000000 --- a/0167-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 2 Oct 2020 10:49:26 +1000 -Subject: [PATCH] crypto: move storage for grub_crypto_pk_* to crypto.c - -The way gcry_rsa and friends (the asymmetric ciphers) are loaded for the -pgp module is a bit quirky. - -include/grub/crypto.h contains: - extern struct gcry_pk_spec *grub_crypto_pk_rsa; - -commands/pgp.c contains the actual storage: - struct gcry_pk_spec *grub_crypto_pk_rsa; - -And the module itself saves to the storage in pgp.c: - GRUB_MOD_INIT(gcry_rsa) - { - grub_crypto_pk_rsa = &_gcry_pubkey_spec_rsa; - } - -This is annoying: gcry_rsa now has a dependency on pgp! - -We want to be able to bring in gcry_rsa without bringing in PGP, -so move the storage to crypto.c. - -Previously, gcry_rsa depended on pgp and mpi. Now it depends on -crypto and mpi. As pgp depends on crypto, this doesn't add any new -module dependencies using the PGP verfier. - -[FWIW, the story is different for the symmetric ciphers. cryptodisk -and friends (zfs encryption etc) use grub_crypto_lookup_cipher_by_name() -to get a cipher handle. That depends on grub_ciphers being populated -by people calling grub_cipher_register. import_gcry.py ensures that the -symmetric ciphers call it.] - -Signed-off-by: Daniel Axtens ---- - grub-core/commands/pgp.c | 4 ---- - grub-core/lib/crypto.c | 4 ++++ - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c -index 2408db4994f..355a43844ac 100644 ---- a/grub-core/commands/pgp.c -+++ b/grub-core/commands/pgp.c -@@ -147,10 +147,6 @@ const char *hashes[] = { - [0x0b] = "sha224" - }; - --struct gcry_pk_spec *grub_crypto_pk_dsa; --struct gcry_pk_spec *grub_crypto_pk_ecdsa; --struct gcry_pk_spec *grub_crypto_pk_rsa; -- - static int - dsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, - const gcry_md_spec_t *hash, struct grub_public_subkey *sk); -diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c -index ca334d5a40e..c578128a59d 100644 ---- a/grub-core/lib/crypto.c -+++ b/grub-core/lib/crypto.c -@@ -121,6 +121,10 @@ grub_md_unregister (gcry_md_spec_t *cipher) - } - } - -+struct gcry_pk_spec *grub_crypto_pk_dsa; -+struct gcry_pk_spec *grub_crypto_pk_ecdsa; -+struct gcry_pk_spec *grub_crypto_pk_rsa; -+ - void - grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in, - grub_size_t inlen) diff --git a/0168-posix_wrap-tweaks-in-preparation-for-libtasn1.patch b/0168-posix_wrap-tweaks-in-preparation-for-libtasn1.patch deleted file mode 100644 index a09cab1..0000000 --- a/0168-posix_wrap-tweaks-in-preparation-for-libtasn1.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Sat, 2 May 2020 00:27:57 +1000 -Subject: [PATCH] posix_wrap: tweaks in preparation for libtasn1 - - - Define SIZEOF_UNSIGNED_LONG_INT, it's the same as - SIZEOF_UNSIGNED_LONG. - - - Define WORD_BIT, the size in bits of an int. This is a defined - in the Single Unix Specification and in gnulib's limits.h. gnulib - assumes it's 32 bits on all our platforms, including 64 bit - platforms, so we also use that value. - - - Provide strto[u]l[l] preprocessor macros that resolve to - grub_strto[u]l[l]. To avoid gcrypt redefining strtoul, we - also define HAVE_STRTOUL here. - -Signed-off-by: Daniel Axtens ---- - grub-core/lib/posix_wrap/limits.h | 1 + - grub-core/lib/posix_wrap/stdlib.h | 8 ++++++++ - grub-core/lib/posix_wrap/sys/types.h | 1 + - 3 files changed, 10 insertions(+) - -diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h -index 7217138ffd6..591dbf3289d 100644 ---- a/grub-core/lib/posix_wrap/limits.h -+++ b/grub-core/lib/posix_wrap/limits.h -@@ -37,5 +37,6 @@ - #define LONG_MAX GRUB_LONG_MAX - - #define CHAR_BIT 8 -+#define WORD_BIT 32 - - #endif -diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h -index 7a8d385e973..4634db09f29 100644 ---- a/grub-core/lib/posix_wrap/stdlib.h -+++ b/grub-core/lib/posix_wrap/stdlib.h -@@ -58,4 +58,12 @@ abs (int c) - return (c >= 0) ? c : -c; - } - -+#define strtol grub_strtol -+ -+/* for libgcrypt */ -+#define HAVE_STRTOUL -+#define strtoul grub_strtoul -+ -+#define strtoull grub_strtoull -+ - #endif -diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h -index 854eb0122ef..f63412c8da0 100644 ---- a/grub-core/lib/posix_wrap/sys/types.h -+++ b/grub-core/lib/posix_wrap/sys/types.h -@@ -51,6 +51,7 @@ typedef grub_uint8_t byte; - typedef grub_addr_t uintptr_t; - - #define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG -+#define SIZEOF_UNSIGNED_LONG_INT GRUB_CPU_SIZEOF_LONG - #define SIZEOF_UNSIGNED_INT 4 - #define SIZEOF_UNSIGNED_LONG_LONG 8 - #define SIZEOF_UNSIGNED_SHORT 2 diff --git a/0169-libtasn1-import-libtasn1-4.16.0.patch b/0169-libtasn1-import-libtasn1-4.16.0.patch deleted file mode 100644 index 89552c8..0000000 --- a/0169-libtasn1-import-libtasn1-4.16.0.patch +++ /dev/null @@ -1,8934 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 10 Jun 2020 16:31:22 +1000 -Subject: [PATCH] libtasn1: import libtasn1-4.16.0 - -Import a very trimmed-down set of libtasn1 files: - -pushd /tmp -wget https://ftp.gnu.org/gnu/libtasn1/libtasn1-4.16.0.tar.gz -popd -pushd grub-core/lib -mkdir libtasn1 -cp /tmp/libtasn1-4.16.0/{README.md,LICENSE} libtasn1/ -mkdir libtasn1/lib -cp /tmp/libtasn1-4.16.0/lib/{coding.c,decoding.c,element.c,element.h,errors.c,gstr.c,gstr.h,int.h,parser_aux.c,parser_aux.h,structure.c,structure.h} libtasn1/lib -cp /tmp/libtasn1-4.16.0/lib/includes/libtasn1.h ../../include/grub/ -git add libtasn1/ ../../include/grub/libtasn1.h -popd - -Signed-off-by: Daniel Axtens ---- - grub-core/lib/libtasn1/lib/coding.c | 1415 ++++++++++++++++++ - grub-core/lib/libtasn1/lib/decoding.c | 2478 +++++++++++++++++++++++++++++++ - grub-core/lib/libtasn1/lib/element.c | 1111 ++++++++++++++ - grub-core/lib/libtasn1/lib/errors.c | 100 ++ - grub-core/lib/libtasn1/lib/gstr.c | 74 + - grub-core/lib/libtasn1/lib/parser_aux.c | 1173 +++++++++++++++ - grub-core/lib/libtasn1/lib/structure.c | 1220 +++++++++++++++ - grub-core/lib/libtasn1/lib/element.h | 40 + - grub-core/lib/libtasn1/lib/gstr.h | 47 + - grub-core/lib/libtasn1/lib/int.h | 221 +++ - grub-core/lib/libtasn1/lib/parser_aux.h | 172 +++ - grub-core/lib/libtasn1/lib/structure.h | 45 + - include/grub/libtasn1.h | 588 ++++++++ - grub-core/lib/libtasn1/LICENSE | 16 + - grub-core/lib/libtasn1/README.md | 91 ++ - 15 files changed, 8791 insertions(+) - create mode 100644 grub-core/lib/libtasn1/lib/coding.c - create mode 100644 grub-core/lib/libtasn1/lib/decoding.c - create mode 100644 grub-core/lib/libtasn1/lib/element.c - create mode 100644 grub-core/lib/libtasn1/lib/errors.c - create mode 100644 grub-core/lib/libtasn1/lib/gstr.c - create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.c - create mode 100644 grub-core/lib/libtasn1/lib/structure.c - create mode 100644 grub-core/lib/libtasn1/lib/element.h - create mode 100644 grub-core/lib/libtasn1/lib/gstr.h - create mode 100644 grub-core/lib/libtasn1/lib/int.h - create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.h - create mode 100644 grub-core/lib/libtasn1/lib/structure.h - create mode 100644 include/grub/libtasn1.h - create mode 100644 grub-core/lib/libtasn1/LICENSE - create mode 100644 grub-core/lib/libtasn1/README.md - -diff --git a/grub-core/lib/libtasn1/lib/coding.c b/grub-core/lib/libtasn1/lib/coding.c -new file mode 100644 -index 00000000000..245ea64cf0a ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/coding.c -@@ -0,0 +1,1415 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+ -+/*****************************************************/ -+/* File: coding.c */ -+/* Description: Functions to create a DER coding of */ -+/* an ASN1 type. */ -+/*****************************************************/ -+ -+#include -+#include "parser_aux.h" -+#include -+#include "element.h" -+#include "minmax.h" -+#include -+ -+#define MAX_TAG_LEN 16 -+ -+/******************************************************/ -+/* Function : _asn1_error_description_value_not_found */ -+/* Description: creates the ErrorDescription string */ -+/* for the ASN1_VALUE_NOT_FOUND error. */ -+/* Parameters: */ -+/* node: node of the tree where the value is NULL. */ -+/* ErrorDescription: string returned. */ -+/* Return: */ -+/******************************************************/ -+static void -+_asn1_error_description_value_not_found (asn1_node node, -+ char *ErrorDescription) -+{ -+ -+ if (ErrorDescription == NULL) -+ return; -+ -+ Estrcpy (ErrorDescription, ":: value of element '"); -+ _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), -+ ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); -+ Estrcat (ErrorDescription, "' not found"); -+ -+} -+ -+/** -+ * asn1_length_der: -+ * @len: value to convert. -+ * @der: buffer to hold the returned encoding (may be %NULL). -+ * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]). -+ * -+ * Creates the DER encoding of the provided length value. -+ * The @der buffer must have enough room for the output. The maximum -+ * length this function will encode is %ASN1_MAX_LENGTH_SIZE. -+ * -+ * To know the size of the DER encoding use a %NULL value for @der. -+ **/ -+void -+asn1_length_der (unsigned long int len, unsigned char *der, int *der_len) -+{ -+ int k; -+ unsigned char temp[ASN1_MAX_LENGTH_SIZE]; -+#if SIZEOF_UNSIGNED_LONG_INT > 8 -+ len &= 0xFFFFFFFFFFFFFFFF; -+#endif -+ -+ if (len < 128) -+ { -+ /* short form */ -+ if (der != NULL) -+ der[0] = (unsigned char) len; -+ *der_len = 1; -+ } -+ else -+ { -+ /* Long form */ -+ k = 0; -+ while (len) -+ { -+ temp[k++] = len & 0xFF; -+ len = len >> 8; -+ } -+ *der_len = k + 1; -+ if (der != NULL) -+ { -+ der[0] = ((unsigned char) k & 0x7F) + 128; -+ while (k--) -+ der[*der_len - 1 - k] = temp[k]; -+ } -+ } -+} -+ -+/******************************************************/ -+/* Function : _asn1_tag_der */ -+/* Description: creates the DER coding for the CLASS */ -+/* and TAG parameters. */ -+/* It is limited by the ASN1_MAX_TAG_SIZE variable */ -+/* Parameters: */ -+/* class: value to convert. */ -+/* tag_value: value to convert. */ -+/* ans: string returned. */ -+/* ans_len: number of meaningful bytes of ANS */ -+/* (ans[0]..ans[ans_len-1]). */ -+/* Return: */ -+/******************************************************/ -+static void -+_asn1_tag_der (unsigned char class, unsigned int tag_value, -+ unsigned char ans[ASN1_MAX_TAG_SIZE], int *ans_len) -+{ -+ int k; -+ unsigned char temp[ASN1_MAX_TAG_SIZE]; -+ -+ if (tag_value < 31) -+ { -+ /* short form */ -+ ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F)); -+ *ans_len = 1; -+ } -+ else -+ { -+ /* Long form */ -+ ans[0] = (class & 0xE0) + 31; -+ k = 0; -+ while (tag_value != 0) -+ { -+ temp[k++] = tag_value & 0x7F; -+ tag_value >>= 7; -+ -+ if (k > ASN1_MAX_TAG_SIZE - 1) -+ break; /* will not encode larger tags */ -+ } -+ *ans_len = k + 1; -+ while (k--) -+ ans[*ans_len - 1 - k] = temp[k] + 128; -+ ans[*ans_len - 1] -= 128; -+ } -+} -+ -+/** -+ * asn1_octet_der: -+ * @str: the input data. -+ * @str_len: STR length (str[0]..str[*str_len-1]). -+ * @der: encoded string returned. -+ * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]). -+ * -+ * Creates a length-value DER encoding for the input data. -+ * The DER encoding of the input data will be placed in the @der variable. -+ * -+ * Note that the OCTET STRING tag is not included in the output. -+ * -+ * This function does not return any value because it is expected -+ * that @der_len will contain enough bytes to store the string -+ * plus the DER encoding. The DER encoding size can be obtained using -+ * asn1_length_der(). -+ **/ -+void -+asn1_octet_der (const unsigned char *str, int str_len, -+ unsigned char *der, int *der_len) -+{ -+ int len_len; -+ -+ if (der == NULL || str_len < 0) -+ return; -+ -+ asn1_length_der (str_len, der, &len_len); -+ memcpy (der + len_len, str, str_len); -+ *der_len = str_len + len_len; -+} -+ -+ -+/** -+ * asn1_encode_simple_der: -+ * @etype: The type of the string to be encoded (ASN1_ETYPE_) -+ * @str: the string data. -+ * @str_len: the string length -+ * @tl: the encoded tag and length -+ * @tl_len: the bytes of the @tl field -+ * -+ * Creates the DER encoding for various simple ASN.1 types like strings etc. -+ * It stores the tag and length in @tl, which should have space for at least -+ * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl. -+ * -+ * The complete DER encoding should consist of the value in @tl appended -+ * with the provided @str. -+ * -+ * Returns: %ASN1_SUCCESS if successful or an error value. -+ **/ -+int -+asn1_encode_simple_der (unsigned int etype, const unsigned char *str, -+ unsigned int str_len, unsigned char *tl, -+ unsigned int *tl_len) -+{ -+ int tag_len, len_len; -+ unsigned tlen; -+ unsigned char der_tag[ASN1_MAX_TAG_SIZE]; -+ unsigned char der_length[ASN1_MAX_LENGTH_SIZE]; -+ unsigned char *p; -+ -+ if (str == NULL) -+ return ASN1_VALUE_NOT_VALID; -+ -+ if (ETYPE_OK (etype) == 0) -+ return ASN1_VALUE_NOT_VALID; -+ -+ /* doesn't handle constructed classes */ -+ if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL) -+ return ASN1_VALUE_NOT_VALID; -+ -+ _asn1_tag_der (ETYPE_CLASS (etype), ETYPE_TAG (etype), der_tag, &tag_len); -+ -+ asn1_length_der (str_len, der_length, &len_len); -+ -+ if (tag_len <= 0 || len_len <= 0) -+ return ASN1_VALUE_NOT_VALID; -+ -+ tlen = tag_len + len_len; -+ -+ if (*tl_len < tlen) -+ return ASN1_MEM_ERROR; -+ -+ p = tl; -+ memcpy (p, der_tag, tag_len); -+ p += tag_len; -+ memcpy (p, der_length, len_len); -+ -+ *tl_len = tlen; -+ -+ return ASN1_SUCCESS; -+} -+ -+/******************************************************/ -+/* Function : _asn1_time_der */ -+/* Description: creates the DER coding for a TIME */ -+/* type (length included). */ -+/* Parameters: */ -+/* str: TIME null-terminated string. */ -+/* der: string returned. */ -+/* der_len: number of meaningful bytes of DER */ -+/* (der[0]..der[ans_len-1]). Initially it */ -+/* if must store the lenght of DER. */ -+/* Return: */ -+/* ASN1_MEM_ERROR when DER isn't big enough */ -+/* ASN1_SUCCESS otherwise */ -+/******************************************************/ -+static int -+_asn1_time_der (unsigned char *str, int str_len, unsigned char *der, -+ int *der_len) -+{ -+ int len_len; -+ int max_len; -+ -+ if (der == NULL) -+ return ASN1_VALUE_NOT_VALID; -+ -+ max_len = *der_len; -+ -+ asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len); -+ -+ if ((len_len + str_len) <= max_len) -+ memcpy (der + len_len, str, str_len); -+ *der_len = len_len + str_len; -+ -+ if ((*der_len) > max_len) -+ return ASN1_MEM_ERROR; -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/* -+void -+_asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str) -+{ -+ int len_len,str_len; -+ char temp[20]; -+ -+ if(str==NULL) return; -+ str_len=asn1_get_length_der(der,*der_len,&len_len); -+ if (str_len<0) return; -+ memcpy(temp,der+len_len,str_len); -+ *der_len=str_len+len_len; -+ switch(str_len) -+ { -+ case 11: -+ temp[10]=0; -+ strcat(temp,"00+0000"); -+ break; -+ case 13: -+ temp[12]=0; -+ strcat(temp,"+0000"); -+ break; -+ case 15: -+ temp[15]=0; -+ memmove(temp+12,temp+10,6); -+ temp[10]=temp[11]='0'; -+ break; -+ case 17: -+ temp[17]=0; -+ break; -+ default: -+ return; -+ } -+ strcpy(str,temp); -+} -+*/ -+ -+static -+void encode_val(uint64_t val, unsigned char *der, int max_len, int *der_len) -+{ -+ int first, k; -+ unsigned char bit7; -+ -+ first = 0; -+ for (k = sizeof(val); k >= 0; k--) -+ { -+ bit7 = (val >> (k * 7)) & 0x7F; -+ if (bit7 || first || !k) -+ { -+ if (k) -+ bit7 |= 0x80; -+ if (max_len > (*der_len)) -+ der[*der_len] = bit7; -+ (*der_len)++; -+ first = 1; -+ } -+ } -+} -+ -+/******************************************************/ -+/* Function : _asn1_object_id_der */ -+/* Description: creates the DER coding for an */ -+/* OBJECT IDENTIFIER type (length included). */ -+/* Parameters: */ -+/* str: OBJECT IDENTIFIER null-terminated string. */ -+/* der: string returned. */ -+/* der_len: number of meaningful bytes of DER */ -+/* (der[0]..der[ans_len-1]). Initially it */ -+/* must store the length of DER. */ -+/* Return: */ -+/* ASN1_MEM_ERROR when DER isn't big enough */ -+/* ASN1_SUCCESS if succesful */ -+/* or an error value. */ -+/******************************************************/ -+static int -+_asn1_object_id_der (const char *str, unsigned char *der, int *der_len) -+{ -+ int len_len, counter, max_len; -+ char *temp, *n_end, *n_start; -+ uint64_t val, val1 = 0; -+ int str_len = _asn1_strlen (str); -+ -+ max_len = *der_len; -+ *der_len = 0; -+ -+ if (der == NULL && max_len > 0) -+ return ASN1_VALUE_NOT_VALID; -+ -+ temp = malloc (str_len + 2); -+ if (temp == NULL) -+ return ASN1_MEM_ALLOC_ERROR; -+ -+ memcpy (temp, str, str_len); -+ temp[str_len] = '.'; -+ temp[str_len + 1] = 0; -+ -+ counter = 0; -+ n_start = temp; -+ while ((n_end = strchr (n_start, '.'))) -+ { -+ *n_end = 0; -+ val = _asn1_strtou64 (n_start, NULL, 10); -+ counter++; -+ -+ if (counter == 1) -+ { -+ val1 = val; -+ } -+ else if (counter == 2) -+ { -+ uint64_t val0; -+ -+ if (val1 > 2) -+ { -+ free(temp); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ else if ((val1 == 0 || val1 == 1) && val > 39) -+ { -+ free(temp); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ -+ val0 = 40 * val1 + val; -+ encode_val(val0, der, max_len, der_len); -+ } -+ else -+ { -+ encode_val(val, der, max_len, der_len); -+ } -+ n_start = n_end + 1; -+ } -+ -+ asn1_length_der (*der_len, NULL, &len_len); -+ if (max_len >= (*der_len + len_len)) -+ { -+ memmove (der + len_len, der, *der_len); -+ asn1_length_der (*der_len, der, &len_len); -+ } -+ *der_len += len_len; -+ -+ free (temp); -+ -+ if (max_len < (*der_len)) -+ return ASN1_MEM_ERROR; -+ -+ return ASN1_SUCCESS; -+} -+ -+/** -+ * asn1_object_id_der: -+ * @str: An object identifier in numeric, dot format. -+ * @der: buffer to hold the returned encoding (may be %NULL). -+ * @der_len: initially the size of @der; will hold the final size. -+ * @flags: must be zero -+ * -+ * Creates the DER encoding of the provided object identifier. -+ * -+ * Returns: %ASN1_SUCCESS if DER encoding was OK, %ASN1_VALUE_NOT_VALID -+ * if @str is not a valid OID, %ASN1_MEM_ERROR if the @der -+ * vector isn't big enough and in this case @der_len will contain the -+ * length needed. -+ **/ -+int asn1_object_id_der(const char *str, unsigned char *der, int *der_len, unsigned flags) -+{ -+ unsigned char tag_der[MAX_TAG_LEN]; -+ int tag_len = 0, r; -+ int max_len = *der_len; -+ -+ *der_len = 0; -+ -+ _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), ETYPE_TAG (ASN1_ETYPE_OBJECT_ID), -+ tag_der, &tag_len); -+ -+ if (max_len > tag_len) -+ { -+ memcpy(der, tag_der, tag_len); -+ } -+ max_len -= tag_len; -+ der += tag_len; -+ -+ r = _asn1_object_id_der (str, der, &max_len); -+ if (r == ASN1_MEM_ERROR || r == ASN1_SUCCESS) -+ { -+ *der_len = max_len + tag_len; -+ } -+ -+ return r; -+} -+ -+static const unsigned char bit_mask[] = -+ { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; -+ -+/** -+ * asn1_bit_der: -+ * @str: BIT string. -+ * @bit_len: number of meaningful bits in STR. -+ * @der: string returned. -+ * @der_len: number of meaningful bytes of DER -+ * (der[0]..der[ans_len-1]). -+ * -+ * Creates a length-value DER encoding for the input data -+ * as it would have been for a BIT STRING. -+ * The DER encoded data will be copied in @der. -+ * -+ * Note that the BIT STRING tag is not included in the output. -+ * -+ * This function does not return any value because it is expected -+ * that @der_len will contain enough bytes to store the string -+ * plus the DER encoding. The DER encoding size can be obtained using -+ * asn1_length_der(). -+ **/ -+void -+asn1_bit_der (const unsigned char *str, int bit_len, -+ unsigned char *der, int *der_len) -+{ -+ int len_len, len_byte, len_pad; -+ -+ if (der == NULL) -+ return; -+ -+ len_byte = bit_len >> 3; -+ len_pad = 8 - (bit_len & 7); -+ if (len_pad == 8) -+ len_pad = 0; -+ else -+ len_byte++; -+ asn1_length_der (len_byte + 1, der, &len_len); -+ der[len_len] = len_pad; -+ -+ if (str) -+ memcpy (der + len_len + 1, str, len_byte); -+ der[len_len + len_byte] &= bit_mask[len_pad]; -+ *der_len = len_byte + len_len + 1; -+} -+ -+ -+/******************************************************/ -+/* Function : _asn1_complete_explicit_tag */ -+/* Description: add the length coding to the EXPLICIT */ -+/* tags. */ -+/* Parameters: */ -+/* node: pointer to the tree element. */ -+/* der: string with the DER coding of the whole tree*/ -+/* counter: number of meaningful bytes of DER */ -+/* (der[0]..der[*counter-1]). */ -+/* max_len: size of der vector */ -+/* Return: */ -+/* ASN1_MEM_ERROR if der vector isn't big enough, */ -+/* otherwise ASN1_SUCCESS. */ -+/******************************************************/ -+static int -+_asn1_complete_explicit_tag (asn1_node node, unsigned char *der, -+ int *counter, int *max_len) -+{ -+ asn1_node p; -+ int is_tag_implicit, len2, len3; -+ unsigned char temp[SIZEOF_UNSIGNED_INT]; -+ -+ if (der == NULL && *max_len > 0) -+ return ASN1_VALUE_NOT_VALID; -+ -+ is_tag_implicit = 0; -+ -+ if (node->type & CONST_TAG) -+ { -+ p = node->down; -+ if (p == NULL) -+ return ASN1_DER_ERROR; -+ /* When there are nested tags we must complete them reverse to -+ the order they were created. This is because completing a tag -+ modifies all data within it, including the incomplete tags -+ which store buffer positions -- simon@josefsson.org 2002-09-06 -+ */ -+ while (p->right) -+ p = p->right; -+ while (p && p != node->down->left) -+ { -+ if (type_field (p->type) == ASN1_ETYPE_TAG) -+ { -+ if (p->type & CONST_EXPLICIT) -+ { -+ len2 = strtol (p->name, NULL, 10); -+ _asn1_set_name (p, NULL); -+ -+ asn1_length_der (*counter - len2, temp, &len3); -+ if (len3 <= (*max_len)) -+ { -+ memmove (der + len2 + len3, der + len2, -+ *counter - len2); -+ memcpy (der + len2, temp, len3); -+ } -+ *max_len -= len3; -+ *counter += len3; -+ is_tag_implicit = 0; -+ } -+ else -+ { /* CONST_IMPLICIT */ -+ if (!is_tag_implicit) -+ { -+ is_tag_implicit = 1; -+ } -+ } -+ } -+ p = p->left; -+ } -+ } -+ -+ if (*max_len < 0) -+ return ASN1_MEM_ERROR; -+ -+ return ASN1_SUCCESS; -+} -+ -+const tag_and_class_st _asn1_tags[] = { -+ [ASN1_ETYPE_GENERALSTRING] = -+ {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, "type:GENERALSTRING"}, -+ [ASN1_ETYPE_NUMERIC_STRING] = -+ {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"}, -+ [ASN1_ETYPE_IA5_STRING] = -+ {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"}, -+ [ASN1_ETYPE_TELETEX_STRING] = -+ {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"}, -+ [ASN1_ETYPE_PRINTABLE_STRING] = -+ {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"}, -+ [ASN1_ETYPE_UNIVERSAL_STRING] = -+ {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"}, -+ [ASN1_ETYPE_BMP_STRING] = -+ {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"}, -+ [ASN1_ETYPE_UTF8_STRING] = -+ {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"}, -+ [ASN1_ETYPE_VISIBLE_STRING] = -+ {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"}, -+ [ASN1_ETYPE_OCTET_STRING] = -+ {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"}, -+ [ASN1_ETYPE_BIT_STRING] = -+ {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"}, -+ [ASN1_ETYPE_OBJECT_ID] = -+ {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_ID"}, -+ [ASN1_ETYPE_NULL] = {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"}, -+ [ASN1_ETYPE_BOOLEAN] = -+ {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"}, -+ [ASN1_ETYPE_INTEGER] = -+ {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"}, -+ [ASN1_ETYPE_ENUMERATED] = -+ {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"}, -+ [ASN1_ETYPE_SEQUENCE] = -+ {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, -+ "type:SEQUENCE"}, -+ [ASN1_ETYPE_SEQUENCE_OF] = -+ {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, -+ "type:SEQ_OF"}, -+ [ASN1_ETYPE_SET] = -+ {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET"}, -+ [ASN1_ETYPE_SET_OF] = -+ {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, -+ "type:SET_OF"}, -+ [ASN1_ETYPE_GENERALIZED_TIME] = -+ {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL, "type:GENERALIZED_TIME"}, -+ [ASN1_ETYPE_UTC_TIME] = -+ {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"}, -+}; -+ -+unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]); -+ -+/******************************************************/ -+/* Function : _asn1_insert_tag_der */ -+/* Description: creates the DER coding of tags of one */ -+/* NODE. */ -+/* Parameters: */ -+/* node: pointer to the tree element. */ -+/* der: string returned */ -+/* counter: number of meaningful bytes of DER */ -+/* (counter[0]..der[*counter-1]). */ -+/* max_len: size of der vector */ -+/* Return: */ -+/* ASN1_GENERIC_ERROR if the type is unknown, */ -+/* ASN1_MEM_ERROR if der vector isn't big enough, */ -+/* otherwise ASN1_SUCCESS. */ -+/******************************************************/ -+static int -+_asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter, -+ int *max_len) -+{ -+ asn1_node p; -+ int tag_len, is_tag_implicit; -+ unsigned char class, class_implicit = 0, temp[MAX(SIZEOF_UNSIGNED_INT * 3 + 1, LTOSTR_MAX_SIZE)]; -+ unsigned long tag_implicit = 0; -+ unsigned char tag_der[MAX_TAG_LEN]; -+ -+ is_tag_implicit = 0; -+ -+ if (node->type & CONST_TAG) -+ { -+ p = node->down; -+ while (p) -+ { -+ if (type_field (p->type) == ASN1_ETYPE_TAG) -+ { -+ if (p->type & CONST_APPLICATION) -+ class = ASN1_CLASS_APPLICATION; -+ else if (p->type & CONST_UNIVERSAL) -+ class = ASN1_CLASS_UNIVERSAL; -+ else if (p->type & CONST_PRIVATE) -+ class = ASN1_CLASS_PRIVATE; -+ else -+ class = ASN1_CLASS_CONTEXT_SPECIFIC; -+ -+ if (p->type & CONST_EXPLICIT) -+ { -+ if (is_tag_implicit) -+ _asn1_tag_der (class_implicit, tag_implicit, tag_der, -+ &tag_len); -+ else -+ _asn1_tag_der (class | ASN1_CLASS_STRUCTURED, -+ _asn1_strtoul (p->value, NULL, 10), -+ tag_der, &tag_len); -+ -+ *max_len -= tag_len; -+ if (der && *max_len >= 0) -+ memcpy (der + *counter, tag_der, tag_len); -+ *counter += tag_len; -+ -+ _asn1_ltostr (*counter, (char *) temp); -+ _asn1_set_name (p, (const char *) temp); -+ -+ is_tag_implicit = 0; -+ } -+ else -+ { /* CONST_IMPLICIT */ -+ if (!is_tag_implicit) -+ { -+ if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) || -+ (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) -+ || (type_field (node->type) == ASN1_ETYPE_SET) -+ || (type_field (node->type) == ASN1_ETYPE_SET_OF)) -+ class |= ASN1_CLASS_STRUCTURED; -+ class_implicit = class; -+ tag_implicit = _asn1_strtoul (p->value, NULL, 10); -+ is_tag_implicit = 1; -+ } -+ } -+ } -+ p = p->right; -+ } -+ } -+ -+ if (is_tag_implicit) -+ { -+ _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len); -+ } -+ else -+ { -+ unsigned type = type_field (node->type); -+ switch (type) -+ { -+ CASE_HANDLED_ETYPES: -+ _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag, -+ tag_der, &tag_len); -+ break; -+ case ASN1_ETYPE_TAG: -+ case ASN1_ETYPE_CHOICE: -+ case ASN1_ETYPE_ANY: -+ tag_len = 0; -+ break; -+ default: -+ return ASN1_GENERIC_ERROR; -+ } -+ } -+ -+ *max_len -= tag_len; -+ if (der && *max_len >= 0) -+ memcpy (der + *counter, tag_der, tag_len); -+ *counter += tag_len; -+ -+ if (*max_len < 0) -+ return ASN1_MEM_ERROR; -+ -+ return ASN1_SUCCESS; -+} -+ -+/******************************************************/ -+/* Function : _asn1_ordering_set */ -+/* Description: puts the elements of a SET type in */ -+/* the correct order according to DER rules. */ -+/* Parameters: */ -+/* der: string with the DER coding. */ -+/* node: pointer to the SET element. */ -+/* Return: */ -+/* ASN1_SUCCESS if successful */ -+/* or an error value. */ -+/******************************************************/ -+static int -+_asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) -+{ -+ struct vet -+ { -+ int end; -+ unsigned long value; -+ struct vet *next, *prev; -+ }; -+ -+ int counter, len, len2; -+ struct vet *first, *last, *p_vet, *p2_vet; -+ asn1_node p; -+ unsigned char class, *temp; -+ unsigned long tag, t; -+ int err; -+ -+ counter = 0; -+ -+ if (type_field (node->type) != ASN1_ETYPE_SET) -+ return ASN1_VALUE_NOT_VALID; -+ -+ p = node->down; -+ while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || -+ (type_field (p->type) == ASN1_ETYPE_SIZE))) -+ p = p->right; -+ -+ if ((p == NULL) || (p->right == NULL)) -+ return ASN1_SUCCESS; -+ -+ first = last = NULL; -+ while (p) -+ { -+ p_vet = malloc (sizeof (struct vet)); -+ if (p_vet == NULL) -+ { -+ err = ASN1_MEM_ALLOC_ERROR; -+ goto error; -+ } -+ -+ p_vet->next = NULL; -+ p_vet->prev = last; -+ if (first == NULL) -+ first = p_vet; -+ else -+ last->next = p_vet; -+ last = p_vet; -+ -+ /* tag value calculation */ -+ err = asn1_get_tag_der (der + counter, der_len - counter, &class, &len2, -+ &tag); -+ if (err != ASN1_SUCCESS) -+ goto error; -+ -+ t = ((unsigned int)class) << 24; -+ p_vet->value = t | tag; -+ counter += len2; -+ -+ /* extraction and length */ -+ len2 = asn1_get_length_der (der + counter, der_len - counter, &len); -+ if (len2 < 0) -+ { -+ err = ASN1_DER_ERROR; -+ goto error; -+ } -+ counter += len + len2; -+ -+ p_vet->end = counter; -+ p = p->right; -+ } -+ -+ p_vet = first; -+ -+ while (p_vet) -+ { -+ p2_vet = p_vet->next; -+ counter = 0; -+ while (p2_vet) -+ { -+ if (p_vet->value > p2_vet->value) -+ { -+ /* change position */ -+ temp = malloc (p_vet->end - counter); -+ if (temp == NULL) -+ { -+ err = ASN1_MEM_ALLOC_ERROR; -+ goto error; -+ } -+ -+ memcpy (temp, der + counter, p_vet->end - counter); -+ memcpy (der + counter, der + p_vet->end, -+ p2_vet->end - p_vet->end); -+ memcpy (der + counter + p2_vet->end - p_vet->end, temp, -+ p_vet->end - counter); -+ free (temp); -+ -+ tag = p_vet->value; -+ p_vet->value = p2_vet->value; -+ p2_vet->value = tag; -+ -+ p_vet->end = counter + (p2_vet->end - p_vet->end); -+ } -+ counter = p_vet->end; -+ -+ p2_vet = p2_vet->next; -+ p_vet = p_vet->next; -+ } -+ -+ if (p_vet != first) -+ p_vet->prev->next = NULL; -+ else -+ first = NULL; -+ free (p_vet); -+ p_vet = first; -+ } -+ return ASN1_SUCCESS; -+ -+error: -+ while (first != NULL) -+ { -+ p_vet = first; -+ first = first->next; -+ free(p_vet); -+ } -+ return err; -+} -+ -+struct vet -+{ -+ unsigned char *ptr; -+ int size; -+}; -+ -+static int setof_compar(const void *_e1, const void *_e2) -+{ -+ unsigned length; -+ const struct vet *e1 = _e1, *e2 = _e2; -+ int rval; -+ -+ /* The encodings of the component values of a set-of value shall -+ * appear in ascending order, the encodings being compared -+ * as octet strings with the shorter components being -+ * padded at their trailing end with 0-octets. -+ * The padding octets are for comparison purposes and -+ * do not appear in the encodings. -+ */ -+ length = MIN(e1->size, e2->size); -+ -+ rval = memcmp(e1->ptr, e2->ptr, length); -+ if (rval == 0 && e1->size != e2->size) -+ { -+ if (e1->size > e2->size) -+ rval = 1; -+ else if (e2->size > e1->size) -+ rval = -1; -+ } -+ -+ return rval; -+} -+ -+/******************************************************/ -+/* Function : _asn1_ordering_set_of */ -+/* Description: puts the elements of a SET OF type in */ -+/* the correct order according to DER rules. */ -+/* Parameters: */ -+/* der: string with the DER coding. */ -+/* node: pointer to the SET OF element. */ -+/* Return: */ -+/* ASN1_SUCCESS if successful */ -+/* or an error value. */ -+/******************************************************/ -+static int -+_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) -+{ -+ int counter, len, len2; -+ struct vet *list = NULL, *tlist; -+ unsigned list_size = 0; -+ struct vet *p_vet; -+ asn1_node p; -+ unsigned char class; -+ unsigned i; -+ unsigned char *out = NULL; -+ int err; -+ -+ if (der == NULL) -+ return ASN1_VALUE_NOT_VALID; -+ -+ counter = 0; -+ -+ if (type_field (node->type) != ASN1_ETYPE_SET_OF) -+ return ASN1_VALUE_NOT_VALID; -+ -+ p = node->down; -+ while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || -+ (type_field (p->type) == ASN1_ETYPE_SIZE))) -+ p = p->right; -+ if (p == NULL) -+ return ASN1_VALUE_NOT_VALID; -+ p = p->right; -+ -+ if ((p == NULL) || (p->right == NULL)) -+ return ASN1_SUCCESS; -+ -+ while (p) -+ { -+ list_size++; -+ tlist = realloc (list, list_size*sizeof(struct vet)); -+ if (tlist == NULL) -+ { -+ err = ASN1_MEM_ALLOC_ERROR; -+ goto error; -+ } -+ list = tlist; -+ p_vet = &list[list_size-1]; -+ -+ p_vet->ptr = der+counter; -+ p_vet->size = 0; -+ -+ /* extraction of tag and length */ -+ if (der_len - counter > 0) -+ { -+ err = asn1_get_tag_der (der + counter, der_len - counter, &class, -+ &len, NULL); -+ if (err != ASN1_SUCCESS) -+ goto error; -+ counter += len; -+ p_vet->size += len; -+ -+ len2 = asn1_get_length_der (der + counter, der_len - counter, &len); -+ if (len2 < 0) -+ { -+ err = ASN1_DER_ERROR; -+ goto error; -+ } -+ counter += len + len2; -+ p_vet->size += len + len2; -+ -+ } -+ else -+ { -+ err = ASN1_DER_ERROR; -+ goto error; -+ } -+ p = p->right; -+ } -+ -+ if (counter > der_len) -+ { -+ err = ASN1_DER_ERROR; -+ goto error; -+ } -+ -+ qsort(list, list_size, sizeof(struct vet), setof_compar); -+ -+ out = malloc(der_len); -+ if (out == NULL) -+ { -+ err = ASN1_MEM_ERROR; -+ goto error; -+ } -+ -+ /* the sum of p_vet->size == der_len */ -+ counter = 0; -+ for (i = 0; i < list_size; i++) -+ { -+ p_vet = &list[i]; -+ memcpy(out+counter, p_vet->ptr, p_vet->size); -+ counter += p_vet->size; -+ } -+ memcpy(der, out, der_len); -+ free(out); -+ -+ err = ASN1_SUCCESS; -+ -+error: -+ free(list); -+ return err; -+} -+ -+/** -+ * asn1_der_coding: -+ * @element: pointer to an ASN1 element -+ * @name: the name of the structure you want to encode (it must be -+ * inside *POINTER). -+ * @ider: vector that will contain the DER encoding. DER must be a -+ * pointer to memory cells already allocated. -+ * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy -+ * holds the sizeof of der vector. -+ * @ErrorDescription: return the error description or an empty -+ * string if success. -+ * -+ * Creates the DER encoding for the NAME structure (inside *POINTER -+ * structure). -+ * -+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND -+ * if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there -+ * is an element without a value, %ASN1_MEM_ERROR if the @ider -+ * vector isn't big enough and in this case @len will contain the -+ * length needed. -+ **/ -+int -+asn1_der_coding (asn1_node_const element, const char *name, void *ider, int *len, -+ char *ErrorDescription) -+{ -+ asn1_node node, p, p2; -+ unsigned char temp[MAX(LTOSTR_MAX_SIZE, SIZEOF_UNSIGNED_LONG_INT * 3 + 1)]; -+ int counter, counter_old, len2, len3, move, max_len, max_len_old; -+ int err; -+ unsigned char *der = ider; -+ -+ if (ErrorDescription) -+ ErrorDescription[0] = 0; -+ -+ node = asn1_find_node (element, name); -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ /* Node is now a locally allocated variable. -+ * That is because in some point we modify the -+ * structure, and I don't know why! --nmav -+ */ -+ node = _asn1_copy_structure3 (node); -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ max_len = *len; -+ -+ if (der == NULL && max_len > 0) -+ return ASN1_VALUE_NOT_VALID; -+ -+ counter = 0; -+ move = DOWN; -+ p = node; -+ -+ while (1) -+ { -+ -+ counter_old = counter; -+ max_len_old = max_len; -+ if (move != UP) -+ { -+ p->start = counter; -+ err = _asn1_insert_tag_der (p, der, &counter, &max_len); -+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) -+ goto error; -+ } -+ switch (type_field (p->type)) -+ { -+ case ASN1_ETYPE_NULL: -+ max_len--; -+ if (der != NULL && max_len >= 0) -+ der[counter] = 0; -+ counter++; -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_BOOLEAN: -+ if ((p->type & CONST_DEFAULT) && (p->value == NULL)) -+ { -+ counter = counter_old; -+ max_len = max_len_old; -+ } -+ else -+ { -+ if (p->value == NULL) -+ { -+ _asn1_error_description_value_not_found (p, -+ ErrorDescription); -+ err = ASN1_VALUE_NOT_FOUND; -+ goto error; -+ } -+ max_len -= 2; -+ if (der != NULL && max_len >= 0) -+ { -+ der[counter++] = 1; -+ if (p->value[0] == 'F') -+ der[counter++] = 0; -+ else -+ der[counter++] = 0xFF; -+ } -+ else -+ counter += 2; -+ } -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_INTEGER: -+ case ASN1_ETYPE_ENUMERATED: -+ if ((p->type & CONST_DEFAULT) && (p->value == NULL)) -+ { -+ counter = counter_old; -+ max_len = max_len_old; -+ } -+ else -+ { -+ if (p->value == NULL) -+ { -+ _asn1_error_description_value_not_found (p, -+ ErrorDescription); -+ err = ASN1_VALUE_NOT_FOUND; -+ goto error; -+ } -+ len2 = asn1_get_length_der (p->value, p->value_len, &len3); -+ if (len2 < 0) -+ { -+ err = ASN1_DER_ERROR; -+ goto error; -+ } -+ max_len -= len2 + len3; -+ if (der != NULL && max_len >= 0) -+ memcpy (der + counter, p->value, len3 + len2); -+ counter += len3 + len2; -+ } -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_OBJECT_ID: -+ if ((p->type & CONST_DEFAULT) && (p->value == NULL)) -+ { -+ counter = counter_old; -+ max_len = max_len_old; -+ } -+ else -+ { -+ if (p->value == NULL) -+ { -+ _asn1_error_description_value_not_found (p, -+ ErrorDescription); -+ err = ASN1_VALUE_NOT_FOUND; -+ goto error; -+ } -+ len2 = max_len; -+ err = _asn1_object_id_der ((char*)p->value, der + counter, &len2); -+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) -+ goto error; -+ -+ max_len -= len2; -+ counter += len2; -+ } -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_GENERALIZED_TIME: -+ case ASN1_ETYPE_UTC_TIME: -+ if (p->value == NULL) -+ { -+ _asn1_error_description_value_not_found (p, ErrorDescription); -+ err = ASN1_VALUE_NOT_FOUND; -+ goto error; -+ } -+ len2 = max_len; -+ err = _asn1_time_der (p->value, p->value_len, der + counter, &len2); -+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) -+ goto error; -+ -+ max_len -= len2; -+ counter += len2; -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_OCTET_STRING: -+ case ASN1_ETYPE_GENERALSTRING: -+ case ASN1_ETYPE_NUMERIC_STRING: -+ case ASN1_ETYPE_IA5_STRING: -+ case ASN1_ETYPE_TELETEX_STRING: -+ case ASN1_ETYPE_PRINTABLE_STRING: -+ case ASN1_ETYPE_UNIVERSAL_STRING: -+ case ASN1_ETYPE_BMP_STRING: -+ case ASN1_ETYPE_UTF8_STRING: -+ case ASN1_ETYPE_VISIBLE_STRING: -+ case ASN1_ETYPE_BIT_STRING: -+ if (p->value == NULL) -+ { -+ _asn1_error_description_value_not_found (p, ErrorDescription); -+ err = ASN1_VALUE_NOT_FOUND; -+ goto error; -+ } -+ len2 = asn1_get_length_der (p->value, p->value_len, &len3); -+ if (len2 < 0) -+ { -+ err = ASN1_DER_ERROR; -+ goto error; -+ } -+ max_len -= len2 + len3; -+ if (der != NULL && max_len >= 0) -+ memcpy (der + counter, p->value, len3 + len2); -+ counter += len3 + len2; -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_SEQUENCE: -+ case ASN1_ETYPE_SET: -+ if (move != UP) -+ { -+ p->tmp_ival = counter; -+ if (p->down == NULL) -+ { -+ move = UP; -+ continue; -+ } -+ else -+ { -+ p2 = p->down; -+ while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG)) -+ p2 = p2->right; -+ if (p2) -+ { -+ p = p2; -+ move = RIGHT; -+ continue; -+ } -+ move = UP; -+ continue; -+ } -+ } -+ else -+ { /* move==UP */ -+ len2 = p->tmp_ival; -+ p->tmp_ival = 0; -+ if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0)) -+ { -+ err = _asn1_ordering_set (der + len2, counter - len2, p); -+ if (err != ASN1_SUCCESS) -+ goto error; -+ } -+ asn1_length_der (counter - len2, temp, &len3); -+ max_len -= len3; -+ if (der != NULL && max_len >= 0) -+ { -+ memmove (der + len2 + len3, der + len2, counter - len2); -+ memcpy (der + len2, temp, len3); -+ } -+ counter += len3; -+ move = RIGHT; -+ } -+ break; -+ case ASN1_ETYPE_SEQUENCE_OF: -+ case ASN1_ETYPE_SET_OF: -+ if (move != UP) -+ { -+ p->tmp_ival = counter; -+ p = p->down; -+ while ((type_field (p->type) == ASN1_ETYPE_TAG) -+ || (type_field (p->type) == ASN1_ETYPE_SIZE)) -+ p = p->right; -+ if (p->right) -+ { -+ p = p->right; -+ move = RIGHT; -+ continue; -+ } -+ else -+ p = _asn1_find_up (p); -+ move = UP; -+ } -+ if (move == UP) -+ { -+ len2 = p->tmp_ival; -+ p->tmp_ival = 0; -+ if ((type_field (p->type) == ASN1_ETYPE_SET_OF) -+ && (counter - len2 > 0) && (max_len >= 0)) -+ { -+ err = _asn1_ordering_set_of (der + len2, counter - len2, p); -+ if (err != ASN1_SUCCESS) -+ goto error; -+ } -+ asn1_length_der (counter - len2, temp, &len3); -+ max_len -= len3; -+ if (der != NULL && max_len >= 0) -+ { -+ memmove (der + len2 + len3, der + len2, counter - len2); -+ memcpy (der + len2, temp, len3); -+ } -+ counter += len3; -+ move = RIGHT; -+ } -+ break; -+ case ASN1_ETYPE_ANY: -+ if (p->value == NULL) -+ { -+ _asn1_error_description_value_not_found (p, ErrorDescription); -+ err = ASN1_VALUE_NOT_FOUND; -+ goto error; -+ } -+ len2 = asn1_get_length_der (p->value, p->value_len, &len3); -+ if (len2 < 0) -+ { -+ err = ASN1_DER_ERROR; -+ goto error; -+ } -+ max_len -= len2; -+ if (der != NULL && max_len >= 0) -+ memcpy (der + counter, p->value + len3, len2); -+ counter += len2; -+ move = RIGHT; -+ break; -+ default: -+ move = (move == UP) ? RIGHT : DOWN; -+ break; -+ } -+ -+ if ((move != DOWN) && (counter != counter_old)) -+ { -+ p->end = counter - 1; -+ err = _asn1_complete_explicit_tag (p, der, &counter, &max_len); -+ if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) -+ goto error; -+ } -+ -+ if (p == node && move != DOWN) -+ break; -+ -+ if (move == DOWN) -+ { -+ if (p->down) -+ p = p->down; -+ else -+ move = RIGHT; -+ } -+ if (move == RIGHT) -+ { -+ if (p->right) -+ p = p->right; -+ else -+ move = UP; -+ } -+ if (move == UP) -+ p = _asn1_find_up (p); -+ } -+ -+ *len = counter; -+ -+ if (max_len < 0) -+ { -+ err = ASN1_MEM_ERROR; -+ goto error; -+ } -+ -+ err = ASN1_SUCCESS; -+ -+error: -+ asn1_delete_structure (&node); -+ return err; -+} -diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c -new file mode 100644 -index 00000000000..ff04eb778cb ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/decoding.c -@@ -0,0 +1,2478 @@ -+/* -+ * Copyright (C) 2002-2016 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+ -+/*****************************************************/ -+/* File: decoding.c */ -+/* Description: Functions to manage DER decoding */ -+/*****************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef DEBUG -+# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__) -+#else -+# define warn() -+#endif -+ -+#define IS_ERR(len, flags) (len < -1 || ((flags & ASN1_DECODE_FLAG_STRICT_DER) && len < 0)) -+ -+#define HAVE_TWO(x) (x>=2?1:0) -+ -+/* Decoding flags (dflags) used in several decoding functions. -+ * DECODE_FLAG_HAVE_TAG: The provided buffer includes a tag -+ * DECODE_FLAG_CONSTRUCTED: The provided buffer is of indefinite encoding (useful -+ * when no tags are present). -+ * DECODE_FLAG_LEVEL1: Internal flag to indicate a level of recursion for BER strings. -+ * DECODE_FLAG_LEVEL2: Internal flag to indicate two levels of recursion for BER strings. -+ * DECODE_FLAG_LEVEL3: Internal flag to indicate three levels of recursion for BER strings. -+ * This is the maximum levels of recursion possible to prevent stack -+ * exhaustion. -+ */ -+ -+#define DECODE_FLAG_HAVE_TAG 1 -+#define DECODE_FLAG_CONSTRUCTED (1<<1) -+#define DECODE_FLAG_LEVEL1 (1<<2) -+#define DECODE_FLAG_LEVEL2 (1<<3) -+#define DECODE_FLAG_LEVEL3 (1<<4) -+ -+#define DECR_LEN(l, s) do { \ -+ l -= s; \ -+ if (l < 0) { \ -+ warn(); \ -+ result = ASN1_DER_ERROR; \ -+ goto cleanup; \ -+ } \ -+ } while (0) -+ -+static int -+_asn1_get_indefinite_length_string (const unsigned char *der, int der_len, int *len); -+ -+static int -+_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, unsigned char **str, -+ unsigned int *str_len, unsigned int *ber_len, -+ unsigned dflags); -+ -+static int -+_asn1_decode_simple_der (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, const unsigned char **str, -+ unsigned int *str_len, unsigned dflags); -+ -+static void -+_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription) -+{ -+ -+ Estrcpy (ErrorDescription, ":: tag error near element '"); -+ _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), -+ ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); -+ Estrcat (ErrorDescription, "'"); -+ -+} -+ -+/** -+ * asn1_get_length_der: -+ * @der: DER data to decode. -+ * @der_len: Length of DER data to decode. -+ * @len: Output variable containing the length of the DER length field. -+ * -+ * Extract a length field from DER data. -+ * -+ * Returns: Return the decoded length value, or -1 on indefinite -+ * length, or -2 when the value was too big to fit in a int, or -4 -+ * when the decoded length value plus @len would exceed @der_len. -+ **/ -+long -+asn1_get_length_der (const unsigned char *der, int der_len, int *len) -+{ -+ unsigned int ans; -+ int k, punt, sum; -+ -+ *len = 0; -+ if (der_len <= 0) -+ return 0; -+ -+ if (!(der[0] & 128)) -+ { -+ /* short form */ -+ *len = 1; -+ ans = der[0]; -+ } -+ else -+ { -+ /* Long form */ -+ k = der[0] & 0x7F; -+ punt = 1; -+ if (k) -+ { /* definite length method */ -+ ans = 0; -+ while (punt <= k && punt < der_len) -+ { -+ if (INT_MULTIPLY_OVERFLOW (ans, 256)) -+ return -2; -+ ans *= 256; -+ -+ if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt]))) -+ return -2; -+ ans += der[punt]; -+ punt++; -+ } -+ } -+ else -+ { /* indefinite length method */ -+ *len = punt; -+ return -1; -+ } -+ -+ *len = punt; -+ } -+ -+ sum = ans; -+ if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len))) -+ return -2; -+ sum += *len; -+ -+ if (sum > der_len) -+ return -4; -+ -+ return ans; -+} -+ -+/** -+ * asn1_get_tag_der: -+ * @der: DER data to decode. -+ * @der_len: Length of DER data to decode. -+ * @cls: Output variable containing decoded class. -+ * @len: Output variable containing the length of the DER TAG data. -+ * @tag: Output variable containing the decoded tag (may be %NULL). -+ * -+ * Decode the class and TAG from DER code. -+ * -+ * Returns: Returns %ASN1_SUCCESS on success, or an error. -+ **/ -+int -+asn1_get_tag_der (const unsigned char *der, int der_len, -+ unsigned char *cls, int *len, unsigned long *tag) -+{ -+ unsigned int ris; -+ int punt; -+ -+ if (der == NULL || der_len < 2 || len == NULL) -+ return ASN1_DER_ERROR; -+ -+ *cls = der[0] & 0xE0; -+ if ((der[0] & 0x1F) != 0x1F) -+ { -+ /* short form */ -+ *len = 1; -+ ris = der[0] & 0x1F; -+ } -+ else -+ { -+ /* Long form */ -+ punt = 1; -+ ris = 0; -+ while (punt < der_len && der[punt] & 128) -+ { -+ -+ if (INT_MULTIPLY_OVERFLOW (ris, 128)) -+ return ASN1_DER_ERROR; -+ ris *= 128; -+ -+ if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) -+ return ASN1_DER_ERROR; -+ ris += (der[punt] & 0x7F); -+ punt++; -+ } -+ -+ if (punt >= der_len) -+ return ASN1_DER_ERROR; -+ -+ if (INT_MULTIPLY_OVERFLOW (ris, 128)) -+ return ASN1_DER_ERROR; -+ ris *= 128; -+ -+ if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) -+ return ASN1_DER_ERROR; -+ ris += (der[punt] & 0x7F); -+ punt++; -+ -+ *len = punt; -+ } -+ -+ if (tag) -+ *tag = ris; -+ return ASN1_SUCCESS; -+} -+ -+/** -+ * asn1_get_length_ber: -+ * @ber: BER data to decode. -+ * @ber_len: Length of BER data to decode. -+ * @len: Output variable containing the length of the BER length field. -+ * -+ * Extract a length field from BER data. The difference to -+ * asn1_get_length_der() is that this function will return a length -+ * even if the value has indefinite encoding. -+ * -+ * Returns: Return the decoded length value, or negative value when -+ * the value was too big. -+ * -+ * Since: 2.0 -+ **/ -+long -+asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len) -+{ -+ int ret; -+ long err; -+ -+ ret = asn1_get_length_der (ber, ber_len, len); -+ -+ if (ret == -1 && ber_len > 1) -+ { /* indefinite length method */ -+ err = _asn1_get_indefinite_length_string (ber + 1, ber_len-1, &ret); -+ if (err != ASN1_SUCCESS) -+ return -3; -+ } -+ -+ return ret; -+} -+ -+/** -+ * asn1_get_octet_der: -+ * @der: DER data to decode containing the OCTET SEQUENCE. -+ * @der_len: The length of the @der data to decode. -+ * @ret_len: Output variable containing the encoded length of the DER data. -+ * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in. -+ * @str_size: Length of pre-allocated output buffer. -+ * @str_len: Output variable containing the length of the contents of the OCTET SEQUENCE. -+ * -+ * Extract an OCTET SEQUENCE from DER data. Note that this function -+ * expects the DER data past the tag field, i.e., the length and -+ * content octets. -+ * -+ * Returns: Returns %ASN1_SUCCESS on success, or an error. -+ **/ -+int -+asn1_get_octet_der (const unsigned char *der, int der_len, -+ int *ret_len, unsigned char *str, int str_size, -+ int *str_len) -+{ -+ int len_len = 0; -+ -+ if (der_len <= 0) -+ return ASN1_GENERIC_ERROR; -+ -+ *str_len = asn1_get_length_der (der, der_len, &len_len); -+ -+ if (*str_len < 0) -+ return ASN1_DER_ERROR; -+ -+ *ret_len = *str_len + len_len; -+ if (str_size >= *str_len) -+ { -+ if (*str_len > 0 && str != NULL) -+ memcpy (str, der + len_len, *str_len); -+ } -+ else -+ { -+ return ASN1_MEM_ERROR; -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/*- -+ * _asn1_get_time_der: -+ * @type: %ASN1_ETYPE_GENERALIZED_TIME or %ASN1_ETYPE_UTC_TIME -+ * @der: DER data to decode containing the time -+ * @der_len: Length of DER data to decode. -+ * @ret_len: Output variable containing the length of the DER data. -+ * @str: Pre-allocated output buffer to put the textual time in. -+ * @str_size: Length of pre-allocated output buffer. -+ * @flags: Zero or %ASN1_DECODE_FLAG_STRICT_DER -+ * -+ * Performs basic checks in the DER encoded time object and returns its textual form. -+ * The textual form will be in the YYYYMMDD000000Z format for GeneralizedTime -+ * and YYMMDD000000Z for UTCTime. -+ * -+ * Returns: %ASN1_SUCCESS on success, or an error. -+ -*/ -+static int -+_asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *ret_len, -+ char *str, int str_size, unsigned flags) -+{ -+ int len_len, str_len; -+ unsigned i; -+ unsigned sign_count = 0; -+ unsigned dot_count = 0; -+ const unsigned char *p; -+ -+ if (der_len <= 0 || str == NULL) -+ return ASN1_DER_ERROR; -+ -+ str_len = asn1_get_length_der (der, der_len, &len_len); -+ if (str_len <= 0 || str_size < str_len) -+ return ASN1_DER_ERROR; -+ -+ /* perform some sanity checks on the data */ -+ if (str_len < 8) -+ { -+ warn(); -+ return ASN1_TIME_ENCODING_ERROR; -+ } -+ -+ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) && !(flags & ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME)) -+ { -+ p = &der[len_len]; -+ for (i=0;i<(unsigned)(str_len-1);i++) -+ { -+ if (c_isdigit(p[i]) == 0) -+ { -+ if (type == ASN1_ETYPE_GENERALIZED_TIME) -+ { -+ /* tolerate lax encodings */ -+ if (p[i] == '.' && dot_count == 0) -+ { -+ dot_count++; -+ continue; -+ } -+ -+ /* This is not really valid DER, but there are -+ * structures using that */ -+ if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && -+ (p[i] == '+' || p[i] == '-') && sign_count == 0) -+ { -+ sign_count++; -+ continue; -+ } -+ } -+ -+ warn(); -+ return ASN1_TIME_ENCODING_ERROR; -+ } -+ } -+ -+ if (sign_count == 0 && p[str_len-1] != 'Z') -+ { -+ warn(); -+ return ASN1_TIME_ENCODING_ERROR; -+ } -+ } -+ memcpy (str, der + len_len, str_len); -+ str[str_len] = 0; -+ *ret_len = str_len + len_len; -+ -+ return ASN1_SUCCESS; -+} -+ -+/** -+ * asn1_get_object_id_der: -+ * @der: DER data to decode containing the OBJECT IDENTIFIER -+ * @der_len: Length of DER data to decode. -+ * @ret_len: Output variable containing the length of the DER data. -+ * @str: Pre-allocated output buffer to put the textual object id in. -+ * @str_size: Length of pre-allocated output buffer. -+ * -+ * Converts a DER encoded object identifier to its textual form. This -+ * function expects the DER object identifier without the tag. -+ * -+ * Returns: %ASN1_SUCCESS on success, or an error. -+ **/ -+int -+asn1_get_object_id_der (const unsigned char *der, int der_len, int *ret_len, -+ char *str, int str_size) -+{ -+ int len_len, len, k; -+ int leading, parsed; -+ char temp[LTOSTR_MAX_SIZE]; -+ uint64_t val, val1, val0; -+ -+ *ret_len = 0; -+ if (str && str_size > 0) -+ str[0] = 0; /* no oid */ -+ -+ if (str == NULL || der_len <= 0) -+ return ASN1_GENERIC_ERROR; -+ -+ len = asn1_get_length_der (der, der_len, &len_len); -+ -+ if (len <= 0 || len + len_len > der_len) -+ return ASN1_DER_ERROR; -+ -+ /* leading octet can never be 0x80 */ -+ if (der[len_len] == 0x80) -+ return ASN1_DER_ERROR; -+ -+ val0 = 0; -+ -+ for (k = 0; k < len; k++) -+ { -+ if (INT_LEFT_SHIFT_OVERFLOW (val0, 7)) -+ return ASN1_DER_ERROR; -+ -+ val0 <<= 7; -+ val0 |= der[len_len + k] & 0x7F; -+ if (!(der[len_len + k] & 0x80)) -+ break; -+ } -+ parsed = ++k; -+ -+ /* val0 = (X*40) + Y, X={0,1,2}, Y<=39 when X={0,1} */ -+ /* X = val, Y = val1 */ -+ -+ /* check if X == 0 */ -+ val = 0; -+ val1 = val0; -+ if (val1 > 39) -+ { -+ val = 1; -+ val1 = val0 - 40; -+ if (val1 > 39) -+ { -+ val = 2; -+ val1 = val0 - 80; -+ } -+ } -+ -+ _asn1_str_cpy (str, str_size, _asn1_ltostr (val, temp)); -+ _asn1_str_cat (str, str_size, "."); -+ _asn1_str_cat (str, str_size, _asn1_ltostr (val1, temp)); -+ -+ val = 0; -+ leading = 1; -+ for (k = parsed; k < len; k++) -+ { -+ /* X.690 mandates that the leading byte must never be 0x80 -+ */ -+ if (leading != 0 && der[len_len + k] == 0x80) -+ return ASN1_DER_ERROR; -+ leading = 0; -+ -+ /* check for wrap around */ -+ if (INT_LEFT_SHIFT_OVERFLOW (val, 7)) -+ return ASN1_DER_ERROR; -+ -+ val = val << 7; -+ val |= der[len_len + k] & 0x7F; -+ -+ if (!(der[len_len + k] & 0x80)) -+ { -+ _asn1_str_cat (str, str_size, "."); -+ _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); -+ val = 0; -+ leading = 1; -+ } -+ } -+ -+ if (INT_ADD_OVERFLOW (len, len_len)) -+ return ASN1_DER_ERROR; -+ -+ *ret_len = len + len_len; -+ -+ return ASN1_SUCCESS; -+} -+ -+/** -+ * asn1_get_bit_der: -+ * @der: DER data to decode containing the BIT SEQUENCE. -+ * @der_len: Length of DER data to decode. -+ * @ret_len: Output variable containing the length of the DER data. -+ * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in. -+ * @str_size: Length of pre-allocated output buffer. -+ * @bit_len: Output variable containing the size of the BIT SEQUENCE. -+ * -+ * Extract a BIT SEQUENCE from DER data. -+ * -+ * Returns: %ASN1_SUCCESS on success, or an error. -+ **/ -+int -+asn1_get_bit_der (const unsigned char *der, int der_len, -+ int *ret_len, unsigned char *str, int str_size, -+ int *bit_len) -+{ -+ int len_len = 0, len_byte; -+ -+ if (der_len <= 0) -+ return ASN1_GENERIC_ERROR; -+ -+ len_byte = asn1_get_length_der (der, der_len, &len_len) - 1; -+ if (len_byte < 0) -+ return ASN1_DER_ERROR; -+ -+ *ret_len = len_byte + len_len + 1; -+ *bit_len = len_byte * 8 - der[len_len]; -+ -+ if (*bit_len < 0) -+ return ASN1_DER_ERROR; -+ -+ if (str_size >= len_byte) -+ { -+ if (len_byte > 0 && str) -+ memcpy (str, der + len_len + 1, len_byte); -+ } -+ else -+ { -+ return ASN1_MEM_ERROR; -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+/* tag_len: the total tag length (explicit+inner) -+ * inner_tag_len: the inner_tag length -+ */ -+static int -+_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len, -+ int *tag_len, int *inner_tag_len, unsigned flags) -+{ -+ asn1_node p; -+ int counter, len2, len3, is_tag_implicit; -+ int result; -+ unsigned long tag, tag_implicit = 0; -+ unsigned char class, class2, class_implicit = 0; -+ -+ if (der_len <= 0) -+ return ASN1_GENERIC_ERROR; -+ -+ counter = is_tag_implicit = 0; -+ -+ if (node->type & CONST_TAG) -+ { -+ p = node->down; -+ while (p) -+ { -+ if (type_field (p->type) == ASN1_ETYPE_TAG) -+ { -+ if (p->type & CONST_APPLICATION) -+ class2 = ASN1_CLASS_APPLICATION; -+ else if (p->type & CONST_UNIVERSAL) -+ class2 = ASN1_CLASS_UNIVERSAL; -+ else if (p->type & CONST_PRIVATE) -+ class2 = ASN1_CLASS_PRIVATE; -+ else -+ class2 = ASN1_CLASS_CONTEXT_SPECIFIC; -+ -+ if (p->type & CONST_EXPLICIT) -+ { -+ if (asn1_get_tag_der -+ (der + counter, der_len, &class, &len2, -+ &tag) != ASN1_SUCCESS) -+ return ASN1_DER_ERROR; -+ -+ DECR_LEN(der_len, len2); -+ counter += len2; -+ -+ if (flags & ASN1_DECODE_FLAG_STRICT_DER) -+ len3 = -+ asn1_get_length_der (der + counter, der_len, -+ &len2); -+ else -+ len3 = -+ asn1_get_length_ber (der + counter, der_len, -+ &len2); -+ if (len3 < 0) -+ return ASN1_DER_ERROR; -+ -+ DECR_LEN(der_len, len2); -+ counter += len2; -+ -+ if (!is_tag_implicit) -+ { -+ if ((class != (class2 | ASN1_CLASS_STRUCTURED)) || -+ (tag != strtoul ((char *) p->value, NULL, 10))) -+ return ASN1_TAG_ERROR; -+ } -+ else -+ { /* ASN1_TAG_IMPLICIT */ -+ if ((class != class_implicit) || (tag != tag_implicit)) -+ return ASN1_TAG_ERROR; -+ } -+ is_tag_implicit = 0; -+ } -+ else -+ { /* ASN1_TAG_IMPLICIT */ -+ if (!is_tag_implicit) -+ { -+ if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) || -+ (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) -+ || (type_field (node->type) == ASN1_ETYPE_SET) -+ || (type_field (node->type) == ASN1_ETYPE_SET_OF)) -+ class2 |= ASN1_CLASS_STRUCTURED; -+ class_implicit = class2; -+ tag_implicit = strtoul ((char *) p->value, NULL, 10); -+ is_tag_implicit = 1; -+ } -+ } -+ } -+ p = p->right; -+ } -+ } -+ -+ if (is_tag_implicit) -+ { -+ if (asn1_get_tag_der -+ (der + counter, der_len, &class, &len2, -+ &tag) != ASN1_SUCCESS) -+ return ASN1_DER_ERROR; -+ -+ DECR_LEN(der_len, len2); -+ -+ if ((class != class_implicit) || (tag != tag_implicit)) -+ { -+ if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING) -+ { -+ class_implicit |= ASN1_CLASS_STRUCTURED; -+ if ((class != class_implicit) || (tag != tag_implicit)) -+ return ASN1_TAG_ERROR; -+ } -+ else -+ return ASN1_TAG_ERROR; -+ } -+ } -+ else -+ { -+ unsigned type = type_field (node->type); -+ if (type == ASN1_ETYPE_TAG) -+ { -+ *tag_len = 0; -+ if (inner_tag_len) -+ *inner_tag_len = 0; -+ return ASN1_SUCCESS; -+ } -+ -+ if (asn1_get_tag_der -+ (der + counter, der_len, &class, &len2, -+ &tag) != ASN1_SUCCESS) -+ return ASN1_DER_ERROR; -+ -+ DECR_LEN(der_len, len2); -+ -+ switch (type) -+ { -+ case ASN1_ETYPE_NULL: -+ case ASN1_ETYPE_BOOLEAN: -+ case ASN1_ETYPE_INTEGER: -+ case ASN1_ETYPE_ENUMERATED: -+ case ASN1_ETYPE_OBJECT_ID: -+ case ASN1_ETYPE_GENERALSTRING: -+ case ASN1_ETYPE_NUMERIC_STRING: -+ case ASN1_ETYPE_IA5_STRING: -+ case ASN1_ETYPE_TELETEX_STRING: -+ case ASN1_ETYPE_PRINTABLE_STRING: -+ case ASN1_ETYPE_UNIVERSAL_STRING: -+ case ASN1_ETYPE_BMP_STRING: -+ case ASN1_ETYPE_UTF8_STRING: -+ case ASN1_ETYPE_VISIBLE_STRING: -+ case ASN1_ETYPE_BIT_STRING: -+ case ASN1_ETYPE_SEQUENCE: -+ case ASN1_ETYPE_SEQUENCE_OF: -+ case ASN1_ETYPE_SET: -+ case ASN1_ETYPE_SET_OF: -+ case ASN1_ETYPE_GENERALIZED_TIME: -+ case ASN1_ETYPE_UTC_TIME: -+ if ((class != _asn1_tags[type].class) -+ || (tag != _asn1_tags[type].tag)) -+ return ASN1_DER_ERROR; -+ break; -+ -+ case ASN1_ETYPE_OCTET_STRING: -+ /* OCTET STRING is handled differently to allow -+ * BER encodings (structured class). */ -+ if (((class != ASN1_CLASS_UNIVERSAL) -+ && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))) -+ || (tag != ASN1_TAG_OCTET_STRING)) -+ return ASN1_DER_ERROR; -+ break; -+ case ASN1_ETYPE_ANY: -+ counter -= len2; -+ break; -+ case ASN1_ETYPE_CHOICE: -+ counter -= len2; -+ break; -+ default: -+ return ASN1_DER_ERROR; -+ break; -+ } -+ } -+ -+ counter += len2; -+ *tag_len = counter; -+ if (inner_tag_len) -+ *inner_tag_len = len2; -+ return ASN1_SUCCESS; -+ -+cleanup: -+ return result; -+} -+ -+static int -+extract_tag_der_recursive(asn1_node node, const unsigned char *der, int der_len, -+ int *ret_len, int *inner_len, unsigned flags) -+{ -+asn1_node p; -+int ris = ASN1_DER_ERROR; -+ -+ if (type_field (node->type) == ASN1_ETYPE_CHOICE) -+ { -+ p = node->down; -+ while (p) -+ { -+ ris = _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len, flags); -+ if (ris == ASN1_SUCCESS) -+ break; -+ p = p->right; -+ } -+ -+ *ret_len = 0; -+ return ris; -+ } -+ else -+ return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len, flags); -+} -+ -+static int -+_asn1_delete_not_used (asn1_node node) -+{ -+ asn1_node p, p2; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = node; -+ while (p) -+ { -+ if (p->type & CONST_NOT_USED) -+ { -+ p2 = NULL; -+ if (p != node) -+ { -+ p2 = _asn1_find_left (p); -+ if (!p2) -+ p2 = _asn1_find_up (p); -+ } -+ asn1_delete_structure (&p); -+ p = p2; -+ } -+ -+ if (!p) -+ break; /* reach node */ -+ -+ if (p->down) -+ { -+ p = p->down; -+ } -+ else -+ { -+ if (p == node) -+ p = NULL; -+ else if (p->right) -+ p = p->right; -+ else -+ { -+ while (1) -+ { -+ p = _asn1_find_up (p); -+ if (p == node) -+ { -+ p = NULL; -+ break; -+ } -+ if (p->right) -+ { -+ p = p->right; -+ break; -+ } -+ } -+ } -+ } -+ } -+ return ASN1_SUCCESS; -+} -+ -+static int -+_asn1_get_indefinite_length_string (const unsigned char *der, -+ int der_len, int *len) -+{ -+ int len2, len3, counter, indefinite; -+ int result; -+ unsigned long tag; -+ unsigned char class; -+ -+ counter = indefinite = 0; -+ -+ while (1) -+ { -+ if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0)) -+ { -+ counter += 2; -+ DECR_LEN(der_len, 2); -+ -+ indefinite--; -+ if (indefinite <= 0) -+ break; -+ else -+ continue; -+ } -+ -+ if (asn1_get_tag_der -+ (der + counter, der_len, &class, &len2, -+ &tag) != ASN1_SUCCESS) -+ return ASN1_DER_ERROR; -+ -+ DECR_LEN(der_len, len2); -+ counter += len2; -+ -+ len2 = asn1_get_length_der (der + counter, der_len, &len3); -+ if (len2 < -1) -+ return ASN1_DER_ERROR; -+ -+ if (len2 == -1) -+ { -+ indefinite++; -+ counter += 1; -+ DECR_LEN(der_len, 1); -+ } -+ else -+ { -+ counter += len2 + len3; -+ DECR_LEN(der_len, len2+len3); -+ } -+ } -+ -+ *len = counter; -+ return ASN1_SUCCESS; -+ -+cleanup: -+ return result; -+} -+ -+static void delete_unneeded_choice_fields(asn1_node p) -+{ -+ asn1_node p2; -+ -+ while (p->right) -+ { -+ p2 = p->right; -+ asn1_delete_structure (&p2); -+ } -+} -+ -+ -+/** -+ * asn1_der_decoding2 -+ * @element: pointer to an ASN1 structure. -+ * @ider: vector that contains the DER encoding. -+ * @max_ider_len: pointer to an integer giving the information about the -+ * maximal number of bytes occupied by *@ider. The real size of the DER -+ * encoding is returned through this pointer. -+ * @flags: flags controlling the behaviour of the function. -+ * @errorDescription: null-terminated string contains details when an -+ * error occurred. -+ * -+ * Fill the structure *@element with values of a DER encoding string. The -+ * structure must just be created with function asn1_create_element(). -+ * -+ * If %ASN1_DECODE_FLAG_ALLOW_PADDING flag is set then the function will ignore -+ * padding after the decoded DER data. Upon a successful return the value of -+ * *@max_ider_len will be set to the number of bytes decoded. -+ * -+ * If %ASN1_DECODE_FLAG_STRICT_DER flag is set then the function will -+ * not decode any BER-encoded elements. -+ * -+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND -+ * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or -+ * %ASN1_DER_ERROR if the der encoding doesn't match the structure -+ * name (*@ELEMENT deleted). -+ **/ -+int -+asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len, -+ unsigned int flags, char *errorDescription) -+{ -+ asn1_node node, p, p2, p3; -+ char temp[128]; -+ int counter, len2, len3, len4, move, ris, tlen; -+ struct node_tail_cache_st tcache = {NULL, NULL}; -+ unsigned char class; -+ unsigned long tag; -+ int tag_len; -+ int indefinite, result, total_len = *max_ider_len, ider_len = *max_ider_len; -+ int inner_tag_len; -+ unsigned char *ptmp; -+ const unsigned char *ptag; -+ const unsigned char *der = ider; -+ -+ node = *element; -+ -+ if (errorDescription != NULL) -+ errorDescription[0] = 0; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ if (node->type & CONST_OPTION) -+ { -+ result = ASN1_GENERIC_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ counter = 0; -+ move = DOWN; -+ p = node; -+ while (1) -+ { -+ tag_len = 0; -+ inner_tag_len = 0; -+ ris = ASN1_SUCCESS; -+ if (move != UP) -+ { -+ if (p->type & CONST_SET) -+ { -+ p2 = _asn1_find_up (p); -+ len2 = p2->tmp_ival; -+ if (len2 == -1) -+ { -+ if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1]) -+ { -+ p = p2; -+ move = UP; -+ counter += 2; -+ DECR_LEN(ider_len, 2); -+ continue; -+ } -+ } -+ else if (counter == len2) -+ { -+ p = p2; -+ move = UP; -+ continue; -+ } -+ else if (counter > len2) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ p2 = p2->down; -+ while (p2) -+ { -+ if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) -+ { -+ ris = -+ extract_tag_der_recursive (p2, der + counter, -+ ider_len, &len2, NULL, flags); -+ if (ris == ASN1_SUCCESS) -+ { -+ p2->type &= ~CONST_NOT_USED; -+ p = p2; -+ break; -+ } -+ } -+ p2 = p2->right; -+ } -+ if (p2 == NULL) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ } -+ -+ /* the position in the DER structure this starts */ -+ p->start = counter; -+ p->end = total_len - 1; -+ -+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) -+ { -+ p2 = _asn1_find_up (p); -+ len2 = p2->tmp_ival; -+ if (counter == len2) -+ { -+ if (p->right) -+ { -+ p2 = p->right; -+ move = RIGHT; -+ } -+ else -+ move = UP; -+ -+ if (p->type & CONST_OPTION) -+ asn1_delete_structure (&p); -+ -+ p = p2; -+ continue; -+ } -+ } -+ -+ if (type_field (p->type) == ASN1_ETYPE_CHOICE) -+ { -+ while (p->down) -+ { -+ ris = -+ extract_tag_der_recursive (p->down, der + counter, -+ ider_len, &len2, NULL, flags); -+ -+ if (ris == ASN1_SUCCESS) -+ { -+ delete_unneeded_choice_fields(p->down); -+ break; -+ } -+ else if (ris == ASN1_ERROR_TYPE_ANY) -+ { -+ result = ASN1_ERROR_TYPE_ANY; -+ warn(); -+ goto cleanup; -+ } -+ else -+ { -+ p2 = p->down; -+ asn1_delete_structure (&p2); -+ } -+ } -+ -+ if (p->down == NULL) -+ { -+ if (!(p->type & CONST_OPTION)) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ } -+ else if (type_field (p->type) != ASN1_ETYPE_CHOICE) -+ p = p->down; -+ -+ p->start = counter; -+ } -+ -+ if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) -+ { -+ p2 = _asn1_find_up (p); -+ len2 = p2->tmp_ival; -+ -+ if ((len2 != -1) && (counter > len2)) -+ ris = ASN1_TAG_ERROR; -+ } -+ -+ if (ris == ASN1_SUCCESS) -+ ris = -+ extract_tag_der_recursive (p, der + counter, ider_len, -+ &tag_len, &inner_tag_len, flags); -+ -+ if (ris != ASN1_SUCCESS) -+ { -+ if (p->type & CONST_OPTION) -+ { -+ p->type |= CONST_NOT_USED; -+ move = RIGHT; -+ } -+ else if (p->type & CONST_DEFAULT) -+ { -+ _asn1_set_value (p, NULL, 0); -+ move = RIGHT; -+ } -+ else -+ { -+ if (errorDescription != NULL) -+ _asn1_error_description_tag_error (p, errorDescription); -+ -+ result = ASN1_TAG_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ } -+ else -+ { -+ DECR_LEN(ider_len, tag_len); -+ counter += tag_len; -+ } -+ } -+ -+ if (ris == ASN1_SUCCESS) -+ { -+ switch (type_field (p->type)) -+ { -+ case ASN1_ETYPE_NULL: -+ DECR_LEN(ider_len, 1); -+ if (der[counter]) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ counter++; -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_BOOLEAN: -+ DECR_LEN(ider_len, 2); -+ -+ if (der[counter++] != 1) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ if (der[counter++] == 0) -+ _asn1_set_value (p, "F", 1); -+ else -+ _asn1_set_value (p, "T", 1); -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_INTEGER: -+ case ASN1_ETYPE_ENUMERATED: -+ len2 = -+ asn1_get_length_der (der + counter, ider_len, &len3); -+ if (len2 < 0) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len3+len2); -+ -+ _asn1_set_value (p, der + counter, len3 + len2); -+ counter += len3 + len2; -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_OBJECT_ID: -+ result = -+ asn1_get_object_id_der (der + counter, ider_len, &len2, -+ temp, sizeof (temp)); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len2); -+ -+ tlen = strlen (temp); -+ if (tlen > 0) -+ _asn1_set_value (p, temp, tlen + 1); -+ -+ counter += len2; -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_GENERALIZED_TIME: -+ case ASN1_ETYPE_UTC_TIME: -+ result = -+ _asn1_get_time_der (type_field (p->type), der + counter, ider_len, &len2, temp, -+ sizeof (temp) - 1, flags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len2); -+ -+ tlen = strlen (temp); -+ if (tlen > 0) -+ _asn1_set_value (p, temp, tlen); -+ -+ counter += len2; -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_OCTET_STRING: -+ if (counter < inner_tag_len) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ ptag = der + counter - inner_tag_len; -+ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) || !(ptag[0] & ASN1_CLASS_STRUCTURED)) -+ { -+ if (ptag[0] & ASN1_CLASS_STRUCTURED) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ len2 = -+ asn1_get_length_der (der + counter, ider_len, &len3); -+ if (len2 < 0) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len3+len2); -+ -+ _asn1_set_value (p, der + counter, len3 + len2); -+ counter += len3 + len2; -+ } -+ else -+ { -+ unsigned dflags = 0, vlen, ber_len; -+ -+ if (ptag[0] & ASN1_CLASS_STRUCTURED) -+ dflags |= DECODE_FLAG_CONSTRUCTED; -+ -+ result = _asn1_decode_simple_ber(type_field (p->type), der+counter, ider_len, &ptmp, &vlen, &ber_len, dflags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, ber_len); -+ -+ _asn1_set_value_lv (p, ptmp, vlen); -+ -+ counter += ber_len; -+ free(ptmp); -+ } -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_GENERALSTRING: -+ case ASN1_ETYPE_NUMERIC_STRING: -+ case ASN1_ETYPE_IA5_STRING: -+ case ASN1_ETYPE_TELETEX_STRING: -+ case ASN1_ETYPE_PRINTABLE_STRING: -+ case ASN1_ETYPE_UNIVERSAL_STRING: -+ case ASN1_ETYPE_BMP_STRING: -+ case ASN1_ETYPE_UTF8_STRING: -+ case ASN1_ETYPE_VISIBLE_STRING: -+ case ASN1_ETYPE_BIT_STRING: -+ len2 = -+ asn1_get_length_der (der + counter, ider_len, &len3); -+ if (len2 < 0) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len3+len2); -+ -+ _asn1_set_value (p, der + counter, len3 + len2); -+ counter += len3 + len2; -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_SEQUENCE: -+ case ASN1_ETYPE_SET: -+ if (move == UP) -+ { -+ len2 = p->tmp_ival; -+ p->tmp_ival = 0; -+ if (len2 == -1) -+ { /* indefinite length method */ -+ DECR_LEN(ider_len, 2); -+ if ((der[counter]) || der[counter + 1]) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ counter += 2; -+ } -+ else -+ { /* definite length method */ -+ if (len2 != counter) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ } -+ move = RIGHT; -+ } -+ else -+ { /* move==DOWN || move==RIGHT */ -+ len3 = -+ asn1_get_length_der (der + counter, ider_len, &len2); -+ if (IS_ERR(len3, flags)) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len2); -+ counter += len2; -+ -+ if (len3 > 0) -+ { -+ p->tmp_ival = counter + len3; -+ move = DOWN; -+ } -+ else if (len3 == 0) -+ { -+ p2 = p->down; -+ while (p2) -+ { -+ if (type_field (p2->type) != ASN1_ETYPE_TAG) -+ { -+ p3 = p2->right; -+ asn1_delete_structure (&p2); -+ p2 = p3; -+ } -+ else -+ p2 = p2->right; -+ } -+ move = RIGHT; -+ } -+ else -+ { /* indefinite length method */ -+ p->tmp_ival = -1; -+ move = DOWN; -+ } -+ } -+ break; -+ case ASN1_ETYPE_SEQUENCE_OF: -+ case ASN1_ETYPE_SET_OF: -+ if (move == UP) -+ { -+ len2 = p->tmp_ival; -+ if (len2 == -1) -+ { /* indefinite length method */ -+ if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1])) -+ { -+ result = _asn1_append_sequence_set (p, &tcache); -+ if (result != 0) -+ { -+ warn(); -+ goto cleanup; -+ } -+ p = tcache.tail; -+ move = RIGHT; -+ continue; -+ } -+ -+ p->tmp_ival = 0; -+ tcache.tail = NULL; /* finished decoding this structure */ -+ tcache.head = NULL; -+ DECR_LEN(ider_len, 2); -+ counter += 2; -+ } -+ else -+ { /* definite length method */ -+ if (len2 > counter) -+ { -+ result = _asn1_append_sequence_set (p, &tcache); -+ if (result != 0) -+ { -+ warn(); -+ goto cleanup; -+ } -+ p = tcache.tail; -+ move = RIGHT; -+ continue; -+ } -+ -+ p->tmp_ival = 0; -+ tcache.tail = NULL; /* finished decoding this structure */ -+ tcache.head = NULL; -+ -+ if (len2 != counter) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ } -+ } -+ else -+ { /* move==DOWN || move==RIGHT */ -+ len3 = -+ asn1_get_length_der (der + counter, ider_len, &len2); -+ if (IS_ERR(len3, flags)) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len2); -+ counter += len2; -+ if (len3) -+ { -+ if (len3 > 0) -+ { /* definite length method */ -+ p->tmp_ival = counter + len3; -+ } -+ else -+ { /* indefinite length method */ -+ p->tmp_ival = -1; -+ } -+ -+ p2 = p->down; -+ if (p2 == NULL) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ while ((type_field (p2->type) == ASN1_ETYPE_TAG) -+ || (type_field (p2->type) == ASN1_ETYPE_SIZE)) -+ p2 = p2->right; -+ if (p2->right == NULL) -+ { -+ result = _asn1_append_sequence_set (p, &tcache); -+ if (result != 0) -+ { -+ warn(); -+ goto cleanup; -+ } -+ } -+ p = p2; -+ } -+ } -+ move = RIGHT; -+ break; -+ case ASN1_ETYPE_ANY: -+ /* Check indefinite lenth method in an EXPLICIT TAG */ -+ -+ if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && (p->type & CONST_TAG) && -+ tag_len == 2 && (der[counter - 1] == 0x80)) -+ indefinite = 1; -+ else -+ indefinite = 0; -+ -+ if (asn1_get_tag_der -+ (der + counter, ider_len, &class, &len2, -+ &tag) != ASN1_SUCCESS) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len2); -+ -+ len4 = -+ asn1_get_length_der (der + counter + len2, -+ ider_len, &len3); -+ if (IS_ERR(len4, flags)) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ if (len4 != -1) /* definite */ -+ { -+ len2 += len4; -+ -+ DECR_LEN(ider_len, len4+len3); -+ _asn1_set_value_lv (p, der + counter, len2 + len3); -+ counter += len2 + len3; -+ } -+ else /* == -1 */ -+ { /* indefinite length */ -+ ider_len += len2; /* undo DECR_LEN */ -+ -+ if (counter == 0) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ -+ result = -+ _asn1_get_indefinite_length_string (der + counter, ider_len, &len2); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ DECR_LEN(ider_len, len2); -+ _asn1_set_value_lv (p, der + counter, len2); -+ counter += len2; -+ -+ } -+ -+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with -+ an indefinite length method. */ -+ if (indefinite) -+ { -+ DECR_LEN(ider_len, 2); -+ if (!der[counter] && !der[counter + 1]) -+ { -+ counter += 2; -+ } -+ else -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ } -+ -+ move = RIGHT; -+ break; -+ default: -+ move = (move == UP) ? RIGHT : DOWN; -+ break; -+ } -+ } -+ -+ if (p) -+ { -+ p->end = counter - 1; -+ } -+ -+ if (p == node && move != DOWN) -+ break; -+ -+ if (move == DOWN) -+ { -+ if (p->down) -+ p = p->down; -+ else -+ move = RIGHT; -+ } -+ if ((move == RIGHT) && !(p->type & CONST_SET)) -+ { -+ if (p->right) -+ p = p->right; -+ else -+ move = UP; -+ } -+ if (move == UP) -+ p = _asn1_find_up (p); -+ } -+ -+ _asn1_delete_not_used (*element); -+ -+ if ((ider_len < 0) || -+ (!(flags & ASN1_DECODE_FLAG_ALLOW_PADDING) && (ider_len != 0))) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ -+ *max_ider_len = total_len - ider_len; -+ -+ return ASN1_SUCCESS; -+ -+cleanup: -+ asn1_delete_structure (element); -+ return result; -+} -+ -+ -+/** -+ * asn1_der_decoding: -+ * @element: pointer to an ASN1 structure. -+ * @ider: vector that contains the DER encoding. -+ * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1]. -+ * @errorDescription: null-terminated string contains details when an -+ * error occurred. -+ * -+ * Fill the structure *@element with values of a DER encoding -+ * string. The structure must just be created with function -+ * asn1_create_element(). -+ * -+ * Note that the *@element variable is provided as a pointer for -+ * historical reasons. -+ * -+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND -+ * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or -+ * %ASN1_DER_ERROR if the der encoding doesn't match the structure -+ * name (*@ELEMENT deleted). -+ **/ -+int -+asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, -+ char *errorDescription) -+{ -+ return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription); -+} -+ -+/** -+ * asn1_der_decoding_element: -+ * @structure: pointer to an ASN1 structure -+ * @elementName: name of the element to fill -+ * @ider: vector that contains the DER encoding of the whole structure. -+ * @len: number of bytes of *der: der[0]..der[len-1] -+ * @errorDescription: null-terminated string contains details when an -+ * error occurred. -+ * -+ * Fill the element named @ELEMENTNAME with values of a DER encoding -+ * string. The structure must just be created with function -+ * asn1_create_element(). The DER vector must contain the encoding -+ * string of the whole @STRUCTURE. If an error occurs during the -+ * decoding procedure, the *@STRUCTURE is deleted and set equal to -+ * %NULL. -+ * -+ * This function is deprecated and may just be an alias to asn1_der_decoding -+ * in future versions. Use asn1_der_decoding() instead. -+ * -+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND -+ * if ELEMENT is %NULL or @elementName == NULL, and -+ * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't -+ * match the structure @structure (*ELEMENT deleted). -+ **/ -+int -+asn1_der_decoding_element (asn1_node * structure, const char *elementName, -+ const void *ider, int len, char *errorDescription) -+{ -+ return asn1_der_decoding(structure, ider, len, errorDescription); -+} -+ -+/** -+ * asn1_der_decoding_startEnd: -+ * @element: pointer to an ASN1 element -+ * @ider: vector that contains the DER encoding. -+ * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1] -+ * @name_element: an element of NAME structure. -+ * @start: the position of the first byte of NAME_ELEMENT decoding -+ * (@ider[*start]) -+ * @end: the position of the last byte of NAME_ELEMENT decoding -+ * (@ider[*end]) -+ * -+ * Find the start and end point of an element in a DER encoding -+ * string. I mean that if you have a der encoding and you have already -+ * used the function asn1_der_decoding() to fill a structure, it may -+ * happen that you want to find the piece of string concerning an -+ * element of the structure. -+ * -+ * One example is the sequence "tbsCertificate" inside an X509 -+ * certificate. -+ * -+ * Note that since libtasn1 3.7 the @ider and @ider_len parameters -+ * can be omitted, if the element is already decoded using asn1_der_decoding(). -+ * -+ * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND -+ * if ELEMENT is %asn1_node EMPTY or @name_element is not a valid -+ * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding -+ * doesn't match the structure ELEMENT. -+ **/ -+int -+asn1_der_decoding_startEnd (asn1_node element, const void *ider, int ider_len, -+ const char *name_element, int *start, int *end) -+{ -+ asn1_node node, node_to_find; -+ int result = ASN1_DER_ERROR; -+ -+ node = element; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ node_to_find = asn1_find_node (node, name_element); -+ -+ if (node_to_find == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ *start = node_to_find->start; -+ *end = node_to_find->end; -+ -+ if (*start == 0 && *end == 0) -+ { -+ if (ider == NULL || ider_len == 0) -+ return ASN1_GENERIC_ERROR; -+ -+ /* it seems asn1_der_decoding() wasn't called before. Do it now */ -+ result = asn1_der_decoding (&node, ider, ider_len, NULL); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ return result; -+ } -+ -+ node_to_find = asn1_find_node (node, name_element); -+ if (node_to_find == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ *start = node_to_find->start; -+ *end = node_to_find->end; -+ } -+ -+ if (*end < *start) -+ return ASN1_GENERIC_ERROR; -+ -+ return ASN1_SUCCESS; -+} -+ -+/** -+ * asn1_expand_any_defined_by: -+ * @definitions: ASN1 definitions -+ * @element: pointer to an ASN1 structure -+ * -+ * Expands every "ANY DEFINED BY" element of a structure created from -+ * a DER decoding process (asn1_der_decoding function). The element -+ * ANY must be defined by an OBJECT IDENTIFIER. The type used to -+ * expand the element ANY is the first one following the definition of -+ * the actual value of the OBJECT IDENTIFIER. -+ * -+ * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if -+ * some "ANY DEFINED BY" element couldn't be expanded due to a -+ * problem in OBJECT_ID -> TYPE association, or other error codes -+ * depending on DER decoding. -+ **/ -+int -+asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element) -+{ -+ char name[2 * ASN1_MAX_NAME_SIZE + 2], -+ value[ASN1_MAX_NAME_SIZE]; -+ int retCode = ASN1_SUCCESS, result; -+ int len, len2, len3; -+ asn1_node_const p2; -+ asn1_node p, p3, aux = NULL; -+ char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; -+ const char *definitionsName; -+ -+ if ((definitions == NULL) || (*element == NULL)) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ definitionsName = definitions->name; -+ -+ p = *element; -+ while (p) -+ { -+ -+ switch (type_field (p->type)) -+ { -+ case ASN1_ETYPE_ANY: -+ if ((p->type & CONST_DEFINED_BY) && (p->value)) -+ { -+ /* search the "DEF_BY" element */ -+ p2 = p->down; -+ while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT)) -+ p2 = p2->right; -+ -+ if (!p2) -+ { -+ retCode = ASN1_ERROR_TYPE_ANY; -+ break; -+ } -+ -+ p3 = _asn1_find_up (p); -+ -+ if (!p3) -+ { -+ retCode = ASN1_ERROR_TYPE_ANY; -+ break; -+ } -+ -+ p3 = p3->down; -+ while (p3) -+ { -+ if (!(strcmp (p3->name, p2->name))) -+ break; -+ p3 = p3->right; -+ } -+ -+ if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || -+ (p3->value == NULL)) -+ { -+ -+ p3 = _asn1_find_up (p); -+ p3 = _asn1_find_up (p3); -+ -+ if (!p3) -+ { -+ retCode = ASN1_ERROR_TYPE_ANY; -+ break; -+ } -+ -+ p3 = p3->down; -+ -+ while (p3) -+ { -+ if (!(strcmp (p3->name, p2->name))) -+ break; -+ p3 = p3->right; -+ } -+ -+ if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) -+ || (p3->value == NULL)) -+ { -+ retCode = ASN1_ERROR_TYPE_ANY; -+ break; -+ } -+ } -+ -+ /* search the OBJECT_ID into definitions */ -+ p2 = definitions->down; -+ while (p2) -+ { -+ if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && -+ (p2->type & CONST_ASSIGN)) -+ { -+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name); -+ -+ len = ASN1_MAX_NAME_SIZE; -+ result = -+ asn1_read_value (definitions, name, value, &len); -+ -+ if ((result == ASN1_SUCCESS) -+ && (!_asn1_strcmp (p3->value, value))) -+ { -+ p2 = p2->right; /* pointer to the structure to -+ use for expansion */ -+ while ((p2) && (p2->type & CONST_ASSIGN)) -+ p2 = p2->right; -+ -+ if (p2) -+ { -+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name); -+ -+ result = -+ asn1_create_element (definitions, name, &aux); -+ if (result == ASN1_SUCCESS) -+ { -+ _asn1_cpy_name (aux, p); -+ len2 = -+ asn1_get_length_der (p->value, -+ p->value_len, &len3); -+ if (len2 < 0) -+ return ASN1_DER_ERROR; -+ -+ result = -+ asn1_der_decoding (&aux, p->value + len3, -+ len2, -+ errorDescription); -+ if (result == ASN1_SUCCESS) -+ { -+ -+ _asn1_set_right (aux, p->right); -+ _asn1_set_right (p, aux); -+ -+ result = asn1_delete_structure (&p); -+ if (result == ASN1_SUCCESS) -+ { -+ p = aux; -+ aux = NULL; -+ break; -+ } -+ else -+ { /* error with asn1_delete_structure */ -+ asn1_delete_structure (&aux); -+ retCode = result; -+ break; -+ } -+ } -+ else -+ { /* error with asn1_der_decoding */ -+ retCode = result; -+ break; -+ } -+ } -+ else -+ { /* error with asn1_create_element */ -+ retCode = result; -+ break; -+ } -+ } -+ else -+ { /* error with the pointer to the structure to exapand */ -+ retCode = ASN1_ERROR_TYPE_ANY; -+ break; -+ } -+ } -+ } -+ p2 = p2->right; -+ } /* end while */ -+ -+ if (!p2) -+ { -+ retCode = ASN1_ERROR_TYPE_ANY; -+ break; -+ } -+ -+ } -+ break; -+ default: -+ break; -+ } -+ -+ -+ if (p->down) -+ { -+ p = p->down; -+ } -+ else if (p == *element) -+ { -+ p = NULL; -+ break; -+ } -+ else if (p->right) -+ p = p->right; -+ else -+ { -+ while (1) -+ { -+ p = _asn1_find_up (p); -+ if (p == *element) -+ { -+ p = NULL; -+ break; -+ } -+ if (p->right) -+ { -+ p = p->right; -+ break; -+ } -+ } -+ } -+ } -+ -+ return retCode; -+} -+ -+/** -+ * asn1_expand_octet_string: -+ * @definitions: ASN1 definitions -+ * @element: pointer to an ASN1 structure -+ * @octetName: name of the OCTECT STRING field to expand. -+ * @objectName: name of the OBJECT IDENTIFIER field to use to define -+ * the type for expansion. -+ * -+ * Expands an "OCTET STRING" element of a structure created from a DER -+ * decoding process (the asn1_der_decoding() function). The type used -+ * for expansion is the first one following the definition of the -+ * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME. -+ * -+ * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND -+ * if @objectName or @octetName are not correct, -+ * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to -+ * use for expansion, or other errors depending on DER decoding. -+ **/ -+int -+asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, -+ const char *octetName, const char *objectName) -+{ -+ char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE]; -+ int retCode = ASN1_SUCCESS, result; -+ int len, len2, len3; -+ asn1_node_const p2; -+ asn1_node aux = NULL; -+ asn1_node octetNode = NULL, objectNode = NULL; -+ char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; -+ -+ if ((definitions == NULL) || (*element == NULL)) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ octetNode = asn1_find_node (*element, octetName); -+ if (octetNode == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING) -+ return ASN1_ELEMENT_NOT_FOUND; -+ if (octetNode->value == NULL) -+ return ASN1_VALUE_NOT_FOUND; -+ -+ objectNode = asn1_find_node (*element, objectName); -+ if (objectNode == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ if (objectNode->value == NULL) -+ return ASN1_VALUE_NOT_FOUND; -+ -+ -+ /* search the OBJECT_ID into definitions */ -+ p2 = definitions->down; -+ while (p2) -+ { -+ if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && -+ (p2->type & CONST_ASSIGN)) -+ { -+ strcpy (name, definitions->name); -+ strcat (name, "."); -+ strcat (name, p2->name); -+ -+ len = sizeof (value); -+ result = asn1_read_value (definitions, name, value, &len); -+ -+ if ((result == ASN1_SUCCESS) -+ && (!_asn1_strcmp (objectNode->value, value))) -+ { -+ -+ p2 = p2->right; /* pointer to the structure to -+ use for expansion */ -+ while ((p2) && (p2->type & CONST_ASSIGN)) -+ p2 = p2->right; -+ -+ if (p2) -+ { -+ strcpy (name, definitions->name); -+ strcat (name, "."); -+ strcat (name, p2->name); -+ -+ result = asn1_create_element (definitions, name, &aux); -+ if (result == ASN1_SUCCESS) -+ { -+ _asn1_cpy_name (aux, octetNode); -+ len2 = -+ asn1_get_length_der (octetNode->value, -+ octetNode->value_len, &len3); -+ if (len2 < 0) -+ return ASN1_DER_ERROR; -+ -+ result = -+ asn1_der_decoding (&aux, octetNode->value + len3, -+ len2, errorDescription); -+ if (result == ASN1_SUCCESS) -+ { -+ -+ _asn1_set_right (aux, octetNode->right); -+ _asn1_set_right (octetNode, aux); -+ -+ result = asn1_delete_structure (&octetNode); -+ if (result == ASN1_SUCCESS) -+ { -+ aux = NULL; -+ break; -+ } -+ else -+ { /* error with asn1_delete_structure */ -+ asn1_delete_structure (&aux); -+ retCode = result; -+ break; -+ } -+ } -+ else -+ { /* error with asn1_der_decoding */ -+ retCode = result; -+ break; -+ } -+ } -+ else -+ { /* error with asn1_create_element */ -+ retCode = result; -+ break; -+ } -+ } -+ else -+ { /* error with the pointer to the structure to exapand */ -+ retCode = ASN1_VALUE_NOT_VALID; -+ break; -+ } -+ } -+ } -+ -+ p2 = p2->right; -+ -+ } -+ -+ if (!p2) -+ retCode = ASN1_VALUE_NOT_VALID; -+ -+ return retCode; -+} -+ -+/*- -+ * _asn1_decode_simple_der: -+ * @etype: The type of the string to be encoded (ASN1_ETYPE_) -+ * @der: the encoded string -+ * @_der_len: the bytes of the encoded string -+ * @str: a pointer to the data -+ * @str_len: the length of the data -+ * @dflags: DECODE_FLAG_* -+ * -+ * Decodes a simple DER encoded type (e.g. a string, which is not constructed). -+ * The output is a pointer inside the @der. -+ * -+ * Returns: %ASN1_SUCCESS if successful or an error value. -+ -*/ -+static int -+_asn1_decode_simple_der (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, const unsigned char **str, -+ unsigned int *str_len, unsigned dflags) -+{ -+ int tag_len, len_len; -+ const unsigned char *p; -+ int der_len = _der_len; -+ unsigned char class; -+ unsigned long tag; -+ long ret; -+ -+ if (der == NULL || der_len == 0) -+ return ASN1_VALUE_NOT_VALID; -+ -+ if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING(etype) == 0) -+ return ASN1_VALUE_NOT_VALID; -+ -+ /* doesn't handle constructed classes */ -+ class = ETYPE_CLASS(etype); -+ if (class != ASN1_CLASS_UNIVERSAL) -+ return ASN1_VALUE_NOT_VALID; -+ -+ p = der; -+ -+ if (dflags & DECODE_FLAG_HAVE_TAG) -+ { -+ ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag); -+ if (ret != ASN1_SUCCESS) -+ return ret; -+ -+ if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype)) -+ { -+ warn(); -+ return ASN1_DER_ERROR; -+ } -+ -+ p += tag_len; -+ der_len -= tag_len; -+ if (der_len <= 0) -+ return ASN1_DER_ERROR; -+ } -+ -+ ret = asn1_get_length_der (p, der_len, &len_len); -+ if (ret < 0) -+ return ASN1_DER_ERROR; -+ -+ p += len_len; -+ der_len -= len_len; -+ if (der_len <= 0) -+ return ASN1_DER_ERROR; -+ -+ *str_len = ret; -+ *str = p; -+ -+ return ASN1_SUCCESS; -+} -+ -+/** -+ * asn1_decode_simple_der: -+ * @etype: The type of the string to be encoded (ASN1_ETYPE_) -+ * @der: the encoded string -+ * @_der_len: the bytes of the encoded string -+ * @str: a pointer to the data -+ * @str_len: the length of the data -+ * -+ * Decodes a simple DER encoded type (e.g. a string, which is not constructed). -+ * The output is a pointer inside the @der. -+ * -+ * Returns: %ASN1_SUCCESS if successful or an error value. -+ **/ -+int -+asn1_decode_simple_der (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, const unsigned char **str, -+ unsigned int *str_len) -+{ -+ return _asn1_decode_simple_der(etype, der, _der_len, str, str_len, DECODE_FLAG_HAVE_TAG); -+} -+ -+static int append(uint8_t **dst, unsigned *dst_size, const unsigned char *src, unsigned src_size) -+{ -+ if (src_size == 0) -+ return ASN1_SUCCESS; -+ -+ *dst = _asn1_realloc(*dst, *dst_size+src_size); -+ if (*dst == NULL) -+ return ASN1_MEM_ALLOC_ERROR; -+ memcpy(*dst + *dst_size, src, src_size); -+ *dst_size += src_size; -+ return ASN1_SUCCESS; -+} -+ -+/*- -+ * _asn1_decode_simple_ber: -+ * @etype: The type of the string to be encoded (ASN1_ETYPE_) -+ * @der: the encoded string -+ * @_der_len: the bytes of the encoded string -+ * @str: a pointer to the data -+ * @str_len: the length of the data -+ * @ber_len: the total length occupied by BER (may be %NULL) -+ * @have_tag: whether a DER tag is included -+ * -+ * Decodes a BER encoded type. The output is an allocated value -+ * of the data. This decodes BER STRINGS only. Other types are -+ * decoded as DER. -+ * -+ * Returns: %ASN1_SUCCESS if successful or an error value. -+ -*/ -+static int -+_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, unsigned char **str, -+ unsigned int *str_len, unsigned int *ber_len, -+ unsigned dflags) -+{ -+ int tag_len, len_len; -+ const unsigned char *p; -+ int der_len = _der_len; -+ uint8_t *total = NULL; -+ unsigned total_size = 0; -+ unsigned char class; -+ unsigned long tag; -+ unsigned char *out = NULL; -+ const unsigned char *cout = NULL; -+ unsigned out_len; -+ long result; -+ -+ if (ber_len) *ber_len = 0; -+ -+ if (der == NULL || der_len == 0) -+ { -+ warn(); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ -+ if (ETYPE_OK (etype) == 0) -+ { -+ warn(); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ -+ /* doesn't handle constructed + definite classes */ -+ class = ETYPE_CLASS (etype); -+ if (class != ASN1_CLASS_UNIVERSAL) -+ { -+ warn(); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ -+ p = der; -+ -+ if (dflags & DECODE_FLAG_HAVE_TAG) -+ { -+ result = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ return result; -+ } -+ -+ if (tag != ETYPE_TAG (etype)) -+ { -+ warn(); -+ return ASN1_DER_ERROR; -+ } -+ -+ p += tag_len; -+ -+ DECR_LEN(der_len, tag_len); -+ -+ if (ber_len) *ber_len += tag_len; -+ } -+ -+ /* indefinite constructed */ -+ if ((((dflags & DECODE_FLAG_CONSTRUCTED) || class == ASN1_CLASS_STRUCTURED) && ETYPE_IS_STRING(etype)) && -+ !(dflags & DECODE_FLAG_LEVEL3)) -+ { -+ if (der_len == 0) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ -+ if (der_len > 0 && p[0] == 0x80) /* indefinite */ -+ { -+ len_len = 1; -+ DECR_LEN(der_len, len_len); -+ p += len_len; -+ -+ if (ber_len) *ber_len += len_len; -+ -+ /* decode the available octet strings */ -+ do -+ { -+ unsigned tmp_len; -+ unsigned flags = DECODE_FLAG_HAVE_TAG; -+ -+ if (dflags & DECODE_FLAG_LEVEL1) -+ flags |= DECODE_FLAG_LEVEL2; -+ else if (dflags & DECODE_FLAG_LEVEL2) -+ flags |= DECODE_FLAG_LEVEL3; -+ else -+ flags |= DECODE_FLAG_LEVEL1; -+ -+ result = _asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len, -+ flags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ p += tmp_len; -+ DECR_LEN(der_len, tmp_len); -+ -+ if (ber_len) *ber_len += tmp_len; -+ -+ DECR_LEN(der_len, 2); /* we need the EOC */ -+ -+ result = append(&total, &total_size, out, out_len); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ free(out); -+ out = NULL; -+ -+ if (p[0] == 0 && p[1] == 0) /* EOC */ -+ { -+ if (ber_len) *ber_len += 2; -+ break; -+ } -+ -+ /* no EOC */ -+ der_len += 2; -+ -+ if (der_len == 2) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ } -+ while(1); -+ } -+ else /* constructed */ -+ { -+ long const_len; -+ -+ result = asn1_get_length_ber(p, der_len, &len_len); -+ if (result < 0) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ -+ DECR_LEN(der_len, len_len); -+ p += len_len; -+ -+ const_len = result; -+ -+ if (ber_len) *ber_len += len_len; -+ -+ /* decode the available octet strings */ -+ while(const_len > 0) -+ { -+ unsigned tmp_len; -+ unsigned flags = DECODE_FLAG_HAVE_TAG; -+ -+ if (dflags & DECODE_FLAG_LEVEL1) -+ flags |= DECODE_FLAG_LEVEL2; -+ else if (dflags & DECODE_FLAG_LEVEL2) -+ flags |= DECODE_FLAG_LEVEL3; -+ else -+ flags |= DECODE_FLAG_LEVEL1; -+ -+ result = _asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len, -+ flags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ p += tmp_len; -+ DECR_LEN(der_len, tmp_len); -+ DECR_LEN(const_len, tmp_len); -+ -+ if (ber_len) *ber_len += tmp_len; -+ -+ result = append(&total, &total_size, out, out_len); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ free(out); -+ out = NULL; -+ } -+ } -+ } -+ else if (class == ETYPE_CLASS(etype)) -+ { -+ if (ber_len) -+ { -+ result = asn1_get_length_der (p, der_len, &len_len); -+ if (result < 0) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ *ber_len += result + len_len; -+ } -+ -+ /* non-string values are decoded as DER */ -+ result = _asn1_decode_simple_der(etype, der, _der_len, &cout, &out_len, dflags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ result = append(&total, &total_size, cout, out_len); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ } -+ else -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ -+ *str = total; -+ *str_len = total_size; -+ -+ return ASN1_SUCCESS; -+cleanup: -+ free(out); -+ free(total); -+ return result; -+} -+ -+/** -+ * asn1_decode_simple_ber: -+ * @etype: The type of the string to be encoded (ASN1_ETYPE_) -+ * @der: the encoded string -+ * @_der_len: the bytes of the encoded string -+ * @str: a pointer to the data -+ * @str_len: the length of the data -+ * @ber_len: the total length occupied by BER (may be %NULL) -+ * -+ * Decodes a BER encoded type. The output is an allocated value -+ * of the data. This decodes BER STRINGS only. Other types are -+ * decoded as DER. -+ * -+ * Returns: %ASN1_SUCCESS if successful or an error value. -+ **/ -+int -+asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, unsigned char **str, -+ unsigned int *str_len, unsigned int *ber_len) -+{ -+ return _asn1_decode_simple_ber(etype, der, _der_len, str, str_len, ber_len, DECODE_FLAG_HAVE_TAG); -+} -diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c -new file mode 100644 -index 00000000000..997eb2725dc ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/element.c -@@ -0,0 +1,1111 @@ -+/* -+ * Copyright (C) 2000-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+/*****************************************************/ -+/* File: element.c */ -+/* Description: Functions with the read and write */ -+/* functions. */ -+/*****************************************************/ -+ -+ -+#include -+#include "parser_aux.h" -+#include -+#include "structure.h" -+#include "c-ctype.h" -+#include "element.h" -+ -+void -+_asn1_hierarchical_name (asn1_node_const node, char *name, int name_size) -+{ -+ asn1_node_const p; -+ char tmp_name[64]; -+ -+ p = node; -+ -+ name[0] = 0; -+ -+ while (p != NULL) -+ { -+ if (p->name[0] != 0) -+ { -+ _asn1_str_cpy (tmp_name, sizeof (tmp_name), name), -+ _asn1_str_cpy (name, name_size, p->name); -+ _asn1_str_cat (name, name_size, "."); -+ _asn1_str_cat (name, name_size, tmp_name); -+ } -+ p = _asn1_find_up (p); -+ } -+ -+ if (name[0] == 0) -+ _asn1_str_cpy (name, name_size, "ROOT"); -+} -+ -+ -+/******************************************************************/ -+/* Function : _asn1_convert_integer */ -+/* Description: converts an integer from a null terminated string */ -+/* to der decoding. The convertion from a null */ -+/* terminated string to an integer is made with */ -+/* the 'strtol' function. */ -+/* Parameters: */ -+/* value: null terminated string to convert. */ -+/* value_out: convertion result (memory must be already */ -+/* allocated). */ -+/* value_out_size: number of bytes of value_out. */ -+/* len: number of significant byte of value_out. */ -+/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */ -+/******************************************************************/ -+int -+_asn1_convert_integer (const unsigned char *value, unsigned char *value_out, -+ int value_out_size, int *len) -+{ -+ char negative; -+ unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; -+ long valtmp; -+ int k, k2; -+ -+ valtmp = _asn1_strtol (value, NULL, 10); -+ -+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) -+ { -+ val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF; -+ } -+ -+ if (val[0] & 0x80) -+ negative = 1; -+ else -+ negative = 0; -+ -+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++) -+ { -+ if (negative && (val[k] != 0xFF)) -+ break; -+ else if (!negative && val[k]) -+ break; -+ } -+ -+ if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80))) -+ k--; -+ -+ *len = SIZEOF_UNSIGNED_LONG_INT - k; -+ -+ if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size) -+ /* VALUE_OUT is too short to contain the value conversion */ -+ return ASN1_MEM_ERROR; -+ -+ if (value_out != NULL) -+ { -+ for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) -+ value_out[k2 - k] = val[k2]; -+ } -+ -+#if 0 -+ printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len); -+ for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) -+ printf (", vOut[%d]=%d", k, value_out[k]); -+ printf ("\n"); -+#endif -+ -+ return ASN1_SUCCESS; -+} -+ -+/* Appends a new element into the sequence (or set) defined by this -+ * node. The new element will have a name of '?number', where number -+ * is a monotonically increased serial number. -+ * -+ * The last element in the list may be provided in @pcache, to avoid -+ * traversing the list, an expensive operation in long lists. -+ * -+ * On success it returns in @pcache the added element (which is the -+ * tail in the list of added elements). -+ */ -+int -+_asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache) -+{ -+ asn1_node p, p2; -+ char temp[LTOSTR_MAX_SIZE]; -+ long n; -+ -+ if (!node || !(node->down)) -+ return ASN1_GENERIC_ERROR; -+ -+ p = node->down; -+ while ((type_field (p->type) == ASN1_ETYPE_TAG) -+ || (type_field (p->type) == ASN1_ETYPE_SIZE)) -+ p = p->right; -+ -+ p2 = _asn1_copy_structure3 (p); -+ if (p2 == NULL) -+ return ASN1_GENERIC_ERROR; -+ -+ if (pcache == NULL || pcache->tail == NULL || pcache->head != node) -+ { -+ while (p->right) -+ { -+ p = p->right; -+ } -+ } -+ else -+ { -+ p = pcache->tail; -+ } -+ -+ _asn1_set_right (p, p2); -+ if (pcache) -+ { -+ pcache->head = node; -+ pcache->tail = p2; -+ } -+ -+ if (p->name[0] == 0) -+ _asn1_str_cpy (temp, sizeof (temp), "?1"); -+ else -+ { -+ n = strtol (p->name + 1, NULL, 0); -+ n++; -+ temp[0] = '?'; -+ _asn1_ltostr (n, temp + 1); -+ } -+ _asn1_set_name (p2, temp); -+ /* p2->type |= CONST_OPTION; */ -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/** -+ * asn1_write_value: -+ * @node_root: pointer to a structure -+ * @name: the name of the element inside the structure that you want to set. -+ * @ivalue: vector used to specify the value to set. If len is >0, -+ * VALUE must be a two's complement form integer. if len=0 *VALUE -+ * must be a null terminated string with an integer value. -+ * @len: number of bytes of *value to use to set the value: -+ * value[0]..value[len-1] or 0 if value is a null terminated string -+ * -+ * Set the value of one element inside a structure. -+ * -+ * If an element is OPTIONAL and you want to delete it, you must use -+ * the value=NULL and len=0. Using "pkix.asn": -+ * -+ * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID", -+ * NULL, 0); -+ * -+ * Description for each type: -+ * -+ * INTEGER: VALUE must contain a two's complement form integer. -+ * -+ * value[0]=0xFF , len=1 -> integer=-1. -+ * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1. -+ * value[0]=0x01 , len=1 -> integer= 1. -+ * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1. -+ * value="123" , len=0 -> integer= 123. -+ * -+ * ENUMERATED: As INTEGER (but only with not negative numbers). -+ * -+ * BOOLEAN: VALUE must be the null terminated string "TRUE" or -+ * "FALSE" and LEN != 0. -+ * -+ * value="TRUE" , len=1 -> boolean=TRUE. -+ * value="FALSE" , len=1 -> boolean=FALSE. -+ * -+ * OBJECT IDENTIFIER: VALUE must be a null terminated string with -+ * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0. -+ * -+ * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha. -+ * -+ * UTCTime: VALUE must be a null terminated string in one of these -+ * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ", -+ * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'", -+ * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0. -+ * -+ * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 -+ * at 12h 00m Greenwich Mean Time -+ * -+ * GeneralizedTime: VALUE must be in one of this format: -+ * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ", -+ * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'", -+ * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s -+ * indicates the seconds with any precision like "10.1" or "01.02". -+ * LEN != 0 -+ * -+ * value="2001010112001.12-0700" , len=1 -> time=Jannuary -+ * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time -+ * -+ * OCTET STRING: VALUE contains the octet string and LEN is the -+ * number of octets. -+ * -+ * value="$\backslash$x01$\backslash$x02$\backslash$x03" , -+ * len=3 -> three bytes octet string -+ * -+ * GeneralString: VALUE contains the generalstring and LEN is the -+ * number of octets. -+ * -+ * value="$\backslash$x01$\backslash$x02$\backslash$x03" , -+ * len=3 -> three bytes generalstring -+ * -+ * BIT STRING: VALUE contains the bit string organized by bytes and -+ * LEN is the number of bits. -+ * -+ * value="$\backslash$xCF" , len=6 -> bit string="110011" (six -+ * bits) -+ * -+ * CHOICE: if NAME indicates a choice type, VALUE must specify one of -+ * the alternatives with a null terminated string. LEN != 0. Using -+ * "pkix.asn"\: -+ * -+ * result=asn1_write_value(cert, -+ * "certificate1.tbsCertificate.subject", "rdnSequence", -+ * 1); -+ * -+ * ANY: VALUE indicates the der encoding of a structure. LEN != 0. -+ * -+ * SEQUENCE OF: VALUE must be the null terminated string "NEW" and -+ * LEN != 0. With this instruction another element is appended in -+ * the sequence. The name of this element will be "?1" if it's the -+ * first one, "?2" for the second and so on. -+ * -+ * Using "pkix.asn"\: -+ * -+ * result=asn1_write_value(cert, -+ * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1); -+ * -+ * SET OF: the same as SEQUENCE OF. Using "pkix.asn": -+ * -+ * result=asn1_write_value(cert, -+ * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1); -+ * -+ * Returns: %ASN1_SUCCESS if the value was set, -+ * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and -+ * %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format. -+ **/ -+int -+asn1_write_value (asn1_node node_root, const char *name, -+ const void *ivalue, int len) -+{ -+ asn1_node node, p, p2; -+ unsigned char *temp, *value_temp = NULL, *default_temp = NULL; -+ int len2, k, k2, negative; -+ size_t i; -+ const unsigned char *value = ivalue; -+ unsigned int type; -+ -+ node = asn1_find_node (node_root, name); -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0)) -+ { -+ asn1_delete_structure (&node); -+ return ASN1_SUCCESS; -+ } -+ -+ type = type_field (node->type); -+ -+ if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0)) -+ { -+ p = node->down; -+ while ((type_field (p->type) == ASN1_ETYPE_TAG) -+ || (type_field (p->type) == ASN1_ETYPE_SIZE)) -+ p = p->right; -+ -+ while (p->right) -+ asn1_delete_structure (&p->right); -+ -+ return ASN1_SUCCESS; -+ } -+ -+ /* Don't allow element deletion for other types */ -+ if (value == NULL) -+ { -+ return ASN1_VALUE_NOT_VALID; -+ } -+ -+ switch (type) -+ { -+ case ASN1_ETYPE_BOOLEAN: -+ if (!_asn1_strcmp (value, "TRUE")) -+ { -+ if (node->type & CONST_DEFAULT) -+ { -+ p = node->down; -+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT) -+ p = p->right; -+ if (p->type & CONST_TRUE) -+ _asn1_set_value (node, NULL, 0); -+ else -+ _asn1_set_value (node, "T", 1); -+ } -+ else -+ _asn1_set_value (node, "T", 1); -+ } -+ else if (!_asn1_strcmp (value, "FALSE")) -+ { -+ if (node->type & CONST_DEFAULT) -+ { -+ p = node->down; -+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT) -+ p = p->right; -+ if (p->type & CONST_FALSE) -+ _asn1_set_value (node, NULL, 0); -+ else -+ _asn1_set_value (node, "F", 1); -+ } -+ else -+ _asn1_set_value (node, "F", 1); -+ } -+ else -+ return ASN1_VALUE_NOT_VALID; -+ break; -+ case ASN1_ETYPE_INTEGER: -+ case ASN1_ETYPE_ENUMERATED: -+ if (len == 0) -+ { -+ if ((c_isdigit (value[0])) || (value[0] == '-')) -+ { -+ value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); -+ if (value_temp == NULL) -+ return ASN1_MEM_ALLOC_ERROR; -+ -+ _asn1_convert_integer (value, value_temp, -+ SIZEOF_UNSIGNED_LONG_INT, &len); -+ } -+ else -+ { /* is an identifier like v1 */ -+ if (!(node->type & CONST_LIST)) -+ return ASN1_VALUE_NOT_VALID; -+ p = node->down; -+ while (p) -+ { -+ if (type_field (p->type) == ASN1_ETYPE_CONSTANT) -+ { -+ if (!_asn1_strcmp (p->name, value)) -+ { -+ value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); -+ if (value_temp == NULL) -+ return ASN1_MEM_ALLOC_ERROR; -+ -+ _asn1_convert_integer (p->value, -+ value_temp, -+ SIZEOF_UNSIGNED_LONG_INT, -+ &len); -+ break; -+ } -+ } -+ p = p->right; -+ } -+ if (p == NULL) -+ return ASN1_VALUE_NOT_VALID; -+ } -+ } -+ else -+ { /* len != 0 */ -+ value_temp = malloc (len); -+ if (value_temp == NULL) -+ return ASN1_MEM_ALLOC_ERROR; -+ memcpy (value_temp, value, len); -+ } -+ -+ if (value_temp[0] & 0x80) -+ negative = 1; -+ else -+ negative = 0; -+ -+ if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED)) -+ { -+ free (value_temp); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ -+ for (k = 0; k < len - 1; k++) -+ if (negative && (value_temp[k] != 0xFF)) -+ break; -+ else if (!negative && value_temp[k]) -+ break; -+ -+ if ((negative && !(value_temp[k] & 0x80)) || -+ (!negative && (value_temp[k] & 0x80))) -+ k--; -+ -+ _asn1_set_value_lv (node, value_temp + k, len - k); -+ -+ if (node->type & CONST_DEFAULT) -+ { -+ p = node->down; -+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT) -+ p = p->right; -+ if ((c_isdigit (p->value[0])) || (p->value[0] == '-')) -+ { -+ default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); -+ if (default_temp == NULL) -+ { -+ free (value_temp); -+ return ASN1_MEM_ALLOC_ERROR; -+ } -+ -+ _asn1_convert_integer (p->value, default_temp, -+ SIZEOF_UNSIGNED_LONG_INT, &len2); -+ } -+ else -+ { /* is an identifier like v1 */ -+ if (!(node->type & CONST_LIST)) -+ { -+ free (value_temp); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ p2 = node->down; -+ while (p2) -+ { -+ if (type_field (p2->type) == ASN1_ETYPE_CONSTANT) -+ { -+ if (!_asn1_strcmp (p2->name, p->value)) -+ { -+ default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); -+ if (default_temp == NULL) -+ { -+ free (value_temp); -+ return ASN1_MEM_ALLOC_ERROR; -+ } -+ -+ _asn1_convert_integer (p2->value, -+ default_temp, -+ SIZEOF_UNSIGNED_LONG_INT, -+ &len2); -+ break; -+ } -+ } -+ p2 = p2->right; -+ } -+ if (p2 == NULL) -+ { -+ free (value_temp); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ } -+ -+ -+ if ((len - k) == len2) -+ { -+ for (k2 = 0; k2 < len2; k2++) -+ if (value_temp[k + k2] != default_temp[k2]) -+ { -+ break; -+ } -+ if (k2 == len2) -+ _asn1_set_value (node, NULL, 0); -+ } -+ free (default_temp); -+ } -+ free (value_temp); -+ break; -+ case ASN1_ETYPE_OBJECT_ID: -+ for (i = 0; i < _asn1_strlen (value); i++) -+ if ((!c_isdigit (value[i])) && (value[i] != '.') && (value[i] != '+')) -+ return ASN1_VALUE_NOT_VALID; -+ if (node->type & CONST_DEFAULT) -+ { -+ p = node->down; -+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT) -+ p = p->right; -+ if (!_asn1_strcmp (value, p->value)) -+ { -+ _asn1_set_value (node, NULL, 0); -+ break; -+ } -+ } -+ _asn1_set_value (node, value, _asn1_strlen (value) + 1); -+ break; -+ case ASN1_ETYPE_UTC_TIME: -+ { -+ len = _asn1_strlen (value); -+ if (len < 11) -+ return ASN1_VALUE_NOT_VALID; -+ for (k = 0; k < 10; k++) -+ if (!c_isdigit (value[k])) -+ return ASN1_VALUE_NOT_VALID; -+ switch (len) -+ { -+ case 11: -+ if (value[10] != 'Z') -+ return ASN1_VALUE_NOT_VALID; -+ break; -+ case 13: -+ if ((!c_isdigit (value[10])) || (!c_isdigit (value[11])) || -+ (value[12] != 'Z')) -+ return ASN1_VALUE_NOT_VALID; -+ break; -+ case 15: -+ if ((value[10] != '+') && (value[10] != '-')) -+ return ASN1_VALUE_NOT_VALID; -+ for (k = 11; k < 15; k++) -+ if (!c_isdigit (value[k])) -+ return ASN1_VALUE_NOT_VALID; -+ break; -+ case 17: -+ if ((!c_isdigit (value[10])) || (!c_isdigit (value[11]))) -+ return ASN1_VALUE_NOT_VALID; -+ if ((value[12] != '+') && (value[12] != '-')) -+ return ASN1_VALUE_NOT_VALID; -+ for (k = 13; k < 17; k++) -+ if (!c_isdigit (value[k])) -+ return ASN1_VALUE_NOT_VALID; -+ break; -+ default: -+ return ASN1_VALUE_NOT_FOUND; -+ } -+ _asn1_set_value (node, value, len); -+ } -+ break; -+ case ASN1_ETYPE_GENERALIZED_TIME: -+ len = _asn1_strlen (value); -+ _asn1_set_value (node, value, len); -+ break; -+ case ASN1_ETYPE_OCTET_STRING: -+ case ASN1_ETYPE_GENERALSTRING: -+ case ASN1_ETYPE_NUMERIC_STRING: -+ case ASN1_ETYPE_IA5_STRING: -+ case ASN1_ETYPE_TELETEX_STRING: -+ case ASN1_ETYPE_PRINTABLE_STRING: -+ case ASN1_ETYPE_UNIVERSAL_STRING: -+ case ASN1_ETYPE_BMP_STRING: -+ case ASN1_ETYPE_UTF8_STRING: -+ case ASN1_ETYPE_VISIBLE_STRING: -+ if (len == 0) -+ len = _asn1_strlen (value); -+ _asn1_set_value_lv (node, value, len); -+ break; -+ case ASN1_ETYPE_BIT_STRING: -+ if (len == 0) -+ len = _asn1_strlen (value); -+ asn1_length_der ((len >> 3) + 2, NULL, &len2); -+ temp = malloc ((len >> 3) + 2 + len2); -+ if (temp == NULL) -+ return ASN1_MEM_ALLOC_ERROR; -+ -+ asn1_bit_der (value, len, temp, &len2); -+ _asn1_set_value_m (node, temp, len2); -+ temp = NULL; -+ break; -+ case ASN1_ETYPE_CHOICE: -+ p = node->down; -+ while (p) -+ { -+ if (!_asn1_strcmp (p->name, value)) -+ { -+ p2 = node->down; -+ while (p2) -+ { -+ if (p2 != p) -+ { -+ asn1_delete_structure (&p2); -+ p2 = node->down; -+ } -+ else -+ p2 = p2->right; -+ } -+ break; -+ } -+ p = p->right; -+ } -+ if (!p) -+ return ASN1_ELEMENT_NOT_FOUND; -+ break; -+ case ASN1_ETYPE_ANY: -+ _asn1_set_value_lv (node, value, len); -+ break; -+ case ASN1_ETYPE_SEQUENCE_OF: -+ case ASN1_ETYPE_SET_OF: -+ if (_asn1_strcmp (value, "NEW")) -+ return ASN1_VALUE_NOT_VALID; -+ _asn1_append_sequence_set (node, NULL); -+ break; -+ default: -+ return ASN1_ELEMENT_NOT_FOUND; -+ break; -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+#define PUT_VALUE( ptr, ptr_size, data, data_size) \ -+ *len = data_size; \ -+ if (ptr_size < data_size) { \ -+ return ASN1_MEM_ERROR; \ -+ } else { \ -+ if (ptr && data_size > 0) \ -+ memcpy (ptr, data, data_size); \ -+ } -+ -+#define PUT_STR_VALUE( ptr, ptr_size, data) \ -+ *len = _asn1_strlen (data) + 1; \ -+ if (ptr_size < *len) { \ -+ return ASN1_MEM_ERROR; \ -+ } else { \ -+ /* this strcpy is checked */ \ -+ if (ptr) { \ -+ _asn1_strcpy (ptr, data); \ -+ } \ -+ } -+ -+#define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \ -+ *len = data_size + 1; \ -+ if (ptr_size < *len) { \ -+ return ASN1_MEM_ERROR; \ -+ } else { \ -+ /* this strcpy is checked */ \ -+ if (ptr) { \ -+ if (data_size > 0) \ -+ memcpy (ptr, data, data_size); \ -+ ptr[data_size] = 0; \ -+ } \ -+ } -+ -+#define ADD_STR_VALUE( ptr, ptr_size, data) \ -+ *len += _asn1_strlen(data); \ -+ if (ptr_size < (int) *len) { \ -+ (*len)++; \ -+ return ASN1_MEM_ERROR; \ -+ } else { \ -+ /* this strcat is checked */ \ -+ if (ptr) _asn1_strcat (ptr, data); \ -+ } -+ -+/** -+ * asn1_read_value: -+ * @root: pointer to a structure. -+ * @name: the name of the element inside a structure that you want to read. -+ * @ivalue: vector that will contain the element's content, must be a -+ * pointer to memory cells already allocated (may be %NULL). -+ * @len: number of bytes of *value: value[0]..value[len-1]. Initialy -+ * holds the sizeof value. -+ * -+ * Returns the value of one element inside a structure. -+ * If an element is OPTIONAL and this returns -+ * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present -+ * in the der encoding that created the structure. The first element -+ * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and -+ * so on. If the @root provided is a node to specific sequence element, -+ * then the keyword "?CURRENT" is also acceptable and indicates the -+ * current sequence element of this node. -+ * -+ * Note that there can be valid values with length zero. In these case -+ * this function will succeed and @len will be zero. -+ * -+ * INTEGER: VALUE will contain a two's complement form integer. -+ * -+ * integer=-1 -> value[0]=0xFF , len=1. -+ * integer=1 -> value[0]=0x01 , len=1. -+ * -+ * ENUMERATED: As INTEGER (but only with not negative numbers). -+ * -+ * BOOLEAN: VALUE will be the null terminated string "TRUE" or -+ * "FALSE" and LEN=5 or LEN=6. -+ * -+ * OBJECT IDENTIFIER: VALUE will be a null terminated string with -+ * each number separated by a dot (i.e. "1.2.3.543.1"). -+ * -+ * LEN = strlen(VALUE)+1 -+ * -+ * UTCTime: VALUE will be a null terminated string in one of these -+ * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'". -+ * LEN=strlen(VALUE)+1. -+ * -+ * GeneralizedTime: VALUE will be a null terminated string in the -+ * same format used to set the value. -+ * -+ * OCTET STRING: VALUE will contain the octet string and LEN will be -+ * the number of octets. -+ * -+ * GeneralString: VALUE will contain the generalstring and LEN will -+ * be the number of octets. -+ * -+ * BIT STRING: VALUE will contain the bit string organized by bytes -+ * and LEN will be the number of bits. -+ * -+ * CHOICE: If NAME indicates a choice type, VALUE will specify the -+ * alternative selected. -+ * -+ * ANY: If NAME indicates an any type, VALUE will indicate the DER -+ * encoding of the structure actually used. -+ * -+ * Returns: %ASN1_SUCCESS if value is returned, -+ * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, -+ * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element -+ * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough -+ * to store the result, and in this case @len will contain the number of -+ * bytes needed. On the occasion that the stored data are of zero-length -+ * this function may return %ASN1_SUCCESS even if the provided @len is zero. -+ **/ -+int -+asn1_read_value (asn1_node_const root, const char *name, void *ivalue, int *len) -+{ -+ return asn1_read_value_type (root, name, ivalue, len, NULL); -+} -+ -+/** -+ * asn1_read_value_type: -+ * @root: pointer to a structure. -+ * @name: the name of the element inside a structure that you want to read. -+ * @ivalue: vector that will contain the element's content, must be a -+ * pointer to memory cells already allocated (may be %NULL). -+ * @len: number of bytes of *value: value[0]..value[len-1]. Initialy -+ * holds the sizeof value. -+ * @etype: The type of the value read (ASN1_ETYPE) -+ * -+ * Returns the type and value of one element inside a structure. -+ * If an element is OPTIONAL and this returns -+ * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present -+ * in the der encoding that created the structure. The first element -+ * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and -+ * so on. If the @root provided is a node to specific sequence element, -+ * then the keyword "?CURRENT" is also acceptable and indicates the -+ * current sequence element of this node. -+ * -+ * Note that there can be valid values with length zero. In these case -+ * this function will succeed and @len will be zero. -+ * -+ * -+ * INTEGER: VALUE will contain a two's complement form integer. -+ * -+ * integer=-1 -> value[0]=0xFF , len=1. -+ * integer=1 -> value[0]=0x01 , len=1. -+ * -+ * ENUMERATED: As INTEGER (but only with not negative numbers). -+ * -+ * BOOLEAN: VALUE will be the null terminated string "TRUE" or -+ * "FALSE" and LEN=5 or LEN=6. -+ * -+ * OBJECT IDENTIFIER: VALUE will be a null terminated string with -+ * each number separated by a dot (i.e. "1.2.3.543.1"). -+ * -+ * LEN = strlen(VALUE)+1 -+ * -+ * UTCTime: VALUE will be a null terminated string in one of these -+ * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'". -+ * LEN=strlen(VALUE)+1. -+ * -+ * GeneralizedTime: VALUE will be a null terminated string in the -+ * same format used to set the value. -+ * -+ * OCTET STRING: VALUE will contain the octet string and LEN will be -+ * the number of octets. -+ * -+ * GeneralString: VALUE will contain the generalstring and LEN will -+ * be the number of octets. -+ * -+ * BIT STRING: VALUE will contain the bit string organized by bytes -+ * and LEN will be the number of bits. -+ * -+ * CHOICE: If NAME indicates a choice type, VALUE will specify the -+ * alternative selected. -+ * -+ * ANY: If NAME indicates an any type, VALUE will indicate the DER -+ * encoding of the structure actually used. -+ * -+ * Returns: %ASN1_SUCCESS if value is returned, -+ * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, -+ * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element -+ * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough -+ * to store the result, and in this case @len will contain the number of -+ * bytes needed. On the occasion that the stored data are of zero-length -+ * this function may return %ASN1_SUCCESS even if the provided @len is zero. -+ **/ -+int -+asn1_read_value_type (asn1_node_const root, const char *name, void *ivalue, -+ int *len, unsigned int *etype) -+{ -+ asn1_node_const node, p, p2; -+ int len2, len3, result; -+ int value_size = *len; -+ unsigned char *value = ivalue; -+ unsigned type; -+ -+ node = asn1_find_node (root, name); -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ type = type_field (node->type); -+ -+ if ((type != ASN1_ETYPE_NULL) && -+ (type != ASN1_ETYPE_CHOICE) && -+ !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) && -+ (node->value == NULL)) -+ return ASN1_VALUE_NOT_FOUND; -+ -+ if (etype) -+ *etype = type; -+ switch (type) -+ { -+ case ASN1_ETYPE_NULL: -+ PUT_STR_VALUE (value, value_size, "NULL"); -+ break; -+ case ASN1_ETYPE_BOOLEAN: -+ if ((node->type & CONST_DEFAULT) && (node->value == NULL)) -+ { -+ p = node->down; -+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT) -+ p = p->right; -+ if (p->type & CONST_TRUE) -+ { -+ PUT_STR_VALUE (value, value_size, "TRUE"); -+ } -+ else -+ { -+ PUT_STR_VALUE (value, value_size, "FALSE"); -+ } -+ } -+ else if (node->value[0] == 'T') -+ { -+ PUT_STR_VALUE (value, value_size, "TRUE"); -+ } -+ else -+ { -+ PUT_STR_VALUE (value, value_size, "FALSE"); -+ } -+ break; -+ case ASN1_ETYPE_INTEGER: -+ case ASN1_ETYPE_ENUMERATED: -+ if ((node->type & CONST_DEFAULT) && (node->value == NULL)) -+ { -+ p = node->down; -+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT) -+ p = p->right; -+ if ((c_isdigit (p->value[0])) || (p->value[0] == '-') -+ || (p->value[0] == '+')) -+ { -+ result = _asn1_convert_integer -+ (p->value, value, value_size, len); -+ if (result != ASN1_SUCCESS) -+ return result; -+ } -+ else -+ { /* is an identifier like v1 */ -+ p2 = node->down; -+ while (p2) -+ { -+ if (type_field (p2->type) == ASN1_ETYPE_CONSTANT) -+ { -+ if (!_asn1_strcmp (p2->name, p->value)) -+ { -+ result = _asn1_convert_integer -+ (p2->value, value, value_size, -+ len); -+ if (result != ASN1_SUCCESS) -+ return result; -+ break; -+ } -+ } -+ p2 = p2->right; -+ } -+ } -+ } -+ else -+ { -+ len2 = -1; -+ result = asn1_get_octet_der -+ (node->value, node->value_len, &len2, value, value_size, -+ len); -+ if (result != ASN1_SUCCESS) -+ return result; -+ } -+ break; -+ case ASN1_ETYPE_OBJECT_ID: -+ if (node->type & CONST_ASSIGN) -+ { -+ *len = 0; -+ if (value) -+ value[0] = 0; -+ p = node->down; -+ while (p) -+ { -+ if (type_field (p->type) == ASN1_ETYPE_CONSTANT) -+ { -+ ADD_STR_VALUE (value, value_size, p->value); -+ if (p->right) -+ { -+ ADD_STR_VALUE (value, value_size, "."); -+ } -+ } -+ p = p->right; -+ } -+ (*len)++; -+ } -+ else if ((node->type & CONST_DEFAULT) && (node->value == NULL)) -+ { -+ p = node->down; -+ while (type_field (p->type) != ASN1_ETYPE_DEFAULT) -+ p = p->right; -+ PUT_STR_VALUE (value, value_size, p->value); -+ } -+ else -+ { -+ PUT_STR_VALUE (value, value_size, node->value); -+ } -+ break; -+ case ASN1_ETYPE_GENERALIZED_TIME: -+ case ASN1_ETYPE_UTC_TIME: -+ PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len); -+ break; -+ case ASN1_ETYPE_OCTET_STRING: -+ case ASN1_ETYPE_GENERALSTRING: -+ case ASN1_ETYPE_NUMERIC_STRING: -+ case ASN1_ETYPE_IA5_STRING: -+ case ASN1_ETYPE_TELETEX_STRING: -+ case ASN1_ETYPE_PRINTABLE_STRING: -+ case ASN1_ETYPE_UNIVERSAL_STRING: -+ case ASN1_ETYPE_BMP_STRING: -+ case ASN1_ETYPE_UTF8_STRING: -+ case ASN1_ETYPE_VISIBLE_STRING: -+ len2 = -1; -+ result = asn1_get_octet_der -+ (node->value, node->value_len, &len2, value, value_size, -+ len); -+ if (result != ASN1_SUCCESS) -+ return result; -+ break; -+ case ASN1_ETYPE_BIT_STRING: -+ len2 = -1; -+ result = asn1_get_bit_der -+ (node->value, node->value_len, &len2, value, value_size, -+ len); -+ if (result != ASN1_SUCCESS) -+ return result; -+ break; -+ case ASN1_ETYPE_CHOICE: -+ PUT_STR_VALUE (value, value_size, node->down->name); -+ break; -+ case ASN1_ETYPE_ANY: -+ len3 = -1; -+ len2 = asn1_get_length_der (node->value, node->value_len, &len3); -+ if (len2 < 0) -+ return ASN1_DER_ERROR; -+ PUT_VALUE (value, value_size, node->value + len3, len2); -+ break; -+ default: -+ return ASN1_ELEMENT_NOT_FOUND; -+ break; -+ } -+ return ASN1_SUCCESS; -+} -+ -+ -+/** -+ * asn1_read_tag: -+ * @root: pointer to a structure -+ * @name: the name of the element inside a structure. -+ * @tagValue: variable that will contain the TAG value. -+ * @classValue: variable that will specify the TAG type. -+ * -+ * Returns the TAG and the CLASS of one element inside a structure. -+ * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION, -+ * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or -+ * %ASN1_CLASS_CONTEXT_SPECIFIC. -+ * -+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if -+ * @name is not a valid element. -+ **/ -+int -+asn1_read_tag (asn1_node_const root, const char *name, int *tagValue, -+ int *classValue) -+{ -+ asn1_node node, p, pTag; -+ -+ node = asn1_find_node (root, name); -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = node->down; -+ -+ /* pTag will points to the IMPLICIT TAG */ -+ pTag = NULL; -+ if (node->type & CONST_TAG) -+ { -+ while (p) -+ { -+ if (type_field (p->type) == ASN1_ETYPE_TAG) -+ { -+ if ((p->type & CONST_IMPLICIT) && (pTag == NULL)) -+ pTag = p; -+ else if (p->type & CONST_EXPLICIT) -+ pTag = NULL; -+ } -+ p = p->right; -+ } -+ } -+ -+ if (pTag) -+ { -+ *tagValue = _asn1_strtoul (pTag->value, NULL, 10); -+ -+ if (pTag->type & CONST_APPLICATION) -+ *classValue = ASN1_CLASS_APPLICATION; -+ else if (pTag->type & CONST_UNIVERSAL) -+ *classValue = ASN1_CLASS_UNIVERSAL; -+ else if (pTag->type & CONST_PRIVATE) -+ *classValue = ASN1_CLASS_PRIVATE; -+ else -+ *classValue = ASN1_CLASS_CONTEXT_SPECIFIC; -+ } -+ else -+ { -+ unsigned type = type_field (node->type); -+ *classValue = ASN1_CLASS_UNIVERSAL; -+ -+ switch (type) -+ { -+ CASE_HANDLED_ETYPES: -+ *tagValue = _asn1_tags[type].tag; -+ break; -+ case ASN1_ETYPE_TAG: -+ case ASN1_ETYPE_CHOICE: -+ case ASN1_ETYPE_ANY: -+ *tagValue = -1; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+/** -+ * asn1_read_node_value: -+ * @node: pointer to a node. -+ * @data: a point to a asn1_data_node_st -+ * -+ * Returns the value a data node inside a asn1_node structure. -+ * The data returned should be handled as constant values. -+ * -+ * Returns: %ASN1_SUCCESS if the node exists. -+ **/ -+int -+asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data) -+{ -+ data->name = node->name; -+ data->value = node->value; -+ data->value_len = node->value_len; -+ data->type = type_field (node->type); -+ -+ return ASN1_SUCCESS; -+} -diff --git a/grub-core/lib/libtasn1/lib/errors.c b/grub-core/lib/libtasn1/lib/errors.c -new file mode 100644 -index 00000000000..cee74daf795 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/errors.c -@@ -0,0 +1,100 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#include -+#ifdef STDC_HEADERS -+#include -+#endif -+ -+#define LIBTASN1_ERROR_ENTRY(name) { #name, name } -+ -+struct libtasn1_error_entry -+{ -+ const char *name; -+ int number; -+}; -+typedef struct libtasn1_error_entry libtasn1_error_entry; -+ -+static const libtasn1_error_entry error_algorithms[] = { -+ LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS), -+ LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND), -+ LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND), -+ LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND), -+ LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR), -+ LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND), -+ LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR), -+ LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID), -+ LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR), -+ LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT), -+ LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY), -+ LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR), -+ LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR), -+ LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR), -+ LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW), -+ LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG), -+ LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR), -+ LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY), -+ LIBTASN1_ERROR_ENTRY (ASN1_TIME_ENCODING_ERROR), -+ LIBTASN1_ERROR_ENTRY (ASN1_RECURSION), -+ {0, 0} -+}; -+ -+/** -+ * asn1_perror: -+ * @error: is an error returned by a libtasn1 function. -+ * -+ * Prints a string to stderr with a description of an error. This -+ * function is like perror(). The only difference is that it accepts -+ * an error returned by a libtasn1 function. -+ * -+ * Since: 1.6 -+ **/ -+void -+asn1_perror (int error) -+{ -+ const char *str = asn1_strerror (error); -+ fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)"); -+} -+ -+/** -+ * asn1_strerror: -+ * @error: is an error returned by a libtasn1 function. -+ * -+ * Returns a string with a description of an error. This function is -+ * similar to strerror. The only difference is that it accepts an -+ * error (number) returned by a libtasn1 function. -+ * -+ * Returns: Pointer to static zero-terminated string describing error -+ * code. -+ * -+ * Since: 1.6 -+ **/ -+const char * -+asn1_strerror (int error) -+{ -+ const libtasn1_error_entry *p; -+ -+ for (p = error_algorithms; p->name != NULL; p++) -+ if (p->number == error) -+ return p->name + sizeof ("ASN1_") - 1; -+ -+ return NULL; -+} -diff --git a/grub-core/lib/libtasn1/lib/gstr.c b/grub-core/lib/libtasn1/lib/gstr.c -new file mode 100644 -index 00000000000..e91a3a151c0 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/gstr.c -@@ -0,0 +1,74 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#include -+#include "gstr.h" -+ -+/* These function are like strcat, strcpy. They only -+ * do bounds checking (they shouldn't cause buffer overruns), -+ * and they always produce null terminated strings. -+ * -+ * They should be used only with null terminated strings. -+ */ -+void -+_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) -+{ -+ size_t str_size = strlen (src); -+ size_t dest_size = strlen (dest); -+ -+ if (dest_tot_size - dest_size > str_size) -+ { -+ strcat (dest, src); -+ } -+ else -+ { -+ if (dest_tot_size - dest_size > 0) -+ { -+ strncat (dest, src, (dest_tot_size - dest_size) - 1); -+ dest[dest_tot_size - 1] = 0; -+ } -+ } -+} -+ -+/* Returns the bytes copied (not including the null terminator) */ -+unsigned int -+_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src) -+{ -+ size_t str_size = strlen (src); -+ -+ if (dest_tot_size > str_size) -+ { -+ strcpy (dest, src); -+ return str_size; -+ } -+ else -+ { -+ if (dest_tot_size > 0) -+ { -+ str_size = dest_tot_size - 1; -+ memcpy (dest, src, str_size); -+ dest[str_size] = 0; -+ return str_size; -+ } -+ else -+ return 0; -+ } -+} -diff --git a/grub-core/lib/libtasn1/lib/parser_aux.c b/grub-core/lib/libtasn1/lib/parser_aux.c -new file mode 100644 -index 00000000000..d5dbbf8765d ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/parser_aux.c -@@ -0,0 +1,1173 @@ -+/* -+ * Copyright (C) 2000-2016 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#include // WORD_BIT -+ -+#include "int.h" -+#include "parser_aux.h" -+#include "gstr.h" -+#include "structure.h" -+#include "element.h" -+#include "c-ctype.h" -+ -+char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */ -+ -+/* Return a hash of the N bytes of X using the method described by -+ Bruno Haible in https://www.haible.de/bruno/hashfunc.html. -+ Note that while many hash functions reduce their result via modulo -+ to a 0..table_size-1 range, this function does not do that. -+ -+ This implementation has been changed from size_t -> unsigned int. */ -+ -+#ifdef __clang__ -+__attribute__((no_sanitize("integer"))) -+#endif -+_GL_ATTRIBUTE_PURE -+static unsigned int -+_asn1_hash_name (const char *x) -+{ -+ const unsigned char *s = (unsigned char *) x; -+ unsigned h = 0; -+ -+ while (*s) -+ h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9))); -+ -+ return h; -+} -+ -+/******************************************************/ -+/* Function : _asn1_add_static_node */ -+/* Description: creates a new NODE_ASN element and */ -+/* puts it in the list pointed by e_list. */ -+/* Parameters: */ -+/* e_list: of type list_type; must be NULL initially */ -+/* type: type of the new element (see ASN1_ETYPE_ */ -+/* and CONST_ constants). */ -+/* Return: pointer to the new element. */ -+/******************************************************/ -+asn1_node -+_asn1_add_static_node (list_type **e_list, unsigned int type) -+{ -+ list_type *p; -+ asn1_node punt; -+ -+ punt = calloc (1, sizeof (struct asn1_node_st)); -+ if (punt == NULL) -+ return NULL; -+ -+ p = malloc (sizeof (list_type)); -+ if (p == NULL) -+ { -+ free (punt); -+ return NULL; -+ } -+ -+ p->node = punt; -+ p->next = *e_list; -+ *e_list = p; -+ -+ punt->type = type; -+ -+ return punt; -+} -+ -+static -+int _asn1_add_static_node2 (list_type **e_list, asn1_node node) -+{ -+ list_type *p; -+ -+ p = malloc (sizeof (list_type)); -+ if (p == NULL) -+ { -+ return -1; -+ } -+ -+ p->node = node; -+ p->next = *e_list; -+ *e_list = p; -+ -+ return 0; -+} -+ -+/** -+ * asn1_find_node: -+ * @pointer: NODE_ASN element pointer. -+ * @name: null terminated string with the element's name to find. -+ * -+ * Searches for an element called @name starting from @pointer. The -+ * name is composed by different identifiers separated by dots. When -+ * *@pointer has a name, the first identifier must be the name of -+ * *@pointer, otherwise it must be the name of one child of *@pointer. -+ * -+ * Returns: the search result, or %NULL if not found. -+ **/ -+asn1_node -+asn1_find_node (asn1_node_const pointer, const char *name) -+{ -+ asn1_node_const p; -+ char *n_end, n[ASN1_MAX_NAME_SIZE + 1]; -+ const char *n_start; -+ unsigned int nsize; -+ unsigned int nhash; -+ -+ if (pointer == NULL) -+ return NULL; -+ -+ if (name == NULL) -+ return NULL; -+ -+ p = pointer; -+ n_start = name; -+ -+ if (name[0] == '?' && name[1] == 'C' && p->name[0] == '?') -+ { /* ?CURRENT */ -+ n_start = strchr(n_start, '.'); -+ if (n_start) -+ n_start++; -+ } -+ else if (p->name[0] != 0) -+ { /* has *pointer got a name ? */ -+ n_end = strchr (n_start, '.'); /* search the first dot */ -+ if (n_end) -+ { -+ nsize = n_end - n_start; -+ if (nsize >= sizeof(n)) -+ return NULL; -+ -+ memcpy (n, n_start, nsize); -+ n[nsize] = 0; -+ n_start = n_end; -+ n_start++; -+ -+ nhash = _asn1_hash_name (n); -+ } -+ else -+ { -+ _asn1_str_cpy (n, sizeof (n), n_start); -+ nhash = _asn1_hash_name (n); -+ -+ n_start = NULL; -+ } -+ -+ while (p) -+ { -+ if (nhash == p->name_hash && (!strcmp (p->name, n))) -+ break; -+ else -+ p = p->right; -+ } /* while */ -+ -+ if (p == NULL) -+ return NULL; -+ } -+ else -+ { /* *pointer doesn't have a name */ -+ if (n_start[0] == 0) -+ return (asn1_node) p; -+ } -+ -+ while (n_start) -+ { /* Has the end of NAME been reached? */ -+ n_end = strchr (n_start, '.'); /* search the next dot */ -+ if (n_end) -+ { -+ nsize = n_end - n_start; -+ if (nsize >= sizeof(n)) -+ return NULL; -+ -+ memcpy (n, n_start, nsize); -+ n[nsize] = 0; -+ n_start = n_end; -+ n_start++; -+ -+ nhash = _asn1_hash_name (n); -+ } -+ else -+ { -+ _asn1_str_cpy (n, sizeof (n), n_start); -+ nhash = _asn1_hash_name (n); -+ n_start = NULL; -+ } -+ -+ if (p->down == NULL) -+ return NULL; -+ -+ p = p->down; -+ if (p == NULL) -+ return NULL; -+ -+ /* The identifier "?LAST" indicates the last element -+ in the right chain. */ -+ if (n[0] == '?' && n[1] == 'L') /* ?LAST */ -+ { -+ while (p->right) -+ p = p->right; -+ } -+ else -+ { /* no "?LAST" */ -+ while (p) -+ { -+ if (p->name_hash == nhash && !strcmp (p->name, n)) -+ break; -+ else -+ p = p->right; -+ } -+ } -+ if (p == NULL) -+ return NULL; -+ } /* while */ -+ -+ return (asn1_node) p; -+} -+ -+ -+/******************************************************************/ -+/* Function : _asn1_set_value */ -+/* Description: sets the field VALUE in a NODE_ASN element. The */ -+/* previous value (if exist) will be lost */ -+/* Parameters: */ -+/* node: element pointer. */ -+/* value: pointer to the value that you want to set. */ -+/* len: character number of value. */ -+/* Return: pointer to the NODE_ASN element. */ -+/******************************************************************/ -+asn1_node -+_asn1_set_value (asn1_node node, const void *value, unsigned int len) -+{ -+ if (node == NULL) -+ return node; -+ if (node->value) -+ { -+ if (node->value != node->small_value) -+ free (node->value); -+ node->value = NULL; -+ node->value_len = 0; -+ } -+ -+ if (!len) -+ return node; -+ -+ if (len < sizeof (node->small_value)) -+ { -+ node->value = node->small_value; -+ } -+ else -+ { -+ node->value = malloc (len); -+ if (node->value == NULL) -+ return NULL; -+ } -+ node->value_len = len; -+ -+ memcpy (node->value, value, len); -+ return node; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_set_value_lv */ -+/* Description: sets the field VALUE in a NODE_ASN element. The */ -+/* previous value (if exist) will be lost. The value */ -+/* given is stored as an length-value format (LV */ -+/* Parameters: */ -+/* node: element pointer. */ -+/* value: pointer to the value that you want to set. */ -+/* len: character number of value. */ -+/* Return: pointer to the NODE_ASN element. */ -+/******************************************************************/ -+asn1_node -+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len) -+{ -+ int len2; -+ void *temp; -+ -+ if (node == NULL) -+ return node; -+ -+ asn1_length_der (len, NULL, &len2); -+ temp = malloc (len + len2); -+ if (temp == NULL) -+ return NULL; -+ -+ asn1_octet_der (value, len, temp, &len2); -+ return _asn1_set_value_m (node, temp, len2); -+} -+ -+/* the same as _asn1_set_value except that it sets an already malloc'ed -+ * value. -+ */ -+asn1_node -+_asn1_set_value_m (asn1_node node, void *value, unsigned int len) -+{ -+ if (node == NULL) -+ return node; -+ -+ if (node->value) -+ { -+ if (node->value != node->small_value) -+ free (node->value); -+ node->value = NULL; -+ node->value_len = 0; -+ } -+ -+ if (!len) -+ return node; -+ -+ node->value = value; -+ node->value_len = len; -+ -+ return node; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_append_value */ -+/* Description: appends to the field VALUE in a NODE_ASN element. */ -+/* */ -+/* Parameters: */ -+/* node: element pointer. */ -+/* value: pointer to the value that you want to be appended. */ -+/* len: character number of value. */ -+/* Return: pointer to the NODE_ASN element. */ -+/******************************************************************/ -+asn1_node -+_asn1_append_value (asn1_node node, const void *value, unsigned int len) -+{ -+ if (node == NULL) -+ return node; -+ -+ if (node->value == NULL) -+ return _asn1_set_value (node, value, len); -+ -+ if (len == 0) -+ return node; -+ -+ if (node->value == node->small_value) -+ { -+ /* value is in node */ -+ int prev_len = node->value_len; -+ node->value_len += len; -+ node->value = malloc (node->value_len); -+ if (node->value == NULL) -+ { -+ node->value_len = 0; -+ return NULL; -+ } -+ -+ if (prev_len > 0) -+ memcpy (node->value, node->small_value, prev_len); -+ -+ memcpy (&node->value[prev_len], value, len); -+ -+ return node; -+ } -+ else /* if (node->value != NULL && node->value != node->small_value) */ -+ { -+ /* value is allocated */ -+ int prev_len = node->value_len; -+ node->value_len += len; -+ -+ node->value = _asn1_realloc (node->value, node->value_len); -+ if (node->value == NULL) -+ { -+ node->value_len = 0; -+ return NULL; -+ } -+ -+ memcpy (&node->value[prev_len], value, len); -+ -+ return node; -+ } -+} -+ -+/******************************************************************/ -+/* Function : _asn1_set_name */ -+/* Description: sets the field NAME in a NODE_ASN element. The */ -+/* previous value (if exist) will be lost */ -+/* Parameters: */ -+/* node: element pointer. */ -+/* name: a null terminated string with the name that you want */ -+/* to set. */ -+/* Return: pointer to the NODE_ASN element. */ -+/******************************************************************/ -+asn1_node -+_asn1_set_name (asn1_node node, const char *name) -+{ -+ if (node == NULL) -+ return node; -+ -+ _asn1_str_cpy (node->name, sizeof (node->name), name ? name : ""); -+ node->name_hash = _asn1_hash_name (node->name); -+ -+ return node; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_cpy_name */ -+/* Description: copies the field NAME in a NODE_ASN element. */ -+/* Parameters: */ -+/* dst: a dest element pointer. */ -+/* src: a source element pointer. */ -+/* Return: pointer to the NODE_ASN element. */ -+/******************************************************************/ -+asn1_node -+_asn1_cpy_name (asn1_node dst, asn1_node_const src) -+{ -+ if (dst == NULL) -+ return dst; -+ -+ if (src == NULL) -+ { -+ dst->name[0] = 0; -+ dst->name_hash = _asn1_hash_name (dst->name); -+ return dst; -+ } -+ -+ _asn1_str_cpy (dst->name, sizeof (dst->name), src->name); -+ dst->name_hash = src->name_hash; -+ -+ return dst; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_set_right */ -+/* Description: sets the field RIGHT in a NODE_ASN element. */ -+/* Parameters: */ -+/* node: element pointer. */ -+/* right: pointer to a NODE_ASN element that you want be pointed*/ -+/* by NODE. */ -+/* Return: pointer to *NODE. */ -+/******************************************************************/ -+asn1_node -+_asn1_set_right (asn1_node node, asn1_node right) -+{ -+ if (node == NULL) -+ return node; -+ node->right = right; -+ if (right) -+ right->left = node; -+ return node; -+} -+ -+ -+/******************************************************************/ -+/* Function : _asn1_get_last_right */ -+/* Description: return the last element along the right chain. */ -+/* Parameters: */ -+/* node: starting element pointer. */ -+/* Return: pointer to the last element along the right chain. */ -+/******************************************************************/ -+asn1_node -+_asn1_get_last_right (asn1_node_const node) -+{ -+ asn1_node_const p; -+ -+ if (node == NULL) -+ return NULL; -+ p = node; -+ while (p->right) -+ p = p->right; -+ return (asn1_node) p; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_remove_node */ -+/* Description: gets free the memory allocated for an NODE_ASN */ -+/* element (not the elements pointed by it). */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* flags: ASN1_DELETE_FLAG_* */ -+/******************************************************************/ -+void -+_asn1_remove_node (asn1_node node, unsigned int flags) -+{ -+ if (node == NULL) -+ return; -+ -+ if (node->value != NULL) -+ { -+ if (flags & ASN1_DELETE_FLAG_ZEROIZE) -+ { -+ safe_memset(node->value, 0, node->value_len); -+ } -+ -+ if (node->value != node->small_value) -+ free (node->value); -+ } -+ free (node); -+} -+ -+/******************************************************************/ -+/* Function : _asn1_find_up */ -+/* Description: return the father of the NODE_ASN element. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* Return: Null if not found. */ -+/******************************************************************/ -+asn1_node -+_asn1_find_up (asn1_node_const node) -+{ -+ asn1_node_const p; -+ -+ if (node == NULL) -+ return NULL; -+ -+ p = node; -+ -+ while ((p->left != NULL) && (p->left->right == p)) -+ p = p->left; -+ -+ return p->left; -+} -+ -+static -+unsigned _asn1_is_up (asn1_node_const up_cand, asn1_node_const down) -+{ -+ asn1_node_const d, u; -+ -+ if (up_cand == NULL || down == NULL) -+ return 0; -+ -+ d = down; -+ -+ while ((u = _asn1_find_up(d)) != NULL && u != d) -+ { -+ if (u == up_cand) -+ return 1; -+ d = u; -+ } -+ -+ return 0; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_delete_node_from_list */ -+/* Description: deletes the list element given */ -+/******************************************************************/ -+void -+_asn1_delete_node_from_list (list_type *list, asn1_node node) -+{ -+ list_type *p = list; -+ -+ while (p) -+ { -+ if (p->node == node) -+ p->node = NULL; -+ p = p->next; -+ } -+} -+ -+/******************************************************************/ -+/* Function : _asn1_delete_list */ -+/* Description: deletes the list elements (not the elements */ -+/* pointed by them). */ -+/******************************************************************/ -+void -+_asn1_delete_list (list_type *e_list) -+{ -+ list_type *p; -+ -+ while (e_list) -+ { -+ p = e_list; -+ e_list = e_list->next; -+ free (p); -+ } -+} -+ -+/******************************************************************/ -+/* Function : _asn1_delete_list_and nodes */ -+/* Description: deletes the list elements and the elements */ -+/* pointed by them. */ -+/******************************************************************/ -+void -+_asn1_delete_list_and_nodes (list_type *e_list) -+{ -+ list_type *p; -+ -+ while (e_list) -+ { -+ p = e_list; -+ e_list = e_list->next; -+ _asn1_remove_node (p->node, 0); -+ free (p); -+ } -+} -+ -+ -+char * -+_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]) -+{ -+ uint64_t d, r; -+ char temp[LTOSTR_MAX_SIZE]; -+ int count, k, start; -+ uint64_t val; -+ -+ if (v < 0) -+ { -+ str[0] = '-'; -+ start = 1; -+ val = -((uint64_t)v); -+ } -+ else -+ { -+ val = v; -+ start = 0; -+ } -+ -+ count = 0; -+ do -+ { -+ d = val / 10; -+ r = val - d * 10; -+ temp[start + count] = '0' + (char) r; -+ count++; -+ val = d; -+ } -+ while (val && ((start+count) < LTOSTR_MAX_SIZE-1)); -+ -+ for (k = 0; k < count; k++) -+ str[k + start] = temp[start + count - k - 1]; -+ str[count + start] = 0; -+ return str; -+} -+ -+ -+/******************************************************************/ -+/* Function : _asn1_change_integer_value */ -+/* Description: converts into DER coding the value assign to an */ -+/* INTEGER constant. */ -+/* Parameters: */ -+/* node: root of an ASN1element. */ -+/* Return: */ -+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -+/* otherwise ASN1_SUCCESS */ -+/******************************************************************/ -+int -+_asn1_change_integer_value (asn1_node node) -+{ -+ asn1_node p; -+ unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; -+ unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1]; -+ int len; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = node; -+ while (p) -+ { -+ if ((type_field (p->type) == ASN1_ETYPE_INTEGER) -+ && (p->type & CONST_ASSIGN)) -+ { -+ if (p->value) -+ { -+ _asn1_convert_integer (p->value, val, sizeof (val), &len); -+ asn1_octet_der (val, len, val2, &len); -+ _asn1_set_value (p, val2, len); -+ } -+ } -+ -+ if (p->down) -+ { -+ p = p->down; -+ } -+ else -+ { -+ if (p == node) -+ p = NULL; -+ else if (p->right) -+ p = p->right; -+ else -+ { -+ while (1) -+ { -+ p = _asn1_find_up (p); -+ if (p == node) -+ { -+ p = NULL; -+ break; -+ } -+ if (p && p->right) -+ { -+ p = p->right; -+ break; -+ } -+ } -+ } -+ } -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+#define MAX_CONSTANTS 1024 -+/******************************************************************/ -+/* Function : _asn1_expand_object_id */ -+/* Description: expand the IDs of an OBJECT IDENTIFIER constant. */ -+/* Parameters: */ -+/* list: root of an object list */ -+/* node: root of an ASN1 element. */ -+/* Return: */ -+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -+/* otherwise ASN1_SUCCESS */ -+/******************************************************************/ -+int -+_asn1_expand_object_id (list_type **list, asn1_node node) -+{ -+ asn1_node p, p2, p3, p4, p5; -+ char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; -+ int move, tlen, tries; -+ unsigned max_constants; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ _asn1_str_cpy (name_root, sizeof (name_root), node->name); -+ -+ p = node; -+ move = DOWN; -+ tries = 0; -+ -+ while (!((p == node) && (move == UP))) -+ { -+ if (move != UP) -+ { -+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) -+ && (p->type & CONST_ASSIGN)) -+ { -+ p2 = p->down; -+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT)) -+ { -+ if (p2->value && !c_isdigit (p2->value[0])) -+ { -+ _asn1_str_cpy (name2, sizeof (name2), name_root); -+ _asn1_str_cat (name2, sizeof (name2), "."); -+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); -+ p3 = asn1_find_node (node, name2); -+ if (!p3 || _asn1_is_up(p2, p3) || -+ (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || -+ !(p3->type & CONST_ASSIGN)) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ _asn1_set_down (p, p2->right); -+ if (p2->down) -+ _asn1_delete_structure (*list, &p2->down, 0); -+ _asn1_delete_node_from_list(*list, p2); -+ _asn1_remove_node (p2, 0); -+ p2 = p; -+ p4 = p3->down; -+ max_constants = 0; -+ while (p4) -+ { -+ if (type_field (p4->type) == ASN1_ETYPE_CONSTANT) -+ { -+ max_constants++; -+ if (max_constants == MAX_CONSTANTS) -+ return ASN1_RECURSION; -+ -+ p5 = -+ _asn1_add_single_node (ASN1_ETYPE_CONSTANT); -+ _asn1_set_name (p5, p4->name); -+ if (p4->value) -+ { -+ tlen = _asn1_strlen (p4->value); -+ if (tlen > 0) -+ _asn1_set_value (p5, p4->value, tlen + 1); -+ } -+ _asn1_add_static_node2(list, p5); -+ -+ if (p2 == p) -+ { -+ _asn1_set_right (p5, p->down); -+ _asn1_set_down (p, p5); -+ } -+ else -+ { -+ _asn1_set_right (p5, p2->right); -+ _asn1_set_right (p2, p5); -+ } -+ p2 = p5; -+ } -+ p4 = p4->right; -+ } -+ move = DOWN; -+ -+ tries++; -+ if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION) -+ return ASN1_RECURSION; -+ -+ continue; -+ } -+ } -+ } -+ move = DOWN; -+ } -+ else -+ move = RIGHT; -+ -+ tries = 0; -+ if (move == DOWN) -+ { -+ if (p->down) -+ p = p->down; -+ else -+ move = RIGHT; -+ } -+ -+ if (p == node) -+ { -+ move = UP; -+ continue; -+ } -+ -+ if (move == RIGHT) -+ { -+ if (p && p->right) -+ p = p->right; -+ else -+ move = UP; -+ } -+ if (move == UP) -+ p = _asn1_find_up (p); -+ } -+ -+ /*******************************/ -+ /* expand DEFAULT */ -+ /*******************************/ -+ p = node; -+ move = DOWN; -+ -+ while (!((p == node) && (move == UP))) -+ { -+ if (move != UP) -+ { -+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && -+ (p->type & CONST_DEFAULT)) -+ { -+ p2 = p->down; -+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT)) -+ { -+ _asn1_str_cpy (name2, sizeof (name2), name_root); -+ _asn1_str_cat (name2, sizeof (name2), "."); -+ if (p2->value) -+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); -+ p3 = asn1_find_node (node, name2); -+ if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) -+ || !(p3->type & CONST_ASSIGN)) -+ return ASN1_ELEMENT_NOT_FOUND; -+ p4 = p3->down; -+ name2[0] = 0; -+ while (p4) -+ { -+ if (type_field (p4->type) == ASN1_ETYPE_CONSTANT) -+ { -+ if (p4->value == NULL) -+ return ASN1_VALUE_NOT_FOUND; -+ -+ if (name2[0]) -+ _asn1_str_cat (name2, sizeof (name2), "."); -+ _asn1_str_cat (name2, sizeof (name2), -+ (char *) p4->value); -+ } -+ p4 = p4->right; -+ } -+ tlen = strlen (name2); -+ if (tlen > 0) -+ _asn1_set_value (p2, name2, tlen + 1); -+ } -+ } -+ move = DOWN; -+ } -+ else -+ move = RIGHT; -+ -+ if (move == DOWN) -+ { -+ if (p->down) -+ p = p->down; -+ else -+ move = RIGHT; -+ } -+ -+ if (p == node) -+ { -+ move = UP; -+ continue; -+ } -+ -+ if (move == RIGHT) -+ { -+ if (p && p->right) -+ p = p->right; -+ else -+ move = UP; -+ } -+ if (move == UP) -+ p = _asn1_find_up (p); -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/******************************************************************/ -+/* Function : _asn1_type_set_config */ -+/* Description: sets the CONST_SET and CONST_NOT_USED properties */ -+/* in the fields of the SET elements. */ -+/* Parameters: */ -+/* node: root of an ASN1 element. */ -+/* Return: */ -+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -+/* otherwise ASN1_SUCCESS */ -+/******************************************************************/ -+int -+_asn1_type_set_config (asn1_node node) -+{ -+ asn1_node p, p2; -+ int move; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = node; -+ move = DOWN; -+ -+ while (!((p == node) && (move == UP))) -+ { -+ if (move != UP) -+ { -+ if (type_field (p->type) == ASN1_ETYPE_SET) -+ { -+ p2 = p->down; -+ while (p2) -+ { -+ if (type_field (p2->type) != ASN1_ETYPE_TAG) -+ p2->type |= CONST_SET | CONST_NOT_USED; -+ p2 = p2->right; -+ } -+ } -+ move = DOWN; -+ } -+ else -+ move = RIGHT; -+ -+ if (move == DOWN) -+ { -+ if (p->down) -+ p = p->down; -+ else -+ move = RIGHT; -+ } -+ -+ if (p == node) -+ { -+ move = UP; -+ continue; -+ } -+ -+ if (move == RIGHT) -+ { -+ if (p && p->right) -+ p = p->right; -+ else -+ move = UP; -+ } -+ if (move == UP) -+ p = _asn1_find_up (p); -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/******************************************************************/ -+/* Function : _asn1_check_identifier */ -+/* Description: checks the definitions of all the identifiers */ -+/* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */ -+/* The _asn1_identifierMissing global variable is filled if */ -+/* necessary. */ -+/* Parameters: */ -+/* node: root of an ASN1 element. */ -+/* Return: */ -+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -+/* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */ -+/* otherwise ASN1_SUCCESS */ -+/******************************************************************/ -+int -+_asn1_check_identifier (asn1_node_const node) -+{ -+ asn1_node_const p, p2; -+ char name2[ASN1_MAX_NAME_SIZE * 2 + 2]; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = node; -+ while (p) -+ { -+ if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER) -+ { -+ _asn1_str_cpy (name2, sizeof (name2), node->name); -+ _asn1_str_cat (name2, sizeof (name2), "."); -+ _asn1_str_cat (name2, sizeof (name2), (char *) p->value); -+ p2 = asn1_find_node (node, name2); -+ if (p2 == NULL) -+ { -+ if (p->value) -+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p->value); -+ else -+ _asn1_strcpy (_asn1_identifierMissing, "(null)"); -+ return ASN1_IDENTIFIER_NOT_FOUND; -+ } -+ } -+ else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && -+ (p->type & CONST_DEFAULT)) -+ { -+ p2 = p->down; -+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT)) -+ { -+ _asn1_str_cpy (name2, sizeof (name2), node->name); -+ if (p2->value) -+ { -+ _asn1_str_cat (name2, sizeof (name2), "."); -+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); -+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p2->value); -+ } -+ else -+ _asn1_strcpy (_asn1_identifierMissing, "(null)"); -+ -+ p2 = asn1_find_node (node, name2); -+ if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) || -+ !(p2->type & CONST_ASSIGN)) -+ return ASN1_IDENTIFIER_NOT_FOUND; -+ else -+ _asn1_identifierMissing[0] = 0; -+ } -+ } -+ else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && -+ (p->type & CONST_ASSIGN)) -+ { -+ p2 = p->down; -+ if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT)) -+ { -+ if (p2->value && !c_isdigit (p2->value[0])) -+ { -+ _asn1_str_cpy (name2, sizeof (name2), node->name); -+ _asn1_str_cat (name2, sizeof (name2), "."); -+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); -+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p2->value); -+ -+ p2 = asn1_find_node (node, name2); -+ if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) -+ || !(p2->type & CONST_ASSIGN)) -+ return ASN1_IDENTIFIER_NOT_FOUND; -+ else -+ _asn1_identifierMissing[0] = 0; -+ } -+ } -+ } -+ -+ if (p->down) -+ { -+ p = p->down; -+ } -+ else if (p->right) -+ p = p->right; -+ else -+ { -+ while (p) -+ { -+ p = _asn1_find_up (p); -+ if (p == node) -+ { -+ p = NULL; -+ break; -+ } -+ if (p && p->right) -+ { -+ p = p->right; -+ break; -+ } -+ } -+ } -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/******************************************************************/ -+/* Function : _asn1_set_default_tag */ -+/* Description: sets the default IMPLICIT or EXPLICIT property in */ -+/* the tagged elements that don't have this declaration. */ -+/* Parameters: */ -+/* node: pointer to a DEFINITIONS element. */ -+/* Return: */ -+/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */ -+/* a DEFINITIONS element, */ -+/* otherwise ASN1_SUCCESS */ -+/******************************************************************/ -+int -+_asn1_set_default_tag (asn1_node node) -+{ -+ asn1_node p; -+ -+ if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS)) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = node; -+ while (p) -+ { -+ if ((type_field (p->type) == ASN1_ETYPE_TAG) && -+ !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT)) -+ { -+ if (node->type & CONST_EXPLICIT) -+ p->type |= CONST_EXPLICIT; -+ else -+ p->type |= CONST_IMPLICIT; -+ } -+ -+ if (p->down) -+ { -+ p = p->down; -+ } -+ else if (p->right) -+ p = p->right; -+ else -+ { -+ while (1) -+ { -+ p = _asn1_find_up (p); -+ if (p == node) -+ { -+ p = NULL; -+ break; -+ } -+ if (p && p->right) -+ { -+ p = p->right; -+ break; -+ } -+ } -+ } -+ } -+ -+ return ASN1_SUCCESS; -+} -diff --git a/grub-core/lib/libtasn1/lib/structure.c b/grub-core/lib/libtasn1/lib/structure.c -new file mode 100644 -index 00000000000..8189c56a4c9 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/structure.c -@@ -0,0 +1,1220 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+ -+/*****************************************************/ -+/* File: structure.c */ -+/* Description: Functions to create and delete an */ -+/* ASN1 tree. */ -+/*****************************************************/ -+ -+ -+#include -+#include -+#include "parser_aux.h" -+#include -+ -+ -+extern char _asn1_identifierMissing[]; -+ -+ -+/******************************************************/ -+/* Function : _asn1_add_single_node */ -+/* Description: creates a new NODE_ASN element. */ -+/* Parameters: */ -+/* type: type of the new element (see ASN1_ETYPE_ */ -+/* and CONST_ constants). */ -+/* Return: pointer to the new element. */ -+/******************************************************/ -+asn1_node -+_asn1_add_single_node (unsigned int type) -+{ -+ asn1_node punt; -+ -+ punt = calloc (1, sizeof (struct asn1_node_st)); -+ if (punt == NULL) -+ return NULL; -+ -+ punt->type = type; -+ -+ return punt; -+} -+ -+ -+/******************************************************************/ -+/* Function : _asn1_find_left */ -+/* Description: returns the NODE_ASN element with RIGHT field that*/ -+/* points the element NODE. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* Return: NULL if not found. */ -+/******************************************************************/ -+asn1_node -+_asn1_find_left (asn1_node_const node) -+{ -+ if ((node == NULL) || (node->left == NULL) || (node->left->down == node)) -+ return NULL; -+ -+ return node->left; -+} -+ -+ -+int -+_asn1_create_static_structure (asn1_node_const pointer, char *output_file_name, -+ char *vector_name) -+{ -+ FILE *file; -+ asn1_node_const p; -+ unsigned long t; -+ -+ file = fopen (output_file_name, "w"); -+ -+ if (file == NULL) -+ return ASN1_FILE_NOT_FOUND; -+ -+ fprintf (file, "#if HAVE_CONFIG_H\n"); -+ fprintf (file, "# include \"config.h\"\n"); -+ fprintf (file, "#endif\n\n"); -+ -+ fprintf (file, "#include \n\n"); -+ -+ fprintf (file, "const asn1_static_node %s[] = {\n", vector_name); -+ -+ p = pointer; -+ -+ while (p) -+ { -+ fprintf (file, " { "); -+ -+ if (p->name[0] != 0) -+ fprintf (file, "\"%s\", ", p->name); -+ else -+ fprintf (file, "NULL, "); -+ -+ t = p->type; -+ if (p->down) -+ t |= CONST_DOWN; -+ if (p->right) -+ t |= CONST_RIGHT; -+ -+ fprintf (file, "%lu, ", t); -+ -+ if (p->value) -+ fprintf (file, "\"%s\"},\n", p->value); -+ else -+ fprintf (file, "NULL },\n"); -+ -+ if (p->down) -+ { -+ p = p->down; -+ } -+ else if (p->right) -+ { -+ p = p->right; -+ } -+ else -+ { -+ while (1) -+ { -+ p = _asn1_find_up (p); -+ if (p == pointer) -+ { -+ p = NULL; -+ break; -+ } -+ if (p->right) -+ { -+ p = p->right; -+ break; -+ } -+ } -+ } -+ } -+ -+ fprintf (file, " { NULL, 0, NULL }\n};\n"); -+ -+ fclose (file); -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/** -+ * asn1_array2tree: -+ * @array: specify the array that contains ASN.1 declarations -+ * @definitions: return the pointer to the structure created by -+ * *ARRAY ASN.1 declarations -+ * @errorDescription: return the error description. -+ * -+ * Creates the structures needed to manage the ASN.1 definitions. -+ * @array is a vector created by asn1_parser2array(). -+ * -+ * Returns: %ASN1_SUCCESS if structure was created correctly, -+ * %ASN1_ELEMENT_NOT_EMPTY if *@definitions not NULL, -+ * %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an identifier -+ * that is not defined (see @errorDescription for more information), -+ * %ASN1_ARRAY_ERROR if the array pointed by @array is wrong. -+ **/ -+int -+asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, -+ char *errorDescription) -+{ -+ asn1_node p, p_last = NULL; -+ unsigned long k; -+ int move; -+ int result; -+ unsigned int type; -+ list_type *e_list = NULL; -+ -+ if (errorDescription) -+ errorDescription[0] = 0; -+ -+ if (*definitions != NULL) -+ return ASN1_ELEMENT_NOT_EMPTY; -+ -+ move = UP; -+ -+ for (k = 0; array[k].value || array[k].type || array[k].name; k++) -+ { -+ type = convert_old_type (array[k].type); -+ -+ p = _asn1_add_static_node (&e_list, type & (~CONST_DOWN)); -+ if (array[k].name) -+ _asn1_set_name (p, array[k].name); -+ if (array[k].value) -+ _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1); -+ -+ if (*definitions == NULL) -+ *definitions = p; -+ -+ if (move == DOWN) -+ { -+ if (p_last && p_last->down) -+ _asn1_delete_structure (e_list, &p_last->down, 0); -+ _asn1_set_down (p_last, p); -+ } -+ else if (move == RIGHT) -+ { -+ if (p_last && p_last->right) -+ _asn1_delete_structure (e_list, &p_last->right, 0); -+ _asn1_set_right (p_last, p); -+ } -+ -+ p_last = p; -+ -+ if (type & CONST_DOWN) -+ move = DOWN; -+ else if (type & CONST_RIGHT) -+ move = RIGHT; -+ else -+ { -+ while (p_last != *definitions) -+ { -+ p_last = _asn1_find_up (p_last); -+ -+ if (p_last == NULL) -+ break; -+ -+ if (p_last->type & CONST_RIGHT) -+ { -+ p_last->type &= ~CONST_RIGHT; -+ move = RIGHT; -+ break; -+ } -+ } /* while */ -+ } -+ } /* while */ -+ -+ if (p_last == *definitions) -+ { -+ result = _asn1_check_identifier (*definitions); -+ if (result == ASN1_SUCCESS) -+ { -+ _asn1_change_integer_value (*definitions); -+ result = _asn1_expand_object_id (&e_list, *definitions); -+ } -+ } -+ else -+ { -+ result = ASN1_ARRAY_ERROR; -+ } -+ -+ if (errorDescription != NULL) -+ { -+ if (result == ASN1_IDENTIFIER_NOT_FOUND) -+ { -+ Estrcpy (errorDescription, ":: identifier '"); -+ Estrcat (errorDescription, _asn1_identifierMissing); -+ Estrcat (errorDescription, "' not found"); -+ } -+ else -+ errorDescription[0] = 0; -+ } -+ -+ if (result != ASN1_SUCCESS) -+ { -+ _asn1_delete_list_and_nodes (e_list); -+ *definitions = NULL; -+ } -+ else -+ _asn1_delete_list (e_list); -+ -+ return result; -+} -+ -+/** -+ * asn1_delete_structure: -+ * @structure: pointer to the structure that you want to delete. -+ * -+ * Deletes the structure *@structure. At the end, *@structure is set -+ * to NULL. -+ * -+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if -+ * *@structure was NULL. -+ **/ -+int -+asn1_delete_structure (asn1_node * structure) -+{ -+ return _asn1_delete_structure (NULL, structure, 0); -+} -+ -+/** -+ * asn1_delete_structure2: -+ * @structure: pointer to the structure that you want to delete. -+ * @flags: additional flags (see %ASN1_DELETE_FLAG) -+ * -+ * Deletes the structure *@structure. At the end, *@structure is set -+ * to NULL. -+ * -+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if -+ * *@structure was NULL. -+ **/ -+int -+asn1_delete_structure2 (asn1_node * structure, unsigned int flags) -+{ -+ return _asn1_delete_structure (NULL, structure, flags); -+} -+ -+int -+_asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int flags) -+{ -+ asn1_node p, p2, p3; -+ -+ if (*structure == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = *structure; -+ while (p) -+ { -+ if (p->down) -+ { -+ p = p->down; -+ } -+ else -+ { /* no down */ -+ p2 = p->right; -+ if (p != *structure) -+ { -+ p3 = _asn1_find_up (p); -+ _asn1_set_down (p3, p2); -+ if (e_list) -+ _asn1_delete_node_from_list (e_list, p); -+ _asn1_remove_node (p, flags); -+ p = p3; -+ } -+ else -+ { /* p==root */ -+ p3 = _asn1_find_left (p); -+ if (!p3) -+ { -+ p3 = _asn1_find_up (p); -+ if (p3) -+ _asn1_set_down (p3, p2); -+ else -+ { -+ if (p->right) -+ p->right->left = NULL; -+ } -+ } -+ else -+ _asn1_set_right (p3, p2); -+ if (e_list) -+ _asn1_delete_node_from_list (e_list, p); -+ _asn1_remove_node (p, flags); -+ p = NULL; -+ } -+ } -+ } -+ -+ *structure = NULL; -+ return ASN1_SUCCESS; -+} -+ -+ -+/** -+ * asn1_delete_element: -+ * @structure: pointer to the structure that contains the element you -+ * want to delete. -+ * @element_name: element's name you want to delete. -+ * -+ * Deletes the element named *@element_name inside *@structure. -+ * -+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if -+ * the @element_name was not found. -+ **/ -+int -+asn1_delete_element (asn1_node structure, const char *element_name) -+{ -+ asn1_node p2, p3, source_node; -+ -+ source_node = asn1_find_node (structure, element_name); -+ -+ if (source_node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p2 = source_node->right; -+ p3 = _asn1_find_left (source_node); -+ if (!p3) -+ { -+ p3 = _asn1_find_up (source_node); -+ if (p3) -+ _asn1_set_down (p3, p2); -+ else if (source_node->right) -+ source_node->right->left = NULL; -+ } -+ else -+ _asn1_set_right (p3, p2); -+ -+ return asn1_delete_structure (&source_node); -+} -+ -+#ifndef __clang_analyzer__ -+asn1_node -+_asn1_copy_structure3 (asn1_node_const source_node) -+{ -+ asn1_node_const p_s; -+ asn1_node dest_node, p_d, p_d_prev; -+ int move; -+ -+ if (source_node == NULL) -+ return NULL; -+ -+ dest_node = _asn1_add_single_node (source_node->type); -+ -+ p_s = source_node; -+ p_d = dest_node; -+ -+ move = DOWN; -+ -+ do -+ { -+ if (move != UP) -+ { -+ if (p_s->name[0] != 0) -+ _asn1_cpy_name (p_d, p_s); -+ if (p_s->value) -+ _asn1_set_value (p_d, p_s->value, p_s->value_len); -+ if (p_s->down) -+ { -+ p_s = p_s->down; -+ p_d_prev = p_d; -+ p_d = _asn1_add_single_node (p_s->type); -+ _asn1_set_down (p_d_prev, p_d); -+ continue; -+ } -+ p_d->start = p_s->start; -+ p_d->end = p_s->end; -+ } -+ -+ if (p_s == source_node) -+ break; -+ -+ if (p_s->right) -+ { -+ move = RIGHT; -+ p_s = p_s->right; -+ p_d_prev = p_d; -+ p_d = _asn1_add_single_node (p_s->type); -+ _asn1_set_right (p_d_prev, p_d); -+ } -+ else -+ { -+ move = UP; -+ p_s = _asn1_find_up (p_s); -+ p_d = _asn1_find_up (p_d); -+ } -+ } -+ while (p_s != source_node); -+ return dest_node; -+} -+#else -+ -+/* Non-production code */ -+asn1_node -+_asn1_copy_structure3 (asn1_node_const source_node) -+{ -+ return NULL; -+} -+#endif /* __clang_analyzer__ */ -+ -+ -+static asn1_node -+_asn1_copy_structure2 (asn1_node_const root, const char *source_name) -+{ -+ asn1_node source_node; -+ -+ source_node = asn1_find_node (root, source_name); -+ -+ return _asn1_copy_structure3 (source_node); -+ -+} -+ -+ -+static int -+_asn1_type_choice_config (asn1_node node) -+{ -+ asn1_node p, p2, p3, p4; -+ int move, tlen; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = node; -+ move = DOWN; -+ -+ while (!((p == node) && (move == UP))) -+ { -+ if (move != UP) -+ { -+ if ((type_field (p->type) == ASN1_ETYPE_CHOICE) -+ && (p->type & CONST_TAG)) -+ { -+ p2 = p->down; -+ while (p2) -+ { -+ if (type_field (p2->type) != ASN1_ETYPE_TAG) -+ { -+ p2->type |= CONST_TAG; -+ p3 = _asn1_find_left (p2); -+ while (p3) -+ { -+ if (type_field (p3->type) == ASN1_ETYPE_TAG) -+ { -+ p4 = _asn1_add_single_node (p3->type); -+ tlen = _asn1_strlen (p3->value); -+ if (tlen > 0) -+ _asn1_set_value (p4, p3->value, tlen + 1); -+ _asn1_set_right (p4, p2->down); -+ _asn1_set_down (p2, p4); -+ } -+ p3 = _asn1_find_left (p3); -+ } -+ } -+ p2 = p2->right; -+ } -+ p->type &= ~(CONST_TAG); -+ p2 = p->down; -+ while (p2) -+ { -+ p3 = p2->right; -+ if (type_field (p2->type) == ASN1_ETYPE_TAG) -+ asn1_delete_structure (&p2); -+ p2 = p3; -+ } -+ } -+ move = DOWN; -+ } -+ else -+ move = RIGHT; -+ -+ if (move == DOWN) -+ { -+ if (p->down) -+ p = p->down; -+ else -+ move = RIGHT; -+ } -+ -+ if (p == node) -+ { -+ move = UP; -+ continue; -+ } -+ -+ if (move == RIGHT) -+ { -+ if (p->right) -+ p = p->right; -+ else -+ move = UP; -+ } -+ if (move == UP) -+ p = _asn1_find_up (p); -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+static int -+_asn1_expand_identifier (asn1_node * node, asn1_node_const root) -+{ -+ asn1_node p, p2, p3; -+ char name2[ASN1_MAX_NAME_SIZE + 2]; -+ int move; -+ -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = *node; -+ move = DOWN; -+ -+ while (!((p == *node) && (move == UP))) -+ { -+ if (move != UP) -+ { -+ if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER) -+ { -+ snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value); -+ p2 = _asn1_copy_structure2 (root, name2); -+ if (p2 == NULL) -+ { -+ return ASN1_IDENTIFIER_NOT_FOUND; -+ } -+ _asn1_cpy_name (p2, p); -+ p2->right = p->right; -+ p2->left = p->left; -+ if (p->right) -+ p->right->left = p2; -+ p3 = p->down; -+ if (p3) -+ { -+ while (p3->right) -+ p3 = p3->right; -+ _asn1_set_right (p3, p2->down); -+ _asn1_set_down (p2, p->down); -+ } -+ -+ p3 = _asn1_find_left (p); -+ if (p3) -+ _asn1_set_right (p3, p2); -+ else -+ { -+ p3 = _asn1_find_up (p); -+ if (p3) -+ _asn1_set_down (p3, p2); -+ else -+ { -+ p2->left = NULL; -+ } -+ } -+ -+ if (p->type & CONST_SIZE) -+ p2->type |= CONST_SIZE; -+ if (p->type & CONST_TAG) -+ p2->type |= CONST_TAG; -+ if (p->type & CONST_OPTION) -+ p2->type |= CONST_OPTION; -+ if (p->type & CONST_DEFAULT) -+ p2->type |= CONST_DEFAULT; -+ if (p->type & CONST_SET) -+ p2->type |= CONST_SET; -+ if (p->type & CONST_NOT_USED) -+ p2->type |= CONST_NOT_USED; -+ -+ if (p == *node) -+ *node = p2; -+ _asn1_remove_node (p, 0); -+ p = p2; -+ move = DOWN; -+ continue; -+ } -+ move = DOWN; -+ } -+ else -+ move = RIGHT; -+ -+ if (move == DOWN) -+ { -+ if (p->down) -+ p = p->down; -+ else -+ move = RIGHT; -+ } -+ -+ if (p == *node) -+ { -+ move = UP; -+ continue; -+ } -+ -+ if (move == RIGHT) -+ { -+ if (p->right) -+ p = p->right; -+ else -+ move = UP; -+ } -+ if (move == UP) -+ p = _asn1_find_up (p); -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/** -+ * asn1_create_element: -+ * @definitions: pointer to the structure returned by "parser_asn1" function -+ * @source_name: the name of the type of the new structure (must be -+ * inside p_structure). -+ * @element: pointer to the structure created. -+ * -+ * Creates a structure of type @source_name. Example using -+ * "pkix.asn": -+ * -+ * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr); -+ * -+ * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if -+ * @source_name is not known. -+ **/ -+int -+asn1_create_element (asn1_node_const definitions, const char *source_name, -+ asn1_node * element) -+{ -+ asn1_node dest_node; -+ int res; -+ -+ dest_node = _asn1_copy_structure2 (definitions, source_name); -+ -+ if (dest_node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ _asn1_set_name (dest_node, ""); -+ -+ res = _asn1_expand_identifier (&dest_node, definitions); -+ _asn1_type_choice_config (dest_node); -+ -+ *element = dest_node; -+ -+ return res; -+} -+ -+ -+/** -+ * asn1_print_structure: -+ * @out: pointer to the output file (e.g. stdout). -+ * @structure: pointer to the structure that you want to visit. -+ * @name: an element of the structure -+ * @mode: specify how much of the structure to print, can be -+ * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE, -+ * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL. -+ * -+ * Prints on the @out file descriptor the structure's tree starting -+ * from the @name element inside the structure @structure. -+ **/ -+void -+asn1_print_structure (FILE * out, asn1_node_const structure, const char *name, -+ int mode) -+{ -+ asn1_node_const p, root; -+ int k, indent = 0, len, len2, len3; -+ -+ if (out == NULL) -+ return; -+ -+ root = asn1_find_node (structure, name); -+ -+ if (root == NULL) -+ return; -+ -+ p = root; -+ while (p) -+ { -+ if (mode == ASN1_PRINT_ALL) -+ { -+ for (k = 0; k < indent; k++) -+ fprintf (out, " "); -+ fprintf (out, "name:"); -+ if (p->name[0] != 0) -+ fprintf (out, "%s ", p->name); -+ else -+ fprintf (out, "NULL "); -+ } -+ else -+ { -+ switch (type_field (p->type)) -+ { -+ case ASN1_ETYPE_CONSTANT: -+ case ASN1_ETYPE_TAG: -+ case ASN1_ETYPE_SIZE: -+ break; -+ default: -+ for (k = 0; k < indent; k++) -+ fprintf (out, " "); -+ fprintf (out, "name:"); -+ if (p->name[0] != 0) -+ fprintf (out, "%s ", p->name); -+ else -+ fprintf (out, "NULL "); -+ } -+ } -+ -+ if (mode != ASN1_PRINT_NAME) -+ { -+ unsigned type = type_field (p->type); -+ switch (type) -+ { -+ case ASN1_ETYPE_CONSTANT: -+ if (mode == ASN1_PRINT_ALL) -+ fprintf (out, "type:CONST"); -+ break; -+ case ASN1_ETYPE_TAG: -+ if (mode == ASN1_PRINT_ALL) -+ fprintf (out, "type:TAG"); -+ break; -+ case ASN1_ETYPE_SIZE: -+ if (mode == ASN1_PRINT_ALL) -+ fprintf (out, "type:SIZE"); -+ break; -+ case ASN1_ETYPE_DEFAULT: -+ fprintf (out, "type:DEFAULT"); -+ break; -+ case ASN1_ETYPE_IDENTIFIER: -+ fprintf (out, "type:IDENTIFIER"); -+ break; -+ case ASN1_ETYPE_ANY: -+ fprintf (out, "type:ANY"); -+ break; -+ case ASN1_ETYPE_CHOICE: -+ fprintf (out, "type:CHOICE"); -+ break; -+ case ASN1_ETYPE_DEFINITIONS: -+ fprintf (out, "type:DEFINITIONS"); -+ break; -+ CASE_HANDLED_ETYPES: -+ fprintf (out, "%s", _asn1_tags[type].desc); -+ break; -+ default: -+ break; -+ } -+ } -+ -+ if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL)) -+ { -+ switch (type_field (p->type)) -+ { -+ case ASN1_ETYPE_CONSTANT: -+ if (mode == ASN1_PRINT_ALL) -+ if (p->value) -+ fprintf (out, " value:%s", p->value); -+ break; -+ case ASN1_ETYPE_TAG: -+ if (mode == ASN1_PRINT_ALL) -+ if (p->value) -+ fprintf (out, " value:%s", p->value); -+ break; -+ case ASN1_ETYPE_SIZE: -+ if (mode == ASN1_PRINT_ALL) -+ if (p->value) -+ fprintf (out, " value:%s", p->value); -+ break; -+ case ASN1_ETYPE_DEFAULT: -+ if (p->value) -+ fprintf (out, " value:%s", p->value); -+ else if (p->type & CONST_TRUE) -+ fprintf (out, " value:TRUE"); -+ else if (p->type & CONST_FALSE) -+ fprintf (out, " value:FALSE"); -+ break; -+ case ASN1_ETYPE_IDENTIFIER: -+ if (p->value) -+ fprintf (out, " value:%s", p->value); -+ break; -+ case ASN1_ETYPE_INTEGER: -+ if (p->value) -+ { -+ len2 = -1; -+ len = asn1_get_length_der (p->value, p->value_len, &len2); -+ fprintf (out, " value:0x"); -+ if (len > 0) -+ for (k = 0; k < len; k++) -+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); -+ } -+ break; -+ case ASN1_ETYPE_ENUMERATED: -+ if (p->value) -+ { -+ len2 = -1; -+ len = asn1_get_length_der (p->value, p->value_len, &len2); -+ fprintf (out, " value:0x"); -+ if (len > 0) -+ for (k = 0; k < len; k++) -+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); -+ } -+ break; -+ case ASN1_ETYPE_BOOLEAN: -+ if (p->value) -+ { -+ if (p->value[0] == 'T') -+ fprintf (out, " value:TRUE"); -+ else if (p->value[0] == 'F') -+ fprintf (out, " value:FALSE"); -+ } -+ break; -+ case ASN1_ETYPE_BIT_STRING: -+ if (p->value) -+ { -+ len2 = -1; -+ len = asn1_get_length_der (p->value, p->value_len, &len2); -+ if (len > 0) -+ { -+ fprintf (out, " value(%i):", -+ (len - 1) * 8 - (p->value[len2])); -+ for (k = 1; k < len; k++) -+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); -+ } -+ } -+ break; -+ case ASN1_ETYPE_GENERALIZED_TIME: -+ case ASN1_ETYPE_UTC_TIME: -+ if (p->value) -+ { -+ fprintf (out, " value:"); -+ for (k = 0; k < p->value_len; k++) -+ fprintf (out, "%c", (p->value)[k]); -+ } -+ break; -+ case ASN1_ETYPE_GENERALSTRING: -+ case ASN1_ETYPE_NUMERIC_STRING: -+ case ASN1_ETYPE_IA5_STRING: -+ case ASN1_ETYPE_TELETEX_STRING: -+ case ASN1_ETYPE_PRINTABLE_STRING: -+ case ASN1_ETYPE_UNIVERSAL_STRING: -+ case ASN1_ETYPE_UTF8_STRING: -+ case ASN1_ETYPE_VISIBLE_STRING: -+ if (p->value) -+ { -+ len2 = -1; -+ len = asn1_get_length_der (p->value, p->value_len, &len2); -+ fprintf (out, " value:"); -+ if (len > 0) -+ for (k = 0; k < len; k++) -+ fprintf (out, "%c", (p->value)[k + len2]); -+ } -+ break; -+ case ASN1_ETYPE_BMP_STRING: -+ case ASN1_ETYPE_OCTET_STRING: -+ if (p->value) -+ { -+ len2 = -1; -+ len = asn1_get_length_der (p->value, p->value_len, &len2); -+ fprintf (out, " value:"); -+ if (len > 0) -+ for (k = 0; k < len; k++) -+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); -+ } -+ break; -+ case ASN1_ETYPE_OBJECT_ID: -+ if (p->value) -+ fprintf (out, " value:%s", p->value); -+ break; -+ case ASN1_ETYPE_ANY: -+ if (p->value) -+ { -+ len3 = -1; -+ len2 = asn1_get_length_der (p->value, p->value_len, &len3); -+ fprintf (out, " value:"); -+ if (len2 > 0) -+ for (k = 0; k < len2; k++) -+ fprintf (out, "%02x", (unsigned) (p->value)[k + len3]); -+ } -+ break; -+ case ASN1_ETYPE_SET: -+ case ASN1_ETYPE_SET_OF: -+ case ASN1_ETYPE_CHOICE: -+ case ASN1_ETYPE_DEFINITIONS: -+ case ASN1_ETYPE_SEQUENCE_OF: -+ case ASN1_ETYPE_SEQUENCE: -+ case ASN1_ETYPE_NULL: -+ break; -+ default: -+ break; -+ } -+ } -+ -+ if (mode == ASN1_PRINT_ALL) -+ { -+ if (p->type & 0x1FFFFF00) -+ { -+ fprintf (out, " attr:"); -+ if (p->type & CONST_UNIVERSAL) -+ fprintf (out, "UNIVERSAL,"); -+ if (p->type & CONST_PRIVATE) -+ fprintf (out, "PRIVATE,"); -+ if (p->type & CONST_APPLICATION) -+ fprintf (out, "APPLICATION,"); -+ if (p->type & CONST_EXPLICIT) -+ fprintf (out, "EXPLICIT,"); -+ if (p->type & CONST_IMPLICIT) -+ fprintf (out, "IMPLICIT,"); -+ if (p->type & CONST_TAG) -+ fprintf (out, "TAG,"); -+ if (p->type & CONST_DEFAULT) -+ fprintf (out, "DEFAULT,"); -+ if (p->type & CONST_TRUE) -+ fprintf (out, "TRUE,"); -+ if (p->type & CONST_FALSE) -+ fprintf (out, "FALSE,"); -+ if (p->type & CONST_LIST) -+ fprintf (out, "LIST,"); -+ if (p->type & CONST_MIN_MAX) -+ fprintf (out, "MIN_MAX,"); -+ if (p->type & CONST_OPTION) -+ fprintf (out, "OPTION,"); -+ if (p->type & CONST_1_PARAM) -+ fprintf (out, "1_PARAM,"); -+ if (p->type & CONST_SIZE) -+ fprintf (out, "SIZE,"); -+ if (p->type & CONST_DEFINED_BY) -+ fprintf (out, "DEF_BY,"); -+ if (p->type & CONST_GENERALIZED) -+ fprintf (out, "GENERALIZED,"); -+ if (p->type & CONST_UTC) -+ fprintf (out, "UTC,"); -+ if (p->type & CONST_SET) -+ fprintf (out, "SET,"); -+ if (p->type & CONST_NOT_USED) -+ fprintf (out, "NOT_USED,"); -+ if (p->type & CONST_ASSIGN) -+ fprintf (out, "ASSIGNMENT,"); -+ } -+ } -+ -+ if (mode == ASN1_PRINT_ALL) -+ { -+ fprintf (out, "\n"); -+ } -+ else -+ { -+ switch (type_field (p->type)) -+ { -+ case ASN1_ETYPE_CONSTANT: -+ case ASN1_ETYPE_TAG: -+ case ASN1_ETYPE_SIZE: -+ break; -+ default: -+ fprintf (out, "\n"); -+ } -+ } -+ -+ if (p->down) -+ { -+ p = p->down; -+ indent += 2; -+ } -+ else if (p == root) -+ { -+ p = NULL; -+ break; -+ } -+ else if (p->right) -+ p = p->right; -+ else -+ { -+ while (1) -+ { -+ p = _asn1_find_up (p); -+ if (p == root) -+ { -+ p = NULL; -+ break; -+ } -+ indent -= 2; -+ if (p->right) -+ { -+ p = p->right; -+ break; -+ } -+ } -+ } -+ } -+} -+ -+ -+ -+/** -+ * asn1_number_of_elements: -+ * @element: pointer to the root of an ASN1 structure. -+ * @name: the name of a sub-structure of ROOT. -+ * @num: pointer to an integer where the result will be stored -+ * -+ * Counts the number of elements of a sub-structure called NAME with -+ * names equal to "?1","?2", ... -+ * -+ * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if -+ * @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL. -+ **/ -+int -+asn1_number_of_elements (asn1_node_const element, const char *name, int *num) -+{ -+ asn1_node_const node, p; -+ -+ if (num == NULL) -+ return ASN1_GENERIC_ERROR; -+ -+ *num = 0; -+ -+ node = asn1_find_node (element, name); -+ if (node == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; -+ -+ p = node->down; -+ -+ while (p) -+ { -+ if (p->name[0] == '?') -+ (*num)++; -+ p = p->right; -+ } -+ -+ return ASN1_SUCCESS; -+} -+ -+ -+/** -+ * asn1_find_structure_from_oid: -+ * @definitions: ASN1 definitions -+ * @oidValue: value of the OID to search (e.g. "1.2.3.4"). -+ * -+ * Search the structure that is defined just after an OID definition. -+ * -+ * Returns: %NULL when @oidValue not found, otherwise the pointer to a -+ * constant string that contains the element name defined just after -+ * the OID. -+ **/ -+const char * -+asn1_find_structure_from_oid (asn1_node_const definitions, const char *oidValue) -+{ -+ char name[2 * ASN1_MAX_NAME_SIZE + 2]; -+ char value[ASN1_MAX_NAME_SIZE]; -+ asn1_node p; -+ int len; -+ int result; -+ const char *definitionsName; -+ -+ if ((definitions == NULL) || (oidValue == NULL)) -+ return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ -+ -+ definitionsName = definitions->name; -+ -+ /* search the OBJECT_ID into definitions */ -+ p = definitions->down; -+ while (p) -+ { -+ if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && -+ (p->type & CONST_ASSIGN)) -+ { -+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p->name); -+ -+ len = ASN1_MAX_NAME_SIZE; -+ result = asn1_read_value (definitions, name, value, &len); -+ -+ if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value))) -+ { -+ p = p->right; -+ if (p == NULL) /* reach the end of ASN1 definitions */ -+ return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ -+ -+ return p->name; -+ } -+ } -+ p = p->right; -+ } -+ -+ return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ -+} -+ -+/** -+ * asn1_copy_node: -+ * @dst: Destination asn1 node. -+ * @dst_name: Field name in destination node. -+ * @src: Source asn1 node. -+ * @src_name: Field name in source node. -+ * -+ * Create a deep copy of a asn1_node variable. That -+ * function requires @dst to be expanded using asn1_create_element(). -+ * -+ * Returns: Return %ASN1_SUCCESS on success. -+ **/ -+int -+asn1_copy_node (asn1_node dst, const char *dst_name, -+ asn1_node_const src, const char *src_name) -+{ -+ int result; -+ asn1_node dst_node; -+ void *data = NULL; -+ int size = 0; -+ -+ result = asn1_der_coding (src, src_name, NULL, &size, NULL); -+ if (result != ASN1_MEM_ERROR) -+ return result; -+ -+ data = malloc (size); -+ if (data == NULL) -+ return ASN1_MEM_ERROR; -+ -+ result = asn1_der_coding (src, src_name, data, &size, NULL); -+ if (result != ASN1_SUCCESS) -+ { -+ free (data); -+ return result; -+ } -+ -+ dst_node = asn1_find_node (dst, dst_name); -+ if (dst_node == NULL) -+ { -+ free (data); -+ return ASN1_ELEMENT_NOT_FOUND; -+ } -+ -+ result = asn1_der_decoding (&dst_node, data, size, NULL); -+ -+ free (data); -+ -+ return result; -+} -+ -+/** -+ * asn1_dup_node: -+ * @src: Source asn1 node. -+ * @src_name: Field name in source node. -+ * -+ * Create a deep copy of a asn1_node variable. This function -+ * will return an exact copy of the provided structure. -+ * -+ * Returns: Return %NULL on failure. -+ **/ -+asn1_node -+asn1_dup_node (asn1_node_const src, const char *src_name) -+{ -+ return _asn1_copy_structure2(src, src_name); -+} -diff --git a/grub-core/lib/libtasn1/lib/element.h b/grub-core/lib/libtasn1/lib/element.h -new file mode 100644 -index 00000000000..440a33f4bb1 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/element.h -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (C) 2000-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#ifndef _ELEMENT_H -+#define _ELEMENT_H -+ -+ -+struct node_tail_cache_st -+{ -+ asn1_node head; /* the first element of the sequence */ -+ asn1_node tail; -+}; -+ -+int _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcached); -+ -+int _asn1_convert_integer (const unsigned char *value, -+ unsigned char *value_out, -+ int value_out_size, int *len); -+ -+void _asn1_hierarchical_name (asn1_node_const node, char *name, int name_size); -+ -+#endif -diff --git a/grub-core/lib/libtasn1/lib/gstr.h b/grub-core/lib/libtasn1/lib/gstr.h -new file mode 100644 -index 00000000000..48229844ff3 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/gstr.h -@@ -0,0 +1,47 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#ifndef GSTR_H -+# define GSTR_H -+ -+unsigned int _asn1_str_cpy (char *dest, size_t dest_tot_size, -+ const char *src); -+void _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src); -+ -+#define Estrcpy(x,y) _asn1_str_cpy(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) -+#define Estrcat(x,y) _asn1_str_cat(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) -+ -+inline static -+void safe_memset(void *data, int c, size_t size) -+{ -+ volatile unsigned volatile_zero = 0; -+ volatile char *vdata = (volatile char*)data; -+ -+ /* This is based on a nice trick for safe memset, -+ * sent by David Jacobson in the openssl-dev mailing list. -+ */ -+ -+ if (size > 0) do { -+ memset(data, c, size); -+ } while(vdata[volatile_zero] != c); -+} -+ -+#endif /* GSTR_H */ -diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h -new file mode 100644 -index 00000000000..ea1625786c1 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/int.h -@@ -0,0 +1,221 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#ifndef INT_H -+#define INT_H -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+ -+#ifdef HAVE_SYS_TYPES_H -+#include -+#endif -+ -+#include -+ -+#define ASN1_SMALL_VALUE_SIZE 16 -+ -+/* This structure is also in libtasn1.h, but then contains less -+ fields. You cannot make any modifications to these first fields -+ without breaking ABI. */ -+struct asn1_node_st -+{ -+ /* public fields: */ -+ char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */ -+ unsigned int name_hash; -+ unsigned int type; /* Node type */ -+ unsigned char *value; /* Node value */ -+ int value_len; -+ asn1_node down; /* Pointer to the son node */ -+ asn1_node right; /* Pointer to the brother node */ -+ asn1_node left; /* Pointer to the next list element */ -+ /* private fields: */ -+ unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */ -+ -+ /* values used during decoding/coding */ -+ int tmp_ival; -+ unsigned start; /* the start of the DER sequence - if decoded */ -+ unsigned end; /* the end of the DER sequence - if decoded */ -+}; -+ -+typedef struct tag_and_class_st -+{ -+ unsigned tag; -+ unsigned class; -+ const char *desc; -+} tag_and_class_st; -+ -+/* the types that are handled in _asn1_tags */ -+#define CASE_HANDLED_ETYPES \ -+ case ASN1_ETYPE_NULL: \ -+ case ASN1_ETYPE_BOOLEAN: \ -+ case ASN1_ETYPE_INTEGER: \ -+ case ASN1_ETYPE_ENUMERATED: \ -+ case ASN1_ETYPE_OBJECT_ID: \ -+ case ASN1_ETYPE_OCTET_STRING: \ -+ case ASN1_ETYPE_GENERALSTRING: \ -+ case ASN1_ETYPE_NUMERIC_STRING: \ -+ case ASN1_ETYPE_IA5_STRING: \ -+ case ASN1_ETYPE_TELETEX_STRING: \ -+ case ASN1_ETYPE_PRINTABLE_STRING: \ -+ case ASN1_ETYPE_UNIVERSAL_STRING: \ -+ case ASN1_ETYPE_BMP_STRING: \ -+ case ASN1_ETYPE_UTF8_STRING: \ -+ case ASN1_ETYPE_VISIBLE_STRING: \ -+ case ASN1_ETYPE_BIT_STRING: \ -+ case ASN1_ETYPE_SEQUENCE: \ -+ case ASN1_ETYPE_SEQUENCE_OF: \ -+ case ASN1_ETYPE_SET: \ -+ case ASN1_ETYPE_UTC_TIME: \ -+ case ASN1_ETYPE_GENERALIZED_TIME: \ -+ case ASN1_ETYPE_SET_OF -+ -+#define ETYPE_TAG(etype) (_asn1_tags[etype].tag) -+#define ETYPE_CLASS(etype) (_asn1_tags[etype].class) -+#define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \ -+ (etype) <= _asn1_tags_size && \ -+ _asn1_tags[(etype)].desc != NULL)?1:0) -+ -+#define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \ -+ etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING || \ -+ etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING || \ -+ etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING || \ -+ etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING || \ -+ etype == ASN1_ETYPE_OCTET_STRING)?1:0) -+ -+extern unsigned int _asn1_tags_size; -+extern const tag_and_class_st _asn1_tags[]; -+ -+#define _asn1_strlen(s) strlen((const char *) s) -+#define _asn1_strtol(n,e,b) strtol((const char *) n, e, b) -+#define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) -+#define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) -+#define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) -+#define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) -+ -+#if SIZEOF_UNSIGNED_LONG_INT == 8 -+# define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) -+#else -+# define _asn1_strtou64(n,e,b) strtoull((const char *) n, e, b) -+#endif -+ -+#define MAX_LOG_SIZE 1024 /* maximum number of characters of a log message */ -+ -+/* Define used for visiting trees. */ -+#define UP 1 -+#define RIGHT 2 -+#define DOWN 3 -+ -+/***********************************************************************/ -+/* List of constants to better specify the type of typedef asn1_node_st. */ -+/***********************************************************************/ -+/* Used with TYPE_TAG */ -+#define CONST_UNIVERSAL (1U<<8) -+#define CONST_PRIVATE (1U<<9) -+#define CONST_APPLICATION (1U<<10) -+#define CONST_EXPLICIT (1U<<11) -+#define CONST_IMPLICIT (1U<<12) -+ -+#define CONST_TAG (1U<<13) /* Used in ASN.1 assignement */ -+#define CONST_OPTION (1U<<14) -+#define CONST_DEFAULT (1U<<15) -+#define CONST_TRUE (1U<<16) -+#define CONST_FALSE (1U<<17) -+ -+#define CONST_LIST (1U<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */ -+#define CONST_MIN_MAX (1U<<19) -+ -+#define CONST_1_PARAM (1U<<20) -+ -+#define CONST_SIZE (1U<<21) -+ -+#define CONST_DEFINED_BY (1U<<22) -+ -+/* Those two are deprecated and used for backwards compatibility */ -+#define CONST_GENERALIZED (1U<<23) -+#define CONST_UTC (1U<<24) -+ -+/* #define CONST_IMPORTS (1U<<25) */ -+ -+#define CONST_NOT_USED (1U<<26) -+#define CONST_SET (1U<<27) -+#define CONST_ASSIGN (1U<<28) -+ -+#define CONST_DOWN (1U<<29) -+#define CONST_RIGHT (1U<<30) -+ -+ -+#define ASN1_ETYPE_TIME 17 -+/****************************************/ -+/* Returns the first 8 bits. */ -+/* Used with the field type of asn1_node_st */ -+/****************************************/ -+inline static unsigned int -+type_field (unsigned int ntype) -+{ -+ return (ntype & 0xff); -+} -+ -+/* To convert old types from a static structure */ -+inline static unsigned int -+convert_old_type (unsigned int ntype) -+{ -+ unsigned int type = ntype & 0xff; -+ if (type == ASN1_ETYPE_TIME) -+ { -+ if (ntype & CONST_UTC) -+ type = ASN1_ETYPE_UTC_TIME; -+ else -+ type = ASN1_ETYPE_GENERALIZED_TIME; -+ -+ ntype &= ~(CONST_UTC | CONST_GENERALIZED); -+ ntype &= 0xffffff00; -+ ntype |= type; -+ -+ return ntype; -+ } -+ else -+ return ntype; -+} -+ -+static inline -+void *_asn1_realloc(void *ptr, size_t size) -+{ -+ void *ret; -+ -+ if (size == 0) -+ return ptr; -+ -+ ret = realloc(ptr, size); -+ if (ret == NULL) -+ { -+ free(ptr); -+ } -+ return ret; -+} -+ -+#endif /* INT_H */ -diff --git a/grub-core/lib/libtasn1/lib/parser_aux.h b/grub-core/lib/libtasn1/lib/parser_aux.h -new file mode 100644 -index 00000000000..598e684b355 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/parser_aux.h -@@ -0,0 +1,172 @@ -+/* -+ * Copyright (C) 2000-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#ifndef _PARSER_AUX_H -+#define _PARSER_AUX_H -+ -+/***********************************************/ -+/* Type: list_type */ -+/* Description: type used in the list during */ -+/* the structure creation. */ -+/***********************************************/ -+typedef struct list_struct -+{ -+ asn1_node node; -+ struct list_struct *next; -+} list_type; -+ -+/***************************************/ -+/* Functions used by ASN.1 parser */ -+/***************************************/ -+asn1_node _asn1_add_static_node (list_type **e_list, unsigned int type); -+ -+void _asn1_delete_list (list_type *e_list); -+ -+void _asn1_delete_list_and_nodes (list_type *e_list); -+ -+void _asn1_delete_node_from_list (list_type *list, asn1_node node); -+ -+asn1_node -+_asn1_set_value (asn1_node node, const void *value, unsigned int len); -+ -+asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len); -+ -+asn1_node -+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len); -+ -+asn1_node -+_asn1_append_value (asn1_node node, const void *value, unsigned int len); -+ -+asn1_node _asn1_set_name (asn1_node node, const char *name); -+ -+asn1_node _asn1_cpy_name (asn1_node dst, asn1_node_const src); -+ -+asn1_node _asn1_set_right (asn1_node node, asn1_node right); -+ -+asn1_node _asn1_get_last_right (asn1_node_const node); -+ -+void _asn1_remove_node (asn1_node node, unsigned int flags); -+ -+/* Max 64-bit integer length is 20 chars + 1 for sign + 1 for null termination */ -+#define LTOSTR_MAX_SIZE 22 -+char *_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]); -+ -+asn1_node _asn1_find_up (asn1_node_const node); -+ -+int _asn1_change_integer_value (asn1_node node); -+ -+#define EXPAND_OBJECT_ID_MAX_RECURSION 16 -+int _asn1_expand_object_id (list_type **list, asn1_node node); -+ -+int _asn1_type_set_config (asn1_node node); -+ -+int _asn1_check_identifier (asn1_node_const node); -+ -+int _asn1_set_default_tag (asn1_node node); -+ -+/******************************************************************/ -+/* Function : _asn1_get_right */ -+/* Description: returns the element pointed by the RIGHT field of */ -+/* a NODE_ASN element. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* Return: field RIGHT of NODE. */ -+/******************************************************************/ -+inline static asn1_node -+_asn1_get_right (asn1_node_const node) -+{ -+ if (node == NULL) -+ return NULL; -+ return node->right; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_set_down */ -+/* Description: sets the field DOWN in a NODE_ASN element. */ -+/* Parameters: */ -+/* node: element pointer. */ -+/* down: pointer to a NODE_ASN element that you want be pointed */ -+/* by NODE. */ -+/* Return: pointer to *NODE. */ -+/******************************************************************/ -+inline static asn1_node -+_asn1_set_down (asn1_node node, asn1_node down) -+{ -+ if (node == NULL) -+ return node; -+ node->down = down; -+ if (down) -+ down->left = node; -+ return node; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_get_down */ -+/* Description: returns the element pointed by the DOWN field of */ -+/* a NODE_ASN element. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* Return: field DOWN of NODE. */ -+/******************************************************************/ -+inline static asn1_node -+_asn1_get_down (asn1_node_const node) -+{ -+ if (node == NULL) -+ return NULL; -+ return node->down; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_get_name */ -+/* Description: returns the name of a NODE_ASN element. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* Return: a null terminated string. */ -+/******************************************************************/ -+inline static char * -+_asn1_get_name (asn1_node_const node) -+{ -+ if (node == NULL) -+ return NULL; -+ return (char *) node->name; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_mod_type */ -+/* Description: change the field TYPE of an NODE_ASN element. */ -+/* The new value is the old one | (bitwise or) the */ -+/* paramener VALUE. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* value: the integer value that must be or-ed with the current */ -+/* value of field TYPE. */ -+/* Return: NODE pointer. */ -+/******************************************************************/ -+inline static asn1_node -+_asn1_mod_type (asn1_node node, unsigned int value) -+{ -+ if (node == NULL) -+ return node; -+ node->type |= value; -+ return node; -+} -+ -+#endif -diff --git a/grub-core/lib/libtasn1/lib/structure.h b/grub-core/lib/libtasn1/lib/structure.h -new file mode 100644 -index 00000000000..99e685da07a ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/structure.h -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+/*************************************************/ -+/* File: structure.h */ -+/* Description: list of exported object by */ -+/* "structure.c" */ -+/*************************************************/ -+ -+#ifndef _STRUCTURE_H -+#define _STRUCTURE_H -+ -+#include "parser_aux.h" // list_type -+ -+int _asn1_create_static_structure (asn1_node_const pointer, -+ char *output_file_name, char *vector_name); -+ -+asn1_node _asn1_copy_structure3 (asn1_node_const source_node); -+ -+asn1_node _asn1_add_single_node (unsigned int type); -+ -+asn1_node _asn1_find_left (asn1_node_const node); -+ -+int -+_asn1_delete_structure (list_type *e_list, asn1_node *structure, unsigned int flags); -+ -+#endif -diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h -new file mode 100644 -index 00000000000..6fd7a30dc35 ---- /dev/null -+++ b/include/grub/libtasn1.h -@@ -0,0 +1,588 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * LIBTASN1 is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Lesser General Public License as -+ * published by the Free Software Foundation; either version 2.1 of -+ * the License, or (at your option) any later version. -+ * -+ * LIBTASN1 is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with LIBTASN1; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ * -+ */ -+ -+/** -+ * libtasn1:Short_Description: -+ * -+ * GNU ASN.1 library -+ */ -+/** -+ * libtasn1:Long_Description: -+ * -+ * The Libtasn1 library provides Abstract Syntax Notation One (ASN.1, as -+ * specified by the X.680 ITU-T recommendation) parsing and structures -+ * management, and Distinguished Encoding Rules (DER, as per X.690) -+ * encoding and decoding functions. -+ */ -+ -+ -+#ifndef LIBTASN1_H -+#define LIBTASN1_H -+ -+#ifndef ASN1_API -+#if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY -+#define ASN1_API __attribute__((__visibility__("default"))) -+#elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC -+#define ASN1_API __declspec(dllexport) -+#elif defined _MSC_VER && ! defined ASN1_STATIC -+#define ASN1_API __declspec(dllimport) -+#else -+#define ASN1_API -+#endif -+#endif -+ -+#ifdef __GNUC__ -+# define __LIBTASN1_CONST__ __attribute__((const)) -+# define __LIBTASN1_PURE__ __attribute__((pure)) -+#else -+# define __LIBTASN1_CONST__ -+# define __LIBTASN1_PURE__ -+#endif -+ -+#include -+#include -+#include /* for FILE* */ -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+/** -+ * ASN1_VERSION: -+ * -+ * Version of the library as a string. -+ */ -+#define ASN1_VERSION "4.16.0" -+ -+/** -+ * ASN1_VERSION_MAJOR: -+ * -+ * Major version number of the library. -+ */ -+#define ASN1_VERSION_MAJOR 4 -+ -+/** -+ * ASN1_VERSION_MINOR: -+ * -+ * Minor version number of the library. -+ */ -+#define ASN1_VERSION_MINOR 16 -+ -+/** -+ * ASN1_VERSION_PATCH: -+ * -+ * Patch version number of the library. -+ */ -+#define ASN1_VERSION_PATCH 0 -+ -+/** -+ * ASN1_VERSION_NUMBER: -+ * -+ * Version number of the library as a number. -+ */ -+#define ASN1_VERSION_NUMBER 0x041000 -+ -+ -+#if defined __GNUC__ && !defined ASN1_INTERNAL_BUILD -+# define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -+# if _ASN1_GCC_VERSION >= 30100 -+# define _ASN1_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) -+# endif -+#endif -+ -+#ifndef _ASN1_GCC_ATTR_DEPRECATED -+#define _ASN1_GCC_ATTR_DEPRECATED -+#endif -+ -+/*****************************************/ -+/* Errors returned by libtasn1 functions */ -+/*****************************************/ -+#define ASN1_SUCCESS 0 -+#define ASN1_FILE_NOT_FOUND 1 -+#define ASN1_ELEMENT_NOT_FOUND 2 -+#define ASN1_IDENTIFIER_NOT_FOUND 3 -+#define ASN1_DER_ERROR 4 -+#define ASN1_VALUE_NOT_FOUND 5 -+#define ASN1_GENERIC_ERROR 6 -+#define ASN1_VALUE_NOT_VALID 7 -+#define ASN1_TAG_ERROR 8 -+#define ASN1_TAG_IMPLICIT 9 -+#define ASN1_ERROR_TYPE_ANY 10 -+#define ASN1_SYNTAX_ERROR 11 -+#define ASN1_MEM_ERROR 12 -+#define ASN1_MEM_ALLOC_ERROR 13 -+#define ASN1_DER_OVERFLOW 14 -+#define ASN1_NAME_TOO_LONG 15 -+#define ASN1_ARRAY_ERROR 16 -+#define ASN1_ELEMENT_NOT_EMPTY 17 -+#define ASN1_TIME_ENCODING_ERROR 18 -+#define ASN1_RECURSION 19 -+ -+/*************************************/ -+/* Constants used in asn1_visit_tree */ -+/*************************************/ -+#define ASN1_PRINT_NAME 1 -+#define ASN1_PRINT_NAME_TYPE 2 -+#define ASN1_PRINT_NAME_TYPE_VALUE 3 -+#define ASN1_PRINT_ALL 4 -+ -+/*****************************************/ -+/* Constants returned by asn1_read_tag */ -+/*****************************************/ -+#define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */ -+#define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */ -+#define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /* old: 3 */ -+#define ASN1_CLASS_PRIVATE 0xC0 /* old: 4 */ -+#define ASN1_CLASS_STRUCTURED 0x20 -+ -+/*****************************************/ -+/* Constants returned by asn1_read_tag */ -+/*****************************************/ -+#define ASN1_TAG_BOOLEAN 0x01 -+#define ASN1_TAG_INTEGER 0x02 -+#define ASN1_TAG_SEQUENCE 0x10 -+#define ASN1_TAG_SET 0x11 -+#define ASN1_TAG_OCTET_STRING 0x04 -+#define ASN1_TAG_BIT_STRING 0x03 -+#define ASN1_TAG_UTCTime 0x17 -+#define ASN1_TAG_GENERALIZEDTime 0x18 -+#define ASN1_TAG_OBJECT_ID 0x06 -+#define ASN1_TAG_ENUMERATED 0x0A -+#define ASN1_TAG_NULL 0x05 -+#define ASN1_TAG_GENERALSTRING 0x1B -+#define ASN1_TAG_NUMERIC_STRING 0x12 -+#define ASN1_TAG_IA5_STRING 0x16 -+#define ASN1_TAG_TELETEX_STRING 0x14 -+#define ASN1_TAG_PRINTABLE_STRING 0x13 -+#define ASN1_TAG_UNIVERSAL_STRING 0x1C -+#define ASN1_TAG_BMP_STRING 0x1E -+#define ASN1_TAG_UTF8_STRING 0x0C -+#define ASN1_TAG_VISIBLE_STRING 0x1A -+ -+/** -+ * asn1_node: -+ * -+ * Structure definition used for the node of the tree -+ * that represents an ASN.1 DEFINITION. -+ */ -+typedef struct asn1_node_st asn1_node_st; -+ -+typedef asn1_node_st *asn1_node; -+typedef const asn1_node_st *asn1_node_const; -+ -+/** -+ * ASN1_MAX_NAME_SIZE: -+ * -+ * Maximum number of characters of a name -+ * inside a file with ASN1 definitions. -+ */ -+#define ASN1_MAX_NAME_SIZE 64 -+ -+ -+/** -+ * asn1_static_node: -+ * @name: Node name -+ * @type: Node typ -+ * @value: Node value -+ * -+ * For the on-disk format of ASN.1 trees, created by asn1_parser2array(). -+ */ -+struct asn1_static_node_st -+{ -+ const char *name; /* Node name */ -+ unsigned int type; /* Node type */ -+ const void *value; /* Node value */ -+}; -+typedef struct asn1_static_node_st asn1_static_node; -+ -+/* List of constants for field type of node_asn */ -+#define ASN1_ETYPE_INVALID 0 -+#define ASN1_ETYPE_CONSTANT 1 -+#define ASN1_ETYPE_IDENTIFIER 2 -+#define ASN1_ETYPE_INTEGER 3 -+#define ASN1_ETYPE_BOOLEAN 4 -+#define ASN1_ETYPE_SEQUENCE 5 -+#define ASN1_ETYPE_BIT_STRING 6 -+#define ASN1_ETYPE_OCTET_STRING 7 -+#define ASN1_ETYPE_TAG 8 -+#define ASN1_ETYPE_DEFAULT 9 -+#define ASN1_ETYPE_SIZE 10 -+#define ASN1_ETYPE_SEQUENCE_OF 11 -+#define ASN1_ETYPE_OBJECT_ID 12 -+#define ASN1_ETYPE_ANY 13 -+#define ASN1_ETYPE_SET 14 -+#define ASN1_ETYPE_SET_OF 15 -+#define ASN1_ETYPE_DEFINITIONS 16 -+#define ASN1_ETYPE_CHOICE 18 -+#define ASN1_ETYPE_IMPORTS 19 -+#define ASN1_ETYPE_NULL 20 -+#define ASN1_ETYPE_ENUMERATED 21 -+#define ASN1_ETYPE_GENERALSTRING 27 -+#define ASN1_ETYPE_NUMERIC_STRING 28 -+#define ASN1_ETYPE_IA5_STRING 29 -+#define ASN1_ETYPE_TELETEX_STRING 30 -+#define ASN1_ETYPE_PRINTABLE_STRING 31 -+#define ASN1_ETYPE_UNIVERSAL_STRING 32 -+#define ASN1_ETYPE_BMP_STRING 33 -+#define ASN1_ETYPE_UTF8_STRING 34 -+#define ASN1_ETYPE_VISIBLE_STRING 35 -+#define ASN1_ETYPE_UTC_TIME 36 -+#define ASN1_ETYPE_GENERALIZED_TIME 37 -+ -+/** -+ * ASN1_DELETE_FLAG_ZEROIZE: -+ * -+ * Used by: asn1_delete_structure2() -+ * -+ * Zeroize values prior to deinitialization. -+ */ -+#define ASN1_DELETE_FLAG_ZEROIZE 1 -+ -+/** -+ * ASN1_DECODE_FLAG_ALLOW_PADDING: -+ * -+ * Used by: asn1_der_decoding2() -+ * -+ * This flag would allow arbitrary data past the DER data. -+ */ -+#define ASN1_DECODE_FLAG_ALLOW_PADDING 1 -+/** -+ * ASN1_DECODE_FLAG_STRICT_DER: -+ * -+ * Used by: asn1_der_decoding2() -+ * -+ * This flag would ensure that no BER decoding takes place. -+ */ -+#define ASN1_DECODE_FLAG_STRICT_DER (1<<1) -+/** -+ * ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME: -+ * -+ * Used by: asn1_der_decoding2() -+ * -+ * This flag will tolerate Time encoding errors when in strict DER. -+ */ -+#define ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME (1<<2) -+ -+ -+/** -+ * asn1_data_node_st: -+ * @name: Node name -+ * @value: Node value -+ * @value_len: Node value size -+ * @type: Node value type (ASN1_ETYPE_*) -+ * -+ * Data node inside a #asn1_node structure. -+ */ -+struct asn1_data_node_st -+{ -+ const char *name; /* Node name */ -+ const void *value; /* Node value */ -+ unsigned int value_len; /* Node value size */ -+ unsigned int type; /* Node value type (ASN1_ETYPE_*) */ -+}; -+typedef struct asn1_data_node_st asn1_data_node_st; -+ -+/***********************************/ -+/* Fixed constants */ -+/***********************************/ -+ -+/** -+ * ASN1_MAX_ERROR_DESCRIPTION_SIZE: -+ * -+ * Maximum number of characters -+ * of a description message -+ * (null character included). -+ */ -+#define ASN1_MAX_ERROR_DESCRIPTION_SIZE 128 -+ -+/***********************************/ -+/* Functions definitions */ -+/***********************************/ -+ -+extern ASN1_API int -+ asn1_parser2tree (const char *file, -+ asn1_node * definitions, char *error_desc); -+ -+extern ASN1_API int -+ asn1_parser2array (const char *inputFileName, -+ const char *outputFileName, -+ const char *vectorName, char *error_desc); -+ -+extern ASN1_API int -+ asn1_array2tree (const asn1_static_node * array, -+ asn1_node * definitions, char *errorDescription); -+ -+extern ASN1_API void -+ asn1_print_structure (FILE * out, asn1_node_const structure, -+ const char *name, int mode); -+ -+extern ASN1_API int -+ asn1_create_element (asn1_node_const definitions, -+ const char *source_name, asn1_node * element); -+ -+extern ASN1_API int asn1_delete_structure (asn1_node * structure); -+ -+extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, unsigned int flags); -+ -+extern ASN1_API int -+ asn1_delete_element (asn1_node structure, const char *element_name); -+ -+extern ASN1_API int -+ asn1_write_value (asn1_node node_root, const char *name, -+ const void *ivalue, int len); -+ -+extern ASN1_API int -+ asn1_read_value (asn1_node_const root, const char *name, -+ void *ivalue, int *len); -+ -+extern ASN1_API int -+ asn1_read_value_type (asn1_node_const root, const char *name, -+ void *ivalue, int *len, unsigned int *etype); -+ -+extern ASN1_API int -+ asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data); -+ -+extern ASN1_API int -+ asn1_number_of_elements (asn1_node_const element, const char *name, int *num); -+ -+extern ASN1_API int -+ asn1_der_coding (asn1_node_const element, const char *name, -+ void *ider, int *len, char *ErrorDescription); -+ -+extern ASN1_API int -+ asn1_der_decoding2 (asn1_node *element, const void *ider, -+ int *max_ider_len, unsigned int flags, -+ char *errorDescription); -+ -+extern ASN1_API int -+ asn1_der_decoding (asn1_node * element, const void *ider, -+ int ider_len, char *errorDescription); -+ -+/* Do not use. Use asn1_der_decoding() instead. */ -+extern ASN1_API int -+ asn1_der_decoding_element (asn1_node * structure, -+ const char *elementName, -+ const void *ider, int len, -+ char *errorDescription) _ASN1_GCC_ATTR_DEPRECATED; -+ -+extern ASN1_API int -+ asn1_der_decoding_startEnd (asn1_node element, -+ const void *ider, int ider_len, -+ const char *name_element, -+ int *start, int *end); -+ -+extern ASN1_API int -+ asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element); -+ -+extern ASN1_API int -+ asn1_expand_octet_string (asn1_node_const definitions, -+ asn1_node * element, -+ const char *octetName, const char *objectName); -+ -+extern ASN1_API int -+ asn1_read_tag (asn1_node_const root, const char *name, -+ int *tagValue, int *classValue); -+ -+extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const -+ definitions, -+ const char -+ *oidValue); -+ -+__LIBTASN1_PURE__ -+extern ASN1_API const char *asn1_check_version (const char *req_version); -+ -+__LIBTASN1_PURE__ -+extern ASN1_API const char *asn1_strerror (int error); -+ -+extern ASN1_API void asn1_perror (int error); -+ -+#define ASN1_MAX_TAG_SIZE 4 -+#define ASN1_MAX_LENGTH_SIZE 9 -+#define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE) -+extern ASN1_API long -+ asn1_get_length_der (const unsigned char *der, int der_len, int *len); -+ -+extern ASN1_API long -+ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len); -+ -+extern ASN1_API void -+ asn1_length_der (unsigned long int len, unsigned char *der, int *der_len); -+ -+/* Other utility functions. */ -+ -+extern ASN1_API -+ int asn1_decode_simple_der (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, -+ const unsigned char **str, -+ unsigned int *str_len); -+ -+extern ASN1_API -+ int asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, -+ unsigned char **str, -+ unsigned int *str_len, -+ unsigned int *ber_len); -+ -+extern ASN1_API int -+ asn1_encode_simple_der (unsigned int etype, const unsigned char *str, -+ unsigned int str_len, unsigned char *tl, -+ unsigned int *tl_len); -+ -+extern ASN1_API asn1_node -+ asn1_find_node (asn1_node_const pointer, const char *name); -+ -+extern ASN1_API int -+ asn1_copy_node (asn1_node dst, const char *dst_name, -+ asn1_node_const src, const char *src_name); -+extern ASN1_API asn1_node -+ asn1_dup_node (asn1_node_const src, const char *src_name); -+ -+/* Internal and low-level DER utility functions. */ -+ -+extern ASN1_API int -+ asn1_get_tag_der (const unsigned char *der, int der_len, -+ unsigned char *cls, int *len, unsigned long *tag); -+ -+extern ASN1_API void -+ asn1_octet_der (const unsigned char *str, int str_len, -+ unsigned char *der, int *der_len); -+ -+extern ASN1_API int -+ asn1_get_octet_der (const unsigned char *der, int der_len, -+ int *ret_len, unsigned char *str, -+ int str_size, int *str_len); -+ -+extern ASN1_API void asn1_bit_der (const unsigned char *str, int bit_len, -+ unsigned char *der, int *der_len); -+ -+extern ASN1_API int -+ asn1_get_bit_der (const unsigned char *der, int der_len, -+ int *ret_len, unsigned char *str, -+ int str_size, int *bit_len); -+ -+extern ASN1_API int -+ asn1_get_object_id_der (const unsigned char *der, -+ int der_len, int *ret_len, -+ char *str, int str_size); -+ -+extern ASN1_API int -+ asn1_object_id_der (const char *str, unsigned char *der, int *der_len, -+ unsigned flags); -+ -+/* Compatibility types */ -+ -+/** -+ * asn1_retCode: -+ * -+ * Type formerly returned by libtasn1 functions. -+ * -+ * Deprecated: 3.0: Use int instead. -+ */ -+typedef int asn1_retCode; -+ -+/** -+ * node_asn_struct: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use #asn1_node instead. -+ */ -+#define node_asn_struct asn1_node_st -+ -+/** -+ * node_asn: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use #asn1_node instead. -+ */ -+#define node_asn asn1_node_st -+ -+/** -+ * ASN1_TYPE: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use #asn1_node instead. -+ */ -+#define ASN1_TYPE asn1_node -+ -+/** -+ * ASN1_TYPE_EMPTY: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use NULL instead. -+ */ -+#define ASN1_TYPE_EMPTY NULL -+ -+/** -+ * static_struct_asn: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use #asn1_static_node instead. -+ */ -+#define static_struct_asn asn1_static_node_st -+ -+/** -+ * ASN1_ARRAY_TYPE: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use #asn1_static_node instead. -+ */ -+#define ASN1_ARRAY_TYPE asn1_static_node -+ -+/** -+ * asn1_static_node_t: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use #asn1_static_node instead. -+ */ -+#define asn1_static_node_t asn1_static_node -+ -+/** -+ * node_data_struct: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use #asn1_data_node_st instead. -+ */ -+#define node_data_struct asn1_data_node_st -+ -+/** -+ * ASN1_DATA_NODE: -+ * -+ * Compat #define. -+ * -+ * Deprecated: 3.0: Use #asn1_data_node_st instead. -+ */ -+#define ASN1_DATA_NODE asn1_data_node_st -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* LIBTASN1_H */ -diff --git a/grub-core/lib/libtasn1/LICENSE b/grub-core/lib/libtasn1/LICENSE -new file mode 100644 -index 00000000000..e8b3628db9b ---- /dev/null -+++ b/grub-core/lib/libtasn1/LICENSE -@@ -0,0 +1,16 @@ -+LICENSING -+========= -+ -+The libtasn1 library is released under the GNU Lesser General Public -+License (LGPL) version 2.1 or later; see [COPYING.LESSER](doc/COPYING.LESSER) -+for the license terms. -+ -+The GNU LGPL applies to the main libtasn1 library, while the -+included applications library are under the GNU GPL version 3. -+The libtasn1 library is located in the lib directory, while the applications -+in src/. -+ -+The documentation in doc/ is under the GNU FDL license 1.3. -+ -+For any copyright year range specified as YYYY-ZZZZ in this package -+note that the range specifies every single year in that closed interval. -diff --git a/grub-core/lib/libtasn1/README.md b/grub-core/lib/libtasn1/README.md -new file mode 100644 -index 00000000000..50a8642296c ---- /dev/null -+++ b/grub-core/lib/libtasn1/README.md -@@ -0,0 +1,91 @@ -+|Branch|CI system|Status| -+|:----:|:-------:|-----:| -+|Master|Gitlab|[![build status](https://gitlab.com/gnutls/libtasn1/badges/master/pipeline.svg)](https://gitlab.com/gnutls/libtasn1/commits/master)[![coverage report](https://gitlab.com/gnutls/libtasn1/badges/master/coverage.svg)](https://gnutls.gitlab.io/libtasn1/coverage)| -+ -+# libtasn1 -+ -+This is GNU Libtasn1, a small ASN.1 library. -+ -+The C library (libtasn1.*) is licensed under the GNU Lesser General -+Public License version 2.1 or later. See the file COPYING.LIB. -+ -+The command line tool, self tests, examples, and other auxilliary -+files, are licensed under the GNU General Public License version 3.0 -+or later. See the file COPYING. -+ -+## Building the library -+ -+We require several tools to build the software, including: -+ -+* [Make](https://www.gnu.org/software/make/) -+* [Automake](https://www.gnu.org/software/automake/) (use 1.11.3 or later) -+* [Autoconf](https://www.gnu.org/software/autoconf/) -+* [Libtool](https://www.gnu.org/software/libtool/) -+* [Texinfo](https://www.gnu.org/software/texinfo/) -+* [help2man](http://www.gnu.org/software/help2man/) -+* [Tar](https://www.gnu.org/software/tar/) -+* [Gzip](https://www.gnu.org/software/gzip/) -+* [bison](https://www.gnu.org/software/bison/) -+* [Texlive & epsf](https://www.tug.org/texlive/) (for PDF manual) -+* [GTK-DOC](https://www.gtk.org/gtk-doc/) (for API manual) -+* [Git](https://git-scm.com/) -+* [libabigail](https://pagure.io/libabigail/) (for abi comparison in make dist) -+* [Valgrind](https://valgrind.org/) (optional) -+ -+The required software is typically distributed with your operating -+system, and the instructions for installing them differ. Here are -+some hints: -+ -+gNewSense/Debian/Ubuntu: -+``` -+sudo apt-get install make git-core autoconf automake libtool -+sudo apt-get install texinfo texlive texlive-generic-recommended texlive-extra-utils -+sudo apt-get install help2man gtk-doc-tools valgrind abigail-tools -+``` -+ -+The next step is to run autoreconf, ./configure, etc: -+ -+``` -+$ ./bootstrap -+``` -+ -+Then build the project normally: -+ -+``` -+$ make -+$ make check -+``` -+ -+Happy hacking! -+ -+ -+## Manual -+ -+The manual is in the `doc/` directory of the release. You can also browse -+the manual online at: -+ -+ - https://gnutls.gitlab.io/libtasn1/ -+ -+ -+## Code coverage report -+ -+The coverage report is at: -+ -+ - https://gnutls.gitlab.io/libtasn1/coverage -+ -+ -+## Issue trackers -+ -+ - [Main issue tracker](https://gitlab.com/gnutls/libtasn1/issues) -+ - [oss-fuzz found issues](https://bugs.chromium.org/p/oss-fuzz/issues/list?q=libtasn1&can=2) -+ -+ -+## Homepage -+ -+The project homepage at the gnu site is at: -+ -+http://www.gnu.org/software/libtasn1/ -+ -+ -+For any copyright year range specified as YYYY-ZZZZ in this package -+note that the range specifies every single year in that closed interval. diff --git a/0170-libtasn1-disable-code-not-needed-in-grub.patch b/0170-libtasn1-disable-code-not-needed-in-grub.patch deleted file mode 100644 index 00f5588..0000000 --- a/0170-libtasn1-disable-code-not-needed-in-grub.patch +++ /dev/null @@ -1,307 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 1 May 2020 17:12:23 +1000 -Subject: [PATCH] libtasn1: disable code not needed in grub - -We don't expect to be able to write ASN.1, only read it, -so we can disable some code. - -Do that with #if 0/#endif, rather than deletion. This means -that the difference between upstream and grub is smaller, -which should make updating libtasn1 easier in the future. - -With these exclusions we also avoid the need for minmax.h, -which is convenient because it means we don't have to -import it from gnulib. - -Signed-off-by: Daniel Axtens ---- - grub-core/lib/libtasn1/lib/coding.c | 12 ++++++++++-- - grub-core/lib/libtasn1/lib/decoding.c | 2 ++ - grub-core/lib/libtasn1/lib/element.c | 4 ++-- - grub-core/lib/libtasn1/lib/errors.c | 3 +++ - grub-core/lib/libtasn1/lib/structure.c | 10 ++++++---- - include/grub/libtasn1.h | 15 +++++++++++++++ - 6 files changed, 38 insertions(+), 8 deletions(-) - -diff --git a/grub-core/lib/libtasn1/lib/coding.c b/grub-core/lib/libtasn1/lib/coding.c -index 245ea64cf0a..52def598368 100644 ---- a/grub-core/lib/libtasn1/lib/coding.c -+++ b/grub-core/lib/libtasn1/lib/coding.c -@@ -30,11 +30,11 @@ - #include "parser_aux.h" - #include - #include "element.h" --#include "minmax.h" - #include - - #define MAX_TAG_LEN 16 - -+#if 0 - /******************************************************/ - /* Function : _asn1_error_description_value_not_found */ - /* Description: creates the ErrorDescription string */ -@@ -58,6 +58,7 @@ _asn1_error_description_value_not_found (asn1_node node, - Estrcat (ErrorDescription, "' not found"); - - } -+#endif - - /** - * asn1_length_der: -@@ -244,6 +245,7 @@ asn1_encode_simple_der (unsigned int etype, const unsigned char *str, - return ASN1_SUCCESS; - } - -+#if 0 - /******************************************************/ - /* Function : _asn1_time_der */ - /* Description: creates the DER coding for a TIME */ -@@ -281,7 +283,7 @@ _asn1_time_der (unsigned char *str, int str_len, unsigned char *der, - - return ASN1_SUCCESS; - } -- -+#endif - - /* - void -@@ -520,6 +522,7 @@ asn1_bit_der (const unsigned char *str, int bit_len, - } - - -+#if 0 - /******************************************************/ - /* Function : _asn1_complete_explicit_tag */ - /* Description: add the length coding to the EXPLICIT */ -@@ -596,6 +599,7 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char *der, - - return ASN1_SUCCESS; - } -+#endif - - const tag_and_class_st _asn1_tags[] = { - [ASN1_ETYPE_GENERALSTRING] = -@@ -648,6 +652,8 @@ const tag_and_class_st _asn1_tags[] = { - - unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]); - -+ -+#if 0 - /******************************************************/ - /* Function : _asn1_insert_tag_der */ - /* Description: creates the DER coding of tags of one */ -@@ -1413,3 +1419,5 @@ error: - asn1_delete_structure (&node); - return err; - } -+ -+#endif -\ No newline at end of file -diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c -index ff04eb778cb..42f9a92b5d4 100644 ---- a/grub-core/lib/libtasn1/lib/decoding.c -+++ b/grub-core/lib/libtasn1/lib/decoding.c -@@ -1613,6 +1613,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, - return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription); - } - -+#if 0 - /** - * asn1_der_decoding_element: - * @structure: pointer to an ASN1 structure -@@ -1643,6 +1644,7 @@ asn1_der_decoding_element (asn1_node * structure, const char *elementName, - { - return asn1_der_decoding(structure, ider, len, errorDescription); - } -+#endif - - /** - * asn1_der_decoding_startEnd: -diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c -index 997eb2725dc..539008d8e94 100644 ---- a/grub-core/lib/libtasn1/lib/element.c -+++ b/grub-core/lib/libtasn1/lib/element.c -@@ -191,7 +191,7 @@ _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache) - return ASN1_SUCCESS; - } - -- -+#if 0 - /** - * asn1_write_value: - * @node_root: pointer to a structure -@@ -645,7 +645,7 @@ asn1_write_value (asn1_node node_root, const char *name, - - return ASN1_SUCCESS; - } -- -+#endif - - #define PUT_VALUE( ptr, ptr_size, data, data_size) \ - *len = data_size; \ -diff --git a/grub-core/lib/libtasn1/lib/errors.c b/grub-core/lib/libtasn1/lib/errors.c -index cee74daf795..42785e8622b 100644 ---- a/grub-core/lib/libtasn1/lib/errors.c -+++ b/grub-core/lib/libtasn1/lib/errors.c -@@ -57,6 +57,8 @@ static const libtasn1_error_entry error_algorithms[] = { - {0, 0} - }; - -+ -+#if 0 - /** - * asn1_perror: - * @error: is an error returned by a libtasn1 function. -@@ -73,6 +75,7 @@ asn1_perror (int error) - const char *str = asn1_strerror (error); - fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)"); - } -+#endif - - /** - * asn1_strerror: -diff --git a/grub-core/lib/libtasn1/lib/structure.c b/grub-core/lib/libtasn1/lib/structure.c -index 8189c56a4c9..fcfde01a393 100644 ---- a/grub-core/lib/libtasn1/lib/structure.c -+++ b/grub-core/lib/libtasn1/lib/structure.c -@@ -76,7 +76,7 @@ _asn1_find_left (asn1_node_const node) - return node->left; - } - -- -+#if 0 - int - _asn1_create_static_structure (asn1_node_const pointer, char *output_file_name, - char *vector_name) -@@ -155,7 +155,7 @@ _asn1_create_static_structure (asn1_node_const pointer, char *output_file_name, - - return ASN1_SUCCESS; - } -- -+#endif - - /** - * asn1_array2tree: -@@ -718,7 +718,7 @@ asn1_create_element (asn1_node_const definitions, const char *source_name, - return res; - } - -- -+#if 0 - /** - * asn1_print_structure: - * @out: pointer to the output file (e.g. stdout). -@@ -1058,7 +1058,7 @@ asn1_print_structure (FILE * out, asn1_node_const structure, const char *name, - } - } - } -- -+#endif - - - /** -@@ -1153,6 +1153,7 @@ asn1_find_structure_from_oid (asn1_node_const definitions, const char *oidValue) - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ - } - -+#if 0 - /** - * asn1_copy_node: - * @dst: Destination asn1 node. -@@ -1202,6 +1203,7 @@ asn1_copy_node (asn1_node dst, const char *dst_name, - - return result; - } -+#endif - - /** - * asn1_dup_node: -diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h -index 6fd7a30dc35..785eda2ae3f 100644 ---- a/include/grub/libtasn1.h -+++ b/include/grub/libtasn1.h -@@ -319,6 +319,8 @@ typedef struct asn1_data_node_st asn1_data_node_st; - /* Functions definitions */ - /***********************************/ - -+/* These functions are not used in grub and should not be referenced. */ -+#if 0 - extern ASN1_API int - asn1_parser2tree (const char *file, - asn1_node * definitions, char *error_desc); -@@ -327,14 +329,17 @@ extern ASN1_API int - asn1_parser2array (const char *inputFileName, - const char *outputFileName, - const char *vectorName, char *error_desc); -+#endif - - extern ASN1_API int - asn1_array2tree (const asn1_static_node * array, - asn1_node * definitions, char *errorDescription); - -+#if 0 - extern ASN1_API void - asn1_print_structure (FILE * out, asn1_node_const structure, - const char *name, int mode); -+#endif - - extern ASN1_API int - asn1_create_element (asn1_node_const definitions, -@@ -347,9 +352,11 @@ extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, unsigned int - extern ASN1_API int - asn1_delete_element (asn1_node structure, const char *element_name); - -+#if 0 - extern ASN1_API int - asn1_write_value (asn1_node node_root, const char *name, - const void *ivalue, int len); -+#endif - - extern ASN1_API int - asn1_read_value (asn1_node_const root, const char *name, -@@ -365,9 +372,11 @@ extern ASN1_API int - extern ASN1_API int - asn1_number_of_elements (asn1_node_const element, const char *name, int *num); - -+#if 0 - extern ASN1_API int - asn1_der_coding (asn1_node_const element, const char *name, - void *ider, int *len, char *ErrorDescription); -+#endif - - extern ASN1_API int - asn1_der_decoding2 (asn1_node *element, const void *ider, -@@ -378,12 +387,14 @@ extern ASN1_API int - asn1_der_decoding (asn1_node * element, const void *ider, - int ider_len, char *errorDescription); - -+#if 0 - /* Do not use. Use asn1_der_decoding() instead. */ - extern ASN1_API int - asn1_der_decoding_element (asn1_node * structure, - const char *elementName, - const void *ider, int len, - char *errorDescription) _ASN1_GCC_ATTR_DEPRECATED; -+#endif - - extern ASN1_API int - asn1_der_decoding_startEnd (asn1_node element, -@@ -408,13 +419,17 @@ extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const - const char - *oidValue); - -+#if 0 - __LIBTASN1_PURE__ - extern ASN1_API const char *asn1_check_version (const char *req_version); -+#endif - - __LIBTASN1_PURE__ - extern ASN1_API const char *asn1_strerror (int error); - -+#if 0 - extern ASN1_API void asn1_perror (int error); -+#endif - - #define ASN1_MAX_TAG_SIZE 4 - #define ASN1_MAX_LENGTH_SIZE 9 diff --git a/0171-libtasn1-changes-for-grub-compatibility.patch b/0171-libtasn1-changes-for-grub-compatibility.patch deleted file mode 100644 index 9b2275c..0000000 --- a/0171-libtasn1-changes-for-grub-compatibility.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 1 May 2020 20:44:29 +1000 -Subject: [PATCH] libtasn1: changes for grub compatibility - -Do a few things to make libtasn1 compile as part of grub: - - - replace strcat. grub removed strcat so replace it with the appropriate - calls to memcpy and strlen. - - - replace c_isdigit with grub_isdigit (and don't import c-ctype from - gnulib) grub_isdigit provides the same functionality as c_isdigit: it - determines if the input is an ASCII digit without regard for locale. - - - replace GL_ATTRIBUTE_PURE with __attribute__((pure)) which been - supported since gcc-2.96. This avoids messing around with gnulib. - - - adjust libtasn1.h: drop the ASN1_API logic, it's not needed for our - modules. Unconditionally support const and pure attributes and adjust - header paths. - - - adjust header paths to "grub/libtasn1.h". - - - replace a 64 bit division with a call to grub_divmod64, preventing - creation of __udivdi3 calls on 32 bit platforms. - -Signed-off-by: Daniel Axtens ---- - grub-core/lib/libtasn1/lib/decoding.c | 11 ++++++----- - grub-core/lib/libtasn1/lib/element.c | 3 ++- - grub-core/lib/libtasn1/lib/gstr.c | 4 ++-- - grub-core/lib/libtasn1/lib/parser_aux.c | 7 ++++--- - grub-core/lib/libtasn1/lib/int.h | 4 ++-- - include/grub/libtasn1.h | 26 ++++++-------------------- - 6 files changed, 22 insertions(+), 33 deletions(-) - -diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c -index 42f9a92b5d4..7856858b272 100644 ---- a/grub-core/lib/libtasn1/lib/decoding.c -+++ b/grub-core/lib/libtasn1/lib/decoding.c -@@ -32,7 +32,8 @@ - #include - #include - #include --#include -+ -+#define c_isdigit grub_isdigit - - #ifdef DEBUG - # define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__) -@@ -2008,8 +2009,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, - (p2->type & CONST_ASSIGN)) - { - strcpy (name, definitions->name); -- strcat (name, "."); -- strcat (name, p2->name); -+ memcpy (name + strlen(name), ".", sizeof(" . ")); -+ memcpy (name + strlen(name), p2->name, strlen(p2->name) + 1); - - len = sizeof (value); - result = asn1_read_value (definitions, name, value, &len); -@@ -2026,8 +2027,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, - if (p2) - { - strcpy (name, definitions->name); -- strcat (name, "."); -- strcat (name, p2->name); -+ memcpy (name + strlen(name), ".", sizeof(" . ")); -+ memcpy (name + strlen(name), p2->name, strlen(p2->name) + 1); - - result = asn1_create_element (definitions, name, &aux); - if (result == ASN1_SUCCESS) -diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c -index 539008d8e94..ed761ff56bd 100644 ---- a/grub-core/lib/libtasn1/lib/element.c -+++ b/grub-core/lib/libtasn1/lib/element.c -@@ -30,9 +30,10 @@ - #include "parser_aux.h" - #include - #include "structure.h" --#include "c-ctype.h" - #include "element.h" - -+#define c_isdigit grub_isdigit -+ - void - _asn1_hierarchical_name (asn1_node_const node, char *name, int name_size) - { -diff --git a/grub-core/lib/libtasn1/lib/gstr.c b/grub-core/lib/libtasn1/lib/gstr.c -index e91a3a151c0..e33875c2c7c 100644 ---- a/grub-core/lib/libtasn1/lib/gstr.c -+++ b/grub-core/lib/libtasn1/lib/gstr.c -@@ -36,13 +36,13 @@ _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) - - if (dest_tot_size - dest_size > str_size) - { -- strcat (dest, src); -+ memcpy (dest + dest_size, src, str_size + 1); - } - else - { - if (dest_tot_size - dest_size > 0) - { -- strncat (dest, src, (dest_tot_size - dest_size) - 1); -+ memcpy (dest + dest_size, src, (dest_tot_size - dest_size) - 1); - dest[dest_tot_size - 1] = 0; - } - } -diff --git a/grub-core/lib/libtasn1/lib/parser_aux.c b/grub-core/lib/libtasn1/lib/parser_aux.c -index d5dbbf8765d..89c9be69dc2 100644 ---- a/grub-core/lib/libtasn1/lib/parser_aux.c -+++ b/grub-core/lib/libtasn1/lib/parser_aux.c -@@ -26,7 +26,8 @@ - #include "gstr.h" - #include "structure.h" - #include "element.h" --#include "c-ctype.h" -+ -+#define c_isdigit grub_isdigit - - char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */ - -@@ -40,7 +41,7 @@ char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not fou - #ifdef __clang__ - __attribute__((no_sanitize("integer"))) - #endif --_GL_ATTRIBUTE_PURE -+__attribute__((__pure__)) - static unsigned int - _asn1_hash_name (const char *x) - { -@@ -634,7 +635,7 @@ _asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]) - count = 0; - do - { -- d = val / 10; -+ d = grub_divmod64(val, 10, NULL); - r = val - d * 10; - temp[start + count] = '0' + (char) r; - count++; -diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h -index ea1625786c1..4a568efee9c 100644 ---- a/grub-core/lib/libtasn1/lib/int.h -+++ b/grub-core/lib/libtasn1/lib/int.h -@@ -35,7 +35,7 @@ - #include - #endif - --#include -+#include "grub/libtasn1.h" - - #define ASN1_SMALL_VALUE_SIZE 16 - -@@ -115,7 +115,7 @@ extern const tag_and_class_st _asn1_tags[]; - #define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) - #define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) - #define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) --#define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) -+#define _asn1_strcat(a,b) memcpy((char *)a + strlen((const char *)a), (const char *)b, strlen((const char *)b) + 1) - - #if SIZEOF_UNSIGNED_LONG_INT == 8 - # define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) -diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h -index 785eda2ae3f..28dbf16c4e0 100644 ---- a/include/grub/libtasn1.h -+++ b/include/grub/libtasn1.h -@@ -38,29 +38,15 @@ - #ifndef LIBTASN1_H - #define LIBTASN1_H - --#ifndef ASN1_API --#if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY --#define ASN1_API __attribute__((__visibility__("default"))) --#elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC --#define ASN1_API __declspec(dllexport) --#elif defined _MSC_VER && ! defined ASN1_STATIC --#define ASN1_API __declspec(dllimport) --#else -+/* grub: ASN1_API is not used */ - #define ASN1_API --#endif --#endif - --#ifdef __GNUC__ --# define __LIBTASN1_CONST__ __attribute__((const)) --# define __LIBTASN1_PURE__ __attribute__((pure)) --#else --# define __LIBTASN1_CONST__ --# define __LIBTASN1_PURE__ --#endif -+/* grub: all our supported compilers support these attributes */ -+#define __LIBTASN1_CONST__ __attribute__((const)) -+#define __LIBTASN1_PURE__ __attribute__((pure)) - --#include --#include --#include /* for FILE* */ -+#include -+#include - - #ifdef __cplusplus - extern "C" diff --git a/0172-libtasn1-compile-into-asn1-module.patch b/0172-libtasn1-compile-into-asn1-module.patch deleted file mode 100644 index 67be4e8..0000000 --- a/0172-libtasn1-compile-into-asn1-module.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 5 Jun 2020 17:47:25 +1000 -Subject: [PATCH] libtasn1: compile into asn1 module - -Create a wrapper file that specifies the module license. -Set up the makefile so it is built. - -Signed-off-by: Daniel Axtens ---- - grub-core/Makefile.core.def | 15 +++++++++++++++ - grub-core/lib/libtasn1_wrap/wrap.c | 26 ++++++++++++++++++++++++++ - 2 files changed, 41 insertions(+) - create mode 100644 grub-core/lib/libtasn1_wrap/wrap.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 97347ae76f9..21d2c541850 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2576,3 +2576,18 @@ module = { - common = commands/i386/wrmsr.c; - enable = x86; - }; -+ -+module = { -+ name = asn1; -+ common = lib/libtasn1/lib/decoding.c; -+ common = lib/libtasn1/lib/coding.c; -+ common = lib/libtasn1/lib/element.c; -+ common = lib/libtasn1/lib/structure.c; -+ common = lib/libtasn1/lib/parser_aux.c; -+ common = lib/libtasn1/lib/gstr.c; -+ common = lib/libtasn1/lib/errors.c; -+ common = lib/libtasn1_wrap/wrap.c; -+ cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; -+ // -Wno-type-limits comes from libtasn1's configure.ac -+ cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1/lib -Wno-type-limits'; -+}; -diff --git a/grub-core/lib/libtasn1_wrap/wrap.c b/grub-core/lib/libtasn1_wrap/wrap.c -new file mode 100644 -index 00000000000..622ba942e33 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/wrap.c -@@ -0,0 +1,26 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+ -+/* -+ * libtasn1 is provided under LGPL2.1+, which is compatible -+ * with GPL3+. As Grub as a whole is under GPL3+, this module -+ * is therefore under GPL3+ also. -+ */ -+GRUB_MOD_LICENSE ("GPLv3+"); diff --git a/0173-test_asn1-test-module-for-libtasn1.patch b/0173-test_asn1-test-module-for-libtasn1.patch deleted file mode 100644 index b659558..0000000 --- a/0173-test_asn1-test-module-for-libtasn1.patch +++ /dev/null @@ -1,1457 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 10 Jun 2020 17:48:42 +1000 -Subject: [PATCH] test_asn1: test module for libtasn1 - -Import tests from libtasn1 that don't use functionality we don't -import. I have put them here rather than in the libtasn1 directory -because: - - - They need much more significant changes to run in the grub - context. - - - I don't expect they will need to be changed when updating - libtasn1: I expect the old tests will usually continue to pass on - new versions. - -This doesn't test the full decoder but that will be exercised in -test suites for coming patch sets. - -Signed-off-by: Daniel Axtens ---- - Makefile.util.def | 6 + - grub-core/Makefile.core.def | 13 ++ - .../lib/libtasn1_wrap/tests/CVE-2018-1000654.c | 61 ++++++ - grub-core/lib/libtasn1_wrap/tests/Test_overflow.c | 138 ++++++++++++++ - grub-core/lib/libtasn1_wrap/tests/Test_simple.c | 207 ++++++++++++++++++++ - grub-core/lib/libtasn1_wrap/tests/Test_strings.c | 150 +++++++++++++++ - .../lib/libtasn1_wrap/tests/object-id-decoding.c | 116 +++++++++++ - .../lib/libtasn1_wrap/tests/object-id-encoding.c | 120 ++++++++++++ - grub-core/lib/libtasn1_wrap/tests/octet-string.c | 211 +++++++++++++++++++++ - grub-core/lib/libtasn1_wrap/tests/reproducers.c | 81 ++++++++ - grub-core/lib/libtasn1_wrap/wrap_tests.c | 75 ++++++++ - .../tests/CVE-2018-1000654-1_asn1_tab.h | 32 ++++ - .../tests/CVE-2018-1000654-2_asn1_tab.h | 36 ++++ - grub-core/lib/libtasn1_wrap/wrap_tests.h | 38 ++++ - .gitignore | 1 + - tests/test_asn1.in | 12 ++ - 16 files changed, 1297 insertions(+) - create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_overflow.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_simple.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_strings.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/octet-string.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/reproducers.c - create mode 100644 grub-core/lib/libtasn1_wrap/wrap_tests.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h - create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h - create mode 100644 grub-core/lib/libtasn1_wrap/wrap_tests.h - create mode 100644 tests/test_asn1.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 9927c2cfd6a..3f191aa8095 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -1306,6 +1306,12 @@ script = { - common = tests/syslinux_test.in; - }; - -+script = { -+ testcase; -+ name = test_asn1; -+ common = tests/test_asn1.in; -+}; -+ - program = { - testcase; - name = example_unit_test; -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 21d2c541850..b4aaccf7b57 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2591,3 +2591,16 @@ module = { - // -Wno-type-limits comes from libtasn1's configure.ac - cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1/lib -Wno-type-limits'; - }; -+ -+module = { -+ name = test_asn1; -+ common = lib/libtasn1_wrap/tests/CVE-2018-1000654.c; -+ common = lib/libtasn1_wrap/tests/object-id-decoding.c; -+ common = lib/libtasn1_wrap/tests/object-id-encoding.c; -+ common = lib/libtasn1_wrap/tests/octet-string.c; -+ common = lib/libtasn1_wrap/tests/reproducers.c; -+ common = lib/libtasn1_wrap/tests/Test_overflow.c; -+ common = lib/libtasn1_wrap/tests/Test_simple.c; -+ common = lib/libtasn1_wrap/tests/Test_strings.c; -+ common = lib/libtasn1_wrap/wrap_tests.c; -+}; -diff --git a/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c -new file mode 100644 -index 00000000000..534e304521e ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2002-2018 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+ -+/****************************************************************/ -+/* Description: reproducer for CVE-2018-1000654 */ -+/****************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include "../wrap_tests.h" -+ -+#include "CVE-2018-1000654-1_asn1_tab.h" -+#include "CVE-2018-1000654-2_asn1_tab.h" -+ -+void -+test_CVE_2018_1000654 (void) -+{ -+ int result; -+ asn1_node definitions = NULL; -+ char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; -+ -+ result = asn1_array2tree (CVE_2018_1000654_1_asn1_tab, &definitions, errorDescription); -+ if (result != ASN1_RECURSION) -+ { -+ grub_fatal ("Error: %s\nErrorDescription = %s\n\n", -+ asn1_strerror (result), errorDescription); -+ return; -+ } -+ -+ asn1_delete_structure (&definitions); -+ -+ result = asn1_array2tree (CVE_2018_1000654_2_asn1_tab, &definitions, errorDescription); -+ if (result != ASN1_RECURSION) -+ { -+ grub_fatal ("Error: %s\nErrorDescription = %s\n\n", -+ asn1_strerror (result), errorDescription); -+ return; -+ } -+ -+ asn1_delete_structure (&definitions); -+} -diff --git a/grub-core/lib/libtasn1_wrap/tests/Test_overflow.c b/grub-core/lib/libtasn1_wrap/tests/Test_overflow.c -new file mode 100644 -index 00000000000..f48aea0ef8b ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/Test_overflow.c -@@ -0,0 +1,138 @@ -+/* -+ * Copyright (C) 2012-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+ -+/* Written by Simon Josefsson */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "../wrap_tests.h" -+ -+void -+test_overflow(void) -+{ -+ /* Test that values larger than long are rejected. This has worked -+ fine with all versions of libtasn1. */ -+ -+ { -+ unsigned char der[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; -+ long l; -+ int len; -+ -+ l = asn1_get_length_der (der, sizeof der, &len); -+ -+ if (l != -2L) -+ { -+ grub_fatal ("ERROR: asn1_get_length_der bignum (l %ld len %d)\n", l, len); -+ return; -+ } -+ } -+ -+ /* Test that values larger than int but smaller than long are -+ rejected. This limitation was introduced with libtasn1 2.12. */ -+#if (GRUB_LONG_MAX > GRUB_INT_MAX) -+ { -+ unsigned long num = ((long) GRUB_UINT_MAX) << 2; -+ unsigned char der[20]; -+ int der_len; -+ long l; -+ int len; -+ -+ asn1_length_der (num, der, &der_len); -+ -+ l = asn1_get_length_der (der, der_len, &len); -+ -+ if (l != -2L) -+ { -+ grub_fatal ("ERROR: asn1_get_length_der intnum (l %ld len %d)\n", l, -+ len); -+ return; -+ } -+ } -+#endif -+ -+ /* Test that values larger than would fit in the input string are -+ rejected. This problem was fixed in libtasn1 2.12. */ -+ { -+ unsigned long num = 64; -+ unsigned char der[20]; -+ int der_len; -+ long l; -+ int len; -+ -+ asn1_length_der (num, der, &der_len); -+ -+ der_len = sizeof (der); -+ l = asn1_get_length_der (der, der_len, &len); -+ -+ if (l != -4L) -+ { -+ grub_fatal ("ERROR: asn1_get_length_der overflow-small (l %ld len %d)\n", -+ l, len); -+ return; -+ } -+ } -+ -+ /* Test that values larger than would fit in the input string are -+ rejected. This problem was fixed in libtasn1 2.12. */ -+ { -+ unsigned long num = 1073741824; -+ unsigned char der[20]; -+ int der_len; -+ long l; -+ int len; -+ -+ asn1_length_der (num, der, &der_len); -+ -+ der_len = sizeof (der); -+ l = asn1_get_length_der (der, der_len, &len); -+ -+ if (l != -4L) -+ { -+ grub_fatal ("ERROR: asn1_get_length_der overflow-large1 (l %ld len %d)\n", -+ l, len); -+ return; -+ } -+ } -+ -+ /* Test that values larger than would fit in the input string are -+ rejected. This problem was fixed in libtasn1 2.12. */ -+ { -+ unsigned long num = 2147483649; -+ unsigned char der[20]; -+ int der_len; -+ long l; -+ int len; -+ -+ asn1_length_der (num, der, &der_len); -+ -+ der_len = sizeof (der); -+ l = asn1_get_length_der (der, der_len, &len); -+ -+ if (l != -2L) -+ { -+ grub_fatal ("ERROR: asn1_get_length_der overflow-large2 (l %ld len %d)\n", -+ l, len); -+ return; -+ } -+ } -+} -diff --git a/grub-core/lib/libtasn1_wrap/tests/Test_simple.c b/grub-core/lib/libtasn1_wrap/tests/Test_simple.c -new file mode 100644 -index 00000000000..9f01006ddf4 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/Test_simple.c -@@ -0,0 +1,207 @@ -+/* -+ * Copyright (C) 2011-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ * Written by Simon Josefsson -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include "../wrap_tests.h" -+ -+struct tv -+{ -+ int bitlen; -+ const char *bitstr; -+ int derlen; -+ const char *der; -+}; -+ -+static const struct tv tv[] = { -+ {0, "", 2, "\x01\x00"}, -+ {1, "\x00", 3, "\x02\x07\x00"}, -+ {2, "\x00", 3, "\x02\x06\x00"}, -+ {3, "\x00", 3, "\x02\x05\x00"}, -+ {4, "\x00", 3, "\x02\x04\x00"}, -+ {5, "\x00", 3, "\x02\x03\x00"}, -+ {6, "\x00", 3, "\x02\x02\x00"}, -+ {7, "\x00", 3, "\x02\x01\x00"}, -+ {8, "\x00\x00", 3, "\x02\x00\x00"}, -+ {9, "\x00\x00", 4, "\x03\x07\x00\x00"}, -+ {10, "\x00\x00", 4, "\x03\x06\x00\x00"}, -+ {11, "\x00\x00", 4, "\x03\x05\x00\x00"}, -+ {12, "\x00\x00", 4, "\x03\x04\x00\x00"}, -+ {13, "\x00\x00", 4, "\x03\x03\x00\x00"}, -+ {14, "\x00\x00", 4, "\x03\x02\x00\x00"}, -+ {15, "\x00\x00", 4, "\x03\x01\x00\x00"}, -+ {16, "\x00\x00", 4, "\x03\x00\x00\x00"}, -+ {17, "\x00\x00\x00", 5, "\x04\x07\x00\x00\x00"}, -+ {18, "\x00\x00\x00", 5, "\x04\x06\x00\x00\x00"}, -+ {19, "\x00\x00\x00", 5, "\x04\x05\x00\x00\x00"}, -+ {1, "\xFF", 3, "\x02\x07\x80"}, -+ {2, "\xFF", 3, "\x02\x06\xc0"}, -+ {3, "\xFF", 3, "\x02\x05\xe0"}, -+ {4, "\xFF", 3, "\x02\x04\xf0"}, -+ {5, "\xFF", 3, "\x02\x03\xf8"}, -+ {6, "\xFF", 3, "\x02\x02\xfc"}, -+ {7, "\xFF", 3, "\x02\x01\xfe"}, -+ {8, "\xFF\xFF", 3, "\x02\x00\xff"}, -+ {9, "\xFF\xFF", 4, "\x03\x07\xff\x80"}, -+ {10, "\xFF\xFF", 4, "\x03\x06\xff\xc0"}, -+ {11, "\xFF\xFF", 4, "\x03\x05\xff\xe0"}, -+ {12, "\xFF\xFF", 4, "\x03\x04\xff\xf0"}, -+ {13, "\xFF\xFF", 4, "\x03\x03\xff\xf8"}, -+ {14, "\xFF\xFF", 4, "\x03\x02\xff\xfc"}, -+ {15, "\xFF\xFF", 4, "\x03\x01\xff\xfe"}, -+ {16, "\xFF\xFF", 4, "\x03\x00\xff\xff"}, -+ {17, "\xFF\xFF\xFF", 5, "\x04\x07\xff\xff\x80"}, -+ {18, "\xFF\xFF\xFF", 5, "\x04\x06\xff\xff\xc0"}, -+ {19, "\xFF\xFF\xFF", 5, "\x04\x05\xff\xff\xe0"}, -+}; -+ -+void -+test_simple (void) -+{ -+ int result; -+ unsigned char der[100]; -+ unsigned char str[100]; -+ int der_len = sizeof (der); -+ int str_size = sizeof (str); -+ int ret_len, bit_len; -+ grub_size_t i; -+ -+ /* Dummy test */ -+ -+ asn1_bit_der (NULL, 0, der, &der_len); -+ result = asn1_get_bit_der (der, 0, &ret_len, str, str_size, &bit_len); -+ if (result != ASN1_GENERIC_ERROR) -+ { -+ grub_fatal ("asn1_get_bit_der zero\n"); -+ return; -+ } -+ -+ /* Encode short strings with increasing bit lengths */ -+ -+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) -+ { -+ /* Encode */ -+ -+ asn1_bit_der ((const unsigned char *) tv[i].bitstr, tv[i].bitlen, -+ der, &der_len); -+ -+#if 0 -+ { -+ size_t j; -+ for (j = 0; j < der_len; j++) -+ printf ("\\x%02x", der[j]); -+ printf ("\n"); -+ } -+#endif -+ -+ if (der_len != tv[i].derlen || grub_memcmp (der, tv[i].der, der_len) != 0) -+ { -+ grub_fatal ("asn1_bit_der iter %lu\n", (unsigned long) i); -+ return; -+ } -+ -+ /* Decode it */ -+ -+ result = asn1_get_bit_der (der, der_len, &ret_len, str, -+ str_size, &bit_len); -+ if (result != ASN1_SUCCESS || ret_len != tv[i].derlen -+ || bit_len != tv[i].bitlen) -+ { -+ grub_fatal ("asn1_get_bit_der iter %lu, err: %d\n", (unsigned long) i, result); -+ return; -+ } -+ } -+ -+ -+ /* Decode sample from "A Layman's Guide to a Subset of ASN.1, BER, -+ and DER" section 5.4 "BIT STRING": "The BER encoding of the BIT -+ STRING value "011011100101110111" can be any of the following, -+ among others, depending on the choice of padding bits, the form -+ of length octets [...]". -+ */ -+ -+ /* 03 04 06 6e 5d c0 DER encoding */ -+ -+ grub_memcpy (der, "\x04\x06\x6e\x5d\xc0", 5); -+ der_len = 5; -+ -+ result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); -+ if (result != ASN1_SUCCESS || ret_len != 5 -+ || bit_len != 18 || grub_memcmp (str, "\x6e\x5d\xc0", 3) != 0) -+ { -+ grub_fatal ("asn1_get_bit_der example\n"); -+ return; -+ } -+ -+ der_len = sizeof (der); -+ asn1_bit_der (str, bit_len, der, &der_len); -+ if (der_len != 5 || grub_memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) -+ { -+ grub_fatal ("asn1_bit_der example roundtrip\n"); -+ return; -+ } -+ -+ /* 03 04 06 6e 5d e0 padded with "100000" */ -+ -+ grub_memcpy (der, "\x04\x06\x6e\x5d\xe0", 5); -+ der_len = 5; -+ -+ result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); -+ if (result != ASN1_SUCCESS || ret_len != 5 -+ || bit_len != 18 || grub_memcmp (str, "\x6e\x5d\xe0", 3) != 0) -+ { -+ grub_fatal ("asn1_get_bit_der example padded\n"); -+ return; -+ } -+ -+ der_len = sizeof (der); -+ asn1_bit_der (str, bit_len, der, &der_len); -+ if (der_len != 5 || grub_memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) -+ { -+ grub_fatal ("asn1_bit_der example roundtrip\n"); -+ return; -+ } -+ -+ /* 03 81 04 06 6e 5d c0 long form of length octets */ -+ -+ grub_memcpy (der, "\x81\x04\x06\x6e\x5d\xc0", 6); -+ der_len = 6; -+ -+ result = asn1_get_bit_der (der, der_len, &ret_len, str, str_size, &bit_len); -+ -+ if (result != ASN1_SUCCESS || ret_len != 6 -+ || bit_len != 18 || grub_memcmp (str, "\x6e\x5d\xc0", 3) != 0) -+ { -+ grub_fatal ("asn1_get_bit_der example long form\n"); -+ return; -+ } -+ -+ der_len = sizeof (der); -+ asn1_bit_der (str, bit_len, der, &der_len); -+ if (der_len != 5 || grub_memcmp (der, "\x04\x06\x6e\x5d\xc0", 5) != 0) -+ { -+ grub_fatal ("asn1_bit_der example roundtrip\n"); -+ return; -+ } -+} -diff --git a/grub-core/lib/libtasn1_wrap/tests/Test_strings.c b/grub-core/lib/libtasn1_wrap/tests/Test_strings.c -new file mode 100644 -index 00000000000..dbe1474b204 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/Test_strings.c -@@ -0,0 +1,150 @@ -+/* -+ * Copyright (C) 2012-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ * Written by Simon Josefsson -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include "../wrap_tests.h" -+ -+struct tv -+{ -+ unsigned int etype; -+ unsigned int str_len; -+ const void *str; -+ unsigned int der_len; -+ const void *der; -+}; -+ -+static const struct tv tv[] = { -+ {ASN1_ETYPE_IA5_STRING, 20, -+ "\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72", -+ 22, -+ "\x16\x14\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72"}, -+ {ASN1_ETYPE_PRINTABLE_STRING, 5, "\x4e\x69\x6b\x6f\x73", -+ 7, "\x13\x05\x4e\x69\x6b\x6f\x73"}, -+ {ASN1_ETYPE_UTF8_STRING, 12, "Αττική", -+ 14, "\x0c\x0c\xce\x91\xcf\x84\xcf\x84\xce\xb9\xce\xba\xce\xae"}, -+ {ASN1_ETYPE_TELETEX_STRING, 15, -+ "\x53\x69\x6d\x6f\x6e\x20\x4a\x6f\x73\x65\x66\x73\x73\x6f\x6e", -+ 17, -+ "\x14\x0f\x53\x69\x6d\x6f\x6e\x20\x4a\x6f\x73\x65\x66\x73\x73\x6f\x6e"}, -+ {ASN1_ETYPE_OCTET_STRING, 36, -+ "\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A", -+ 38, -+ "\x04\x24\x30\x22\x80\x0F\x32\x30\x31\x31\x30\x38\x32\x31\x30\x38\x30\x30\x30\x36\x5A\x81\x0F\x32\x30\x31\x31\x30\x38\x32\x33\x32\x30\x35\x39\x35\x39\x5A"} -+}; -+ -+#define SSTR(x) sizeof(x)-1,x -+static const struct tv ber[] = { -+ {ASN1_ETYPE_OCTET_STRING, -+ SSTR("\xa0\xa0"), -+ SSTR("\x24\x80\x04\x82\x00\x02\xa0\xa0\x00\x00")}, -+ {ASN1_ETYPE_OCTET_STRING, -+ SSTR("\xa0\xa0\xb0\xb0\xb0"), -+ SSTR("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x00\x00")}, -+ {ASN1_ETYPE_OCTET_STRING, -+ SSTR("\xa0\xa0\xb0\xb0\xb0\xa1\xa1"), -+ SSTR("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x24\x80\x04\x82\x00\x02\xa1\xa1\x00\x00\x00\x00")}, -+ {ASN1_ETYPE_OCTET_STRING, -+ SSTR("\xa0\xa0\xb0\xb0\xb0\xa1\xa1\xc1"), -+ SSTR("\x24\x80\x04\x82\x00\x02\xa0\xa0\x04\x82\x00\x03\xb0\xb0\xb0\x24\x80\x04\x82\x00\x02\xa1\xa1\x04\x82\x00\x01\xc1\x00\x00\x00\x00")}, -+}; -+ -+void -+test_strings () -+{ -+ int ret; -+ unsigned char tl[ASN1_MAX_TL_SIZE]; -+ unsigned int tl_len, der_len, str_len; -+ const unsigned char *str; -+ unsigned char *b; -+ unsigned int i; -+ -+ /* Dummy test */ -+ -+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) -+ { -+ /* Encode */ -+ tl_len = sizeof (tl); -+ ret = asn1_encode_simple_der (tv[i].etype, tv[i].str, tv[i].str_len, -+ tl, &tl_len); -+ if (ret != ASN1_SUCCESS) -+ { -+ grub_fatal ("Encoding error in %u: %s\n", i, -+ asn1_strerror (ret)); -+ return; -+ } -+ der_len = tl_len + tv[i].str_len; -+ -+ if (der_len != tv[i].der_len || grub_memcmp (tl, tv[i].der, tl_len) != 0) -+ { -+ grub_fatal ( -+ "DER encoding differs in %u! (size: %u, expected: %u)\n", -+ i, der_len, tv[i].der_len); -+ return; -+ } -+ -+ /* decoding */ -+ ret = -+ asn1_decode_simple_der (tv[i].etype, tv[i].der, tv[i].der_len, &str, -+ &str_len); -+ if (ret != ASN1_SUCCESS) -+ { -+ grub_fatal ("Decoding error in %u: %s\n", i, -+ asn1_strerror (ret)); -+ return; -+ } -+ -+ if (str_len != tv[i].str_len || grub_memcmp (str, tv[i].str, str_len) != 0) -+ { -+ grub_fatal ( -+ "DER decoded data differ in %u! (size: %u, expected: %u)\n", -+ i, der_len, tv[i].str_len); -+ return; -+ } -+ } -+ -+ /* BER decoding */ -+ for (i = 0; i < sizeof (ber) / sizeof (ber[0]); i++) -+ { -+ /* decoding */ -+ ret = -+ asn1_decode_simple_ber (ber[i].etype, ber[i].der, ber[i].der_len, &b, -+ &str_len, NULL); -+ if (ret != ASN1_SUCCESS) -+ { -+ grub_fatal ("BER decoding error in %u: %s\n", i, -+ asn1_strerror (ret)); -+ return; -+ } -+ -+ if (str_len != ber[i].str_len || grub_memcmp (b, ber[i].str, str_len) != 0) -+ { -+ grub_fatal ( -+ "BER decoded data differ in %u! (size: %u, expected: %u)\n", -+ i, str_len, ber[i].str_len); -+ return; -+ } -+ grub_free(b); -+ } -+} -diff --git a/grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c b/grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c -new file mode 100644 -index 00000000000..d367bbfb5a7 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c -@@ -0,0 +1,116 @@ -+/* -+ * Copyright (C) 2016 Red Hat, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include "../wrap_tests.h" -+ -+struct tv -+{ -+ int der_len; -+ const unsigned char *der; -+ const char *oid; -+ int expected_error; -+}; -+ -+static const struct tv tv[] = { -+ {.der_len = 5, -+ .der = (void *) "\x06\x03\x80\x37\x03", -+ .oid = "2.999.3", -+ .expected_error = ASN1_DER_ERROR /* leading 0x80 */ -+ }, -+ {.der_len = 12, -+ .der = (void *) "\x06\x0a\x2b\x06\x01\x80\x01\x92\x08\x09\x05\x01", -+ .oid = "1.3.6.1.4.1.2312.9.5.1", -+ .expected_error = ASN1_DER_ERROR /* leading 0x80 */ -+ }, -+ {.der_len = 6, -+ .der = (void *) "\x06\x04\x01\x02\x03\x04", -+ .oid = "0.1.2.3.4", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 5, -+ .der = (void *) "\x06\x03\x51\x02\x03", -+ .oid = "2.1.2.3", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 5, -+ .der = (void *) "\x06\x03\x88\x37\x03", -+ .oid = "2.999.3", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 12, -+ .der = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01", -+ .oid = "1.3.6.1.4.1.2312.9.5.1", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 19, -+ .der = (void *) "\x06\x11\xfa\x80\x00\x00\x00\x0e\x01\x0e\xfa\x80\x00\x00\x00\x0e\x63\x6f\x6d", -+ .oid = "2.1998768.0.0.14.1.14.1998848.0.0.14.99.111.109", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 19, -+ .der = -+ (void *) -+ "\x06\x11\x2b\x06\x01\x04\x01\x92\x08\x09\x02\xaa\xda\xbe\xbe\xfa\x72\x01\x07", -+ .oid = "1.3.6.1.4.1.2312.9.2.1467399257458.1.7", -+ .expected_error = ASN1_SUCCESS}, -+}; -+ -+void -+test_object_id_decoding (void) -+{ -+ char str[128]; -+ int ret, ret_len; -+ grub_size_t i; -+ -+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) -+ { -+ /* decode */ -+ ret = -+ asn1_get_object_id_der (tv[i].der+1, -+ tv[i].der_len-1, &ret_len, str, -+ sizeof (str)); -+ if (ret != tv[i].expected_error) -+ { -+ grub_fatal ( -+ "%d: asn1_get_object_id_der iter %lu: got '%s' expected %d\n", -+ __LINE__, (unsigned long) i, asn1_strerror(ret), tv[i].expected_error); -+ return; -+ } -+ -+ if (tv[i].expected_error != ASN1_SUCCESS) -+ continue; -+ -+ if (ret_len != tv[i].der_len-1) -+ { -+ grub_fatal ( -+ "%d: iter %lu: error in DER, length returned is %d, had %d\n", -+ __LINE__, (unsigned long)i, ret_len, tv[i].der_len-1); -+ return; -+ } -+ -+ if (grub_strcmp (tv[i].oid, str) != 0) -+ { -+ grub_fatal ( -+ "%d: strcmp iter %lu: got invalid OID: %s, expected: %s\n", -+ __LINE__, (unsigned long) i, str, tv[i].oid); -+ return; -+ } -+ -+ } -+} -diff --git a/grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c b/grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c -new file mode 100644 -index 00000000000..3a83b58c59f ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c -@@ -0,0 +1,120 @@ -+/* -+ * Copyright (C) 2019 Nikos Mavrogiannopoulos -+ * -+ * This file is part of LIBTASN1. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include "../wrap_tests.h" -+ -+struct tv -+{ -+ int der_len; -+ const unsigned char *der; -+ const char *oid; -+ int expected_error; -+}; -+ -+static const struct tv tv[] = { -+ {.der_len = 0, -+ .der = (void *) "", -+ .oid = "5.999.3", -+ .expected_error = ASN1_VALUE_NOT_VALID /* cannot start with 5 */ -+ }, -+ {.der_len = 0, -+ .der = (void *) "", -+ .oid = "0.48.9", -+ .expected_error = ASN1_VALUE_NOT_VALID /* second field cannot be 48 */ -+ }, -+ {.der_len = 0, -+ .der = (void *) "", -+ .oid = "1.40.9", -+ .expected_error = ASN1_VALUE_NOT_VALID /* second field cannot be 40 */ -+ }, -+ {.der_len = 4, -+ .der = (void *) "\x06\x02\x4f\x63", -+ .oid = "1.39.99", -+ .expected_error = ASN1_SUCCESS, -+ }, -+ {.der_len = 6, -+ .der = (void *) "\x06\x04\x01\x02\x03\x04", -+ .oid = "0.1.2.3.4", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 5, -+ .der = (void *) "\x06\x03\x51\x02\x03", -+ .oid = "2.1.2.3", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 5, -+ .der = (void *) "\x06\x03\x88\x37\x03", -+ .oid = "2.999.3", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 12, -+ .der = (void *) "\x06\x0a\x2b\x06\x01\x04\x01\x92\x08\x09\x05\x01", -+ .oid = "1.3.6.1.4.1.2312.9.5.1", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 19, -+ .der = (void *) "\x06\x11\xfa\x80\x00\x00\x00\x0e\x01\x0e\xfa\x80\x00\x00\x00\x0e\x63\x6f\x6d", -+ .oid = "2.1998768.0.0.14.1.14.1998848.0.0.14.99.111.109", -+ .expected_error = ASN1_SUCCESS}, -+ {.der_len = 19, -+ .der = -+ (void *) -+ "\x06\x11\x2b\x06\x01\x04\x01\x92\x08\x09\x02\xaa\xda\xbe\xbe\xfa\x72\x01\x07", -+ .oid = "1.3.6.1.4.1.2312.9.2.1467399257458.1.7", -+ .expected_error = ASN1_SUCCESS}, -+}; -+ -+void -+test_object_id_encoding(void) -+{ -+ unsigned char der[128]; -+ int ret, der_len, i; -+ -+ for (i = 0; i < (int)(sizeof (tv) / sizeof (tv[0])); i++) -+ { -+ der_len = sizeof(der); -+ ret = asn1_object_id_der(tv[i].oid, der, &der_len, 0); -+ if (ret != ASN1_SUCCESS) -+ { -+ if (ret == tv[i].expected_error) -+ continue; -+ grub_fatal ( -+ "%d: iter %lu, encoding of OID failed: %s\n", -+ __LINE__, (unsigned long) i, asn1_strerror(ret)); -+ return; -+ } -+ else if (ret != tv[i].expected_error) -+ { -+ grub_fatal ( -+ "%d: iter %lu, encoding of OID %s succeeded when expecting failure\n", -+ __LINE__, (unsigned long) i, tv[i].oid); -+ return; -+ } -+ -+ if (der_len != tv[i].der_len || grub_memcmp(der, tv[i].der, der_len) != 0) -+ { -+ grub_fatal ( -+ "%d: iter %lu, re-encoding of OID %s resulted to different string (%d vs %d bytes)\n", -+ __LINE__, (unsigned long) i, tv[i].oid, der_len, tv[i].der_len); -+ -+ return; -+ } -+ } -+} -diff --git a/grub-core/lib/libtasn1_wrap/tests/octet-string.c b/grub-core/lib/libtasn1_wrap/tests/octet-string.c -new file mode 100644 -index 00000000000..d8a049e8df0 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/octet-string.c -@@ -0,0 +1,211 @@ -+/* -+ * Copyright (C) 2011-2020 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ * Written by Simon Josefsson and Nikos Mavrogiannopoulos -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include "../wrap_tests.h" -+ -+ -+struct tv -+{ -+ const char *name; -+ int der_len; -+ const unsigned char *der_str; -+ int len; -+ const unsigned char *string; -+ int expected_error; -+ int ber; -+}; -+ -+static const struct tv tv[] = { -+ {.name = "primitive octet strings", -+ .der_len = 10, -+ .der_str = -+ (void*)"\x04\x08\x01\x23\x45\x67\x89\xab\xcd\xef", -+ .len = 8, -+ .string = -+ (void*)"\x01\x23\x45\x67\x89\xab\xcd\xef", -+ .ber = 0}, -+ {.der_len = 22, -+ .der_str = -+ (void*)"\x04\x14\x13\x00\xd9\xa8\x47\xf7\xf2\x1c\xf4\xb0\xec\x5f\xc1\x73\xe5\x1b\x25\xc2\x62\x27", -+ .len = 20, -+ .string = -+ (void*)"\x13\x00\xD9\xA8\x47\xF7\xF2\x1C\xF4\xB0\xEC\x5F\xC1\x73\xE5\x1B\x25\xC2\x62\x27"}, -+ -+ {.name = "long type of length", -+ .der_len = 23, -+ .der_str = -+ (void*)"\x04\x81\x14\x13\x00\xd9\xa8\x47\xf7\xf2\x1c\xf4\xb0\xec\x5f\xc1\x73\xe5\x1b\x25\xc2\x62\x27", -+ .len = 20, -+ .string = -+ (void*)"\x13\x00\xD9\xA8\x47\xF7\xF2\x1C\xF4\xB0\xEC\x5F\xC1\x73\xE5\x1B\x25\xC2\x62\x27", -+ .ber = 1}, -+ {.der_len = 11, -+ .der_str = -+ (void*)"\x04\x81\x08\x01\x23\x45\x67\x89\xab\xcd\xef", -+ .len = 8, -+ .string = -+ (void*)"\x01\x23\x45\x67\x89\xab\xcd\xef", -+ .ber = 1}, -+ -+ {.name = "constructed - indefinite", -+ .der_len = 11, -+ .der_str = (void*)"\x24\x80\x04\x05\x01\x02\x03\x04\x05\x00\x00", -+ .len = 5, -+ .string = (void*)"\x01\x02\x03\x04\x05", -+ .ber = 1, -+ }, -+ -+ {.name = "constructed - definite - concat", -+ .der_len = 12, -+ .der_str = (void*)"\x24\x0a\x04\x04\x0a\x0b\x0c\x0d\x04\x02\x0e\x0f", -+ .len = 6, -+ .string = (void*)"\x0a\x0b\x0c\x0d\x0e\x0f", -+ .ber = 1, -+ }, -+ {.name = "constructed - definite - recursive", -+ .der_len = 15, -+ .der_str = (void*)"\x24\x0d\x04\x04\x0a\x0b\x0c\x0d\x24\x05\x04\x00\x04\x01\x0f", -+ .len = 5, -+ .string = (void*)"\x0a\x0b\x0c\x0d\x0f", -+ .ber = 1, -+ }, -+ {.name = "constructed - definite - single", -+ .der_len = 7, -+ .der_str = (void*)"\x24\x05\x04\x03\x01\x02\x03", -+ .len = 3, -+ .string = (void*)"\x01\x02\x03", -+ .ber = 1, -+ }, -+ -+ /* a large amount of recursive indefinite encoding */ -+ {.name = "a large amount of recursive indefinite encoding", -+ .der_len = 29325, -+ .der_str = (void*)"\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80\x24\x80", -+ .len = 0, -+ .ber = 1, -+ .expected_error = ASN1_DER_ERROR -+ } -+}; -+ -+void -+test_octet_string (void) -+{ -+ unsigned char str[100]; -+ unsigned char der[100]; -+ int der_len = sizeof (der); -+ int str_size = sizeof (str); -+ unsigned char *tmp = NULL; -+ int ret, ret_len; -+ grub_size_t i; -+ -+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) -+ { -+ /* Decode */ -+ -+ if (tv[i].ber == 0) -+ { -+ str_size = sizeof (str); -+ ret = -+ asn1_get_octet_der (tv[i].der_str + 1, -+ tv[i].der_len - 1, &ret_len, str, -+ sizeof (str), &str_size); -+ if (ret != tv[i].expected_error) -+ { -+ grub_fatal ( -+ "%d: asn1_get_octet_der: %s: got %d expected %d\n", -+ __LINE__, tv[i].name, ret, -+ tv[i].expected_error); -+ return; -+ } -+ if (tv[i].expected_error) -+ continue; -+ -+ if (ret_len != tv[i].der_len - 1) -+ { -+ grub_fatal ( -+ "%d: error in DER, length returned is %d, had %d\n", -+ __LINE__, ret_len, tv[i].der_len - 1); -+ return; -+ } -+ -+ if (str_size != tv[i].len -+ || grub_memcmp (tv[i].string, str, tv[i].len) != 0) -+ { -+ grub_fatal ( -+ "%d: memcmp: %s: got invalid decoding\n", -+ __LINE__, tv[i].name); -+ -+ return; -+ } -+ -+ /* Encode */ -+ der_len = sizeof (der); -+ asn1_octet_der (str, str_size, der, &der_len); -+ -+ if (der_len != tv[i].der_len - 1 -+ || grub_memcmp (tv[i].der_str + 1, der, tv[i].der_len - 1) != 0) -+ { -+ grub_fatal ( -+ "encoding: %s: got invalid encoding\n", -+ tv[i].name); -+ return; -+ } -+ } -+ -+ ret = -+ asn1_decode_simple_ber (ASN1_ETYPE_OCTET_STRING, -+ tv[i].der_str, tv[i].der_len, -+ &tmp, (unsigned int*)&str_size, (unsigned int*)&der_len); -+ if (ret != tv[i].expected_error) -+ { -+ grub_fatal ( -+ "%d: asn1_decode_simple_ber: %s: got %s expected %s\n", -+ __LINE__, tv[i].name, asn1_strerror(ret), asn1_strerror(tv[i].expected_error)); -+ return; -+ } -+ if (tv[i].expected_error) -+ continue; -+ -+ if (der_len != tv[i].der_len) -+ { -+ grub_fatal ( -+ "%d: error: %s: DER, length returned is %d, had %d\n", -+ __LINE__, tv[i].name, der_len, tv[i].der_len); -+ return; -+ } -+ -+ if (str_size != tv[i].len || grub_memcmp (tv[i].string, tmp, tv[i].len) != 0) -+ { -+ grub_fatal ( -+ "%d: memcmp: %s: got invalid decoding\n", -+ __LINE__, tv[i].name); -+ return; -+ } -+ grub_free (tmp); -+ tmp = NULL; -+ -+ } -+} -diff --git a/grub-core/lib/libtasn1_wrap/tests/reproducers.c b/grub-core/lib/libtasn1_wrap/tests/reproducers.c -new file mode 100644 -index 00000000000..dc7268d4c6c ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/reproducers.c -@@ -0,0 +1,81 @@ -+/* -+ * Copyright (C) 2019 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ * -+ */ -+ -+/****************************************************************/ -+/* Description: run reproducers for several fixed issues */ -+/****************************************************************/ -+ -+#include -+#include -+#include -+#include "../wrap_tests.h" -+ -+#define CONST_DOWN (1U<<29) -+ -+/* produces endless loop (fixed by d4b624b2): -+ * The following translates into a single node with all pointers -+ * (right,left,down) set to NULL. */ -+const asn1_static_node endless_asn1_tab[] = { -+ { "TEST_TREE", 536875024, NULL }, -+ { NULL, 0, NULL } -+}; -+ -+/* produces memory leak (fixed by f16d1ff9): -+ * 152 bytes in 1 blocks are definitely lost in loss record 1 of 1 -+ * at 0x4837B65: calloc (vg_replace_malloc.c:762) -+ * by 0x4851C0D: _asn1_add_static_node (parser_aux.c:71) -+ * by 0x4853AAC: asn1_array2tree (structure.c:200) -+ * by 0x10923B: main (single_node.c:67) -+ */ -+const asn1_static_node tab[] = { -+{ "a", CONST_DOWN, "" }, -+{ "b", 0, "" }, -+{ "c", 0, "" }, -+{ NULL, 0, NULL } -+}; -+ -+void -+test_reproducers (void) -+{ -+ int result; -+ asn1_node definitions = NULL; -+ char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; -+ -+ result = asn1_array2tree (endless_asn1_tab, &definitions, errorDescription); -+ if (result != ASN1_SUCCESS) -+ { -+ grub_fatal ("Error: %s\nErrorDescription = %s\n\n", -+ asn1_strerror (result), errorDescription); -+ return; -+ } -+ -+ asn1_delete_structure (&definitions); -+ -+ definitions = NULL; -+ result = asn1_array2tree (tab, &definitions, errorDescription); -+ if (result != ASN1_SUCCESS) -+ { -+ grub_fatal ("Error: %s\nErrorDescription = %s\n\n", -+ asn1_strerror (result), errorDescription); -+ return; -+ } -+ -+ asn1_delete_structure (&definitions); -+} -diff --git a/grub-core/lib/libtasn1_wrap/wrap_tests.c b/grub-core/lib/libtasn1_wrap/wrap_tests.c -new file mode 100644 -index 00000000000..75fcd21f0d5 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/wrap_tests.c -@@ -0,0 +1,75 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include "wrap_tests.h" -+ -+/* -+ * libtasn1 tests - from which this is derived - are provided under GPL3+. -+ */ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_command_t cmd; -+ -+static grub_err_t -+grub_cmd_asn1test (grub_command_t cmdd __attribute__((unused)), -+ int argc __attribute__((unused)), -+ char **args __attribute__((unused))) -+{ -+ grub_printf ("test_CVE_2018_1000654\n"); -+ test_CVE_2018_1000654 (); -+ -+ grub_printf ("test_object_id_decoding\n"); -+ test_object_id_decoding (); -+ -+ grub_printf ("test_object_id_encoding\n"); -+ test_object_id_encoding (); -+ -+ grub_printf ("test_octet_string\n"); -+ test_octet_string (); -+ -+ grub_printf ("test_overflow\n"); -+ test_overflow (); -+ -+ grub_printf ("test_reproducers\n"); -+ test_overflow (); -+ -+ grub_printf ("test_simple\n"); -+ test_simple (); -+ -+ grub_printf ("test_strings\n"); -+ test_strings (); -+ -+ grub_printf ("ASN.1 self-tests passed\n"); -+ -+ return GRUB_ERR_NONE; -+} -+ -+ -+GRUB_MOD_INIT(test_asn1) -+{ -+ cmd = grub_register_command ("test_asn1", grub_cmd_asn1test, NULL, -+ "Run self-tests for the ASN.1 parser."); -+} -+ -+GRUB_MOD_FINI(test_asn1) -+{ -+ grub_unregister_command (cmd); -+} -diff --git a/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h -new file mode 100644 -index 00000000000..1e7d3d64f55 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h -@@ -0,0 +1,32 @@ -+#if HAVE_CONFIG_H -+# include "config.h" -+#endif -+ -+#include -+ -+const asn1_static_node CVE_2018_1000654_1_asn1_tab[] = { -+ { "TEST_TREE", 536875024, NULL }, -+ { NULL, 1610612748, NULL }, -+ { "iso", 1073741825, "1"}, -+ { "identified-organization", 1073741825, "3"}, -+ { "dod", 1073741825, "6"}, -+ { "internet", 1073741825, "1"}, -+ { "security", 1073741825, "5"}, -+ { "mechanisms", 1073741825, "5"}, -+ { "pkix", 1073741825, "7"}, -+ { "id-mod", 1073741825, "0"}, -+ { "id-pkix1-implicit-88", 1, "2"}, -+ { "id-xnyTest", 1879048204, NULL }, -+ { NULL, 1073741825, "id-ix"}, -+ { NULL, 1073741825, "29"}, -+ { NULL, 1, "1"}, -+ { "id-ix", 1880096780, "OBJECR"}, -+ { NULL, 1073741825, "id-ix"}, -+ { NULL, 1073741825, "29"}, -+ { NULL, 1, "2"}, -+ { "id-xnyTest", 805306380, NULL }, -+ { NULL, 1073741825, "id-ix"}, -+ { NULL, 1073741825, "29"}, -+ { NULL, 1, "1"}, -+ { NULL, 0, NULL } -+}; -diff --git a/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h -new file mode 100644 -index 00000000000..e2561e5ec6d ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h -@@ -0,0 +1,36 @@ -+#if HAVE_CONFIG_H -+# include "config.h" -+#endif -+ -+#include -+ -+const asn1_static_node CVE_2018_1000654_2_asn1_tab[] = { -+ { "TEST_TREE", 536875024, NULL }, -+ { NULL, 1610612748, NULL }, -+ { "iso", 1073741825, "1"}, -+ { "identified-organization", 1073741825, "3"}, -+ { "dod", 1073741825, "6"}, -+ { "internet", 1073741825, "1"}, -+ { "security", 1073741825, "5"}, -+ { "mechanisms", 1073741825, "5"}, -+ { "pkix", 1073741825, "7"}, -+ { "id-mod", 1073741825, "0"}, -+ { "id-pkix1-implicit-88", 1, "2"}, -+ { "id-oneTest", 1879048204, NULL }, -+ { NULL, 1073741825, "id-two"}, -+ { NULL, 1073741825, "9"}, -+ { NULL, 1, "1"}, -+ { "id-two", 1879048204, NULL }, -+ { NULL, 1073741825, "id-three"}, -+ { NULL, 1073741825, "2"}, -+ { NULL, 1, "2"}, -+ { "id-three", 1879048204, NULL }, -+ { NULL, 1073741825, "id-four"}, -+ { NULL, 1073741825, "3"}, -+ { NULL, 1, "3"}, -+ { "id-four", 805306380, NULL }, -+ { NULL, 1073741825, "id-two"}, -+ { NULL, 1073741825, "3"}, -+ { NULL, 1, "3"}, -+ { NULL, 0, NULL } -+}; -diff --git a/grub-core/lib/libtasn1_wrap/wrap_tests.h b/grub-core/lib/libtasn1_wrap/wrap_tests.h -new file mode 100644 -index 00000000000..555e56dd202 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/wrap_tests.h -@@ -0,0 +1,38 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef LIBTASN1_WRAP_TESTS_H -+#define LIBTASN1_WRAP_TESTS_H -+ -+void test_CVE_2018_1000654 (void); -+ -+void test_object_id_encoding (void); -+ -+void test_object_id_decoding (void); -+ -+void test_octet_string (void); -+ -+void test_overflow (void); -+ -+void test_reproducers (void); -+ -+void test_simple (void); -+ -+void test_strings (void); -+ -+#endif -diff --git a/.gitignore b/.gitignore -index 594d0134d33..856e69bc5c1 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -264,6 +264,7 @@ widthspec.bin - /stamp-h1 - /syslinux_test - /tar_test -+/test_asn1 - /test_sha512sum - /test_unset - /tests/syslinux/ubuntu10.04_grub.cfg -diff --git a/tests/test_asn1.in b/tests/test_asn1.in -new file mode 100644 -index 00000000000..8173c5c270e ---- /dev/null -+++ b/tests/test_asn1.in -@@ -0,0 +1,12 @@ -+#! @BUILD_SHEBANG@ -+set -e -+ -+. "@builddir@/grub-core/modinfo.sh" -+ -+out=`echo test_asn1 | @builddir@/grub-shell` -+ -+if [ "$(echo "$out" | tail -n 1)" != "ASN.1 self-tests passed" ]; then -+ echo "ASN.1 test failure: $out" -+ exit 1 -+fi -+ diff --git a/0174-grub-install-support-embedding-x509-certificates.patch b/0174-grub-install-support-embedding-x509-certificates.patch deleted file mode 100644 index bd02e6d..0000000 --- a/0174-grub-install-support-embedding-x509-certificates.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Alastair D'Silva -Date: Mon, 6 Jul 2020 13:33:04 +1000 -Subject: [PATCH] grub-install: support embedding x509 certificates - -To support verification of appended signatures, we need a way to -embed the necessary public keys. Existing appended signature schemes -in the Linux kernel use X.509 certificates, so allow certificates to -be embedded in the grub core image in the same way as PGP keys. - -Signed-off-by: Alastair D'Silva -Signed-off-by: Daniel Axtens ---- - grub-core/commands/pgp.c | 2 +- - util/grub-install-common.c | 22 +++++++++++++++++++++- - util/grub-mkimage.c | 15 +++++++++++++-- - util/mkimage.c | 38 ++++++++++++++++++++++++++++++++++++-- - include/grub/kernel.h | 4 +++- - include/grub/util/install.h | 7 +++++-- - 6 files changed, 79 insertions(+), 9 deletions(-) - -diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c -index 355a43844ac..b81ac0ae46c 100644 ---- a/grub-core/commands/pgp.c -+++ b/grub-core/commands/pgp.c -@@ -944,7 +944,7 @@ GRUB_MOD_INIT(pgp) - grub_memset (&pseudo_file, 0, sizeof (pseudo_file)); - - /* Not an ELF module, skip. */ -- if (header->type != OBJ_TYPE_PUBKEY) -+ if (header->type != OBJ_TYPE_GPG_PUBKEY) - continue; - - pseudo_file.fs = &pseudo_fs; -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index aab2a941f85..422f82362c7 100644 ---- a/util/grub-install-common.c -+++ b/util/grub-install-common.c -@@ -460,6 +460,8 @@ static char **pubkeys; - static size_t npubkeys; - static char *sbat; - static int disable_shim_lock; -+static char **x509keys; -+static size_t nx509keys; - static grub_compression_t compression; - static size_t appsig_size; - -@@ -500,6 +502,11 @@ grub_install_parse (int key, char *arg) - return 1; - case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK: - disable_shim_lock = 1; -+ case 'x': -+ x509keys = xrealloc (x509keys, -+ sizeof (x509keys[0]) -+ * (nx509keys + 1)); -+ x509keys[nx509keys++] = xstrdup (arg); - return 1; - - case GRUB_INSTALL_OPTIONS_VERBOSITY: -@@ -627,6 +634,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, - for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) - slen += 20 + grub_strlen (*pk); - -+ for (pk = x509keys; pk < x509keys + nx509keys; pk++) -+ slen += 10 + grub_strlen (*pk); -+ - for (md = modules.entries; *md; md++) - { - slen += 10 + grub_strlen (*md); -@@ -655,6 +665,14 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, - *p++ = ' '; - } - -+ for (pk = x509keys; pk < x509keys + nx509keys; pk++) -+ { -+ p = grub_stpcpy (p, "--x509 '"); -+ p = grub_stpcpy (p, *pk); -+ *p++ = '\''; -+ *p++ = ' '; -+ } -+ - for (md = modules.entries; *md; md++) - { - *p++ = '\''; -@@ -688,7 +706,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, - - grub_install_generate_image (dir, prefix, fp, outname, - modules.entries, memdisk_path, -- pubkeys, npubkeys, config_path, tgt, -+ pubkeys, npubkeys, -+ x509keys, nx509keys, -+ config_path, tgt, - note, appsig_size, compression, dtb, sbat, - disable_shim_lock); - while (dc--) -diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c -index 8a53310548b..e1f1112784a 100644 ---- a/util/grub-mkimage.c -+++ b/util/grub-mkimage.c -@@ -75,7 +75,8 @@ static struct argp_option options[] = { - /* TRANSLATORS: "embed" is a verb (command description). "*/ - {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0}, - /* TRANSLATORS: "embed" is a verb (command description). "*/ -- {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0}, -+ {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for PGP signature checking"), 0}, -+ {"x509", 'x', N_("FILE"), 0, N_("embed FILE as an x509 certificate for appended signature checking"), 0}, - /* TRANSLATORS: NOTE is a name of segment. */ - {"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0}, - {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0}, -@@ -124,6 +125,8 @@ struct arguments - char *dtb; - char **pubkeys; - size_t npubkeys; -+ char **x509keys; -+ size_t nx509keys; - char *font; - char *config; - char *sbat; -@@ -206,6 +209,13 @@ argp_parser (int key, char *arg, struct argp_state *state) - arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg); - break; - -+ case 'x': -+ arguments->x509keys = xrealloc (arguments->x509keys, -+ sizeof (arguments->x509keys[0]) -+ * (arguments->nx509keys + 1)); -+ arguments->x509keys[arguments->nx509keys++] = xstrdup (arg); -+ break; -+ - case 'c': - if (arguments->config) - free (arguments->config); -@@ -332,7 +342,8 @@ main (int argc, char *argv[]) - grub_install_generate_image (arguments.dir, arguments.prefix, fp, - arguments.output, arguments.modules, - arguments.memdisk, arguments.pubkeys, -- arguments.npubkeys, arguments.config, -+ arguments.npubkeys, arguments.x509keys, -+ arguments.nx509keys, arguments.config, - arguments.image_target, arguments.note, - arguments.appsig_size, arguments.comp, - arguments.dtb, arguments.sbat, -diff --git a/util/mkimage.c b/util/mkimage.c -index bab12276010..8319e8dfbde 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -867,7 +867,8 @@ void - grub_install_generate_image (const char *dir, const char *prefix, - FILE *out, const char *outname, char *mods[], - char *memdisk_path, char **pubkey_paths, -- size_t npubkeys, char *config_path, -+ size_t npubkeys, char **x509key_paths, -+ size_t nx509keys, char *config_path, - const struct grub_install_image_target_desc *image_target, - int note, size_t appsig_size, grub_compression_t comp, - const char *dtb_path, const char *sbat_path, -@@ -913,6 +914,19 @@ grub_install_generate_image (const char *dir, const char *prefix, - } - } - -+ { -+ size_t i; -+ for (i = 0; i < nx509keys; i++) -+ { -+ size_t curs; -+ curs = ALIGN_ADDR (grub_util_get_image_size (x509key_paths[i])); -+ grub_util_info ("the size of x509 public key %u is 0x%" -+ GRUB_HOST_PRIxLONG_LONG, -+ (unsigned) i, (unsigned long long) curs); -+ total_module_size += curs + sizeof (struct grub_module_header); -+ } -+ } -+ - if (memdisk_path) - { - memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); -@@ -1034,7 +1048,7 @@ grub_install_generate_image (const char *dir, const char *prefix, - curs = grub_util_get_image_size (pubkey_paths[i]); - - header = (struct grub_module_header *) (kernel_img + offset); -- header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY); -+ header->type = grub_host_to_target32 (OBJ_TYPE_GPG_PUBKEY); - header->size = grub_host_to_target32 (curs + sizeof (*header)); - offset += sizeof (*header); - -@@ -1043,6 +1057,26 @@ grub_install_generate_image (const char *dir, const char *prefix, - } - } - -+ { -+ size_t i; -+ for (i = 0; i < nx509keys; i++) -+ { -+ size_t curs; -+ struct grub_module_header *header; -+ -+ curs = grub_util_get_image_size (x509key_paths[i]); -+ -+ header = (struct grub_module_header *) (kernel_img + offset); -+ header->type = grub_host_to_target32 (OBJ_TYPE_X509_PUBKEY); -+ header->size = grub_host_to_target32 (curs + sizeof (*header)); -+ offset += sizeof (*header); -+ -+ grub_util_load_image (x509key_paths[i], kernel_img + offset); -+ offset += ALIGN_ADDR (curs); -+ } -+ } -+ -+ - if (memdisk_path) - { - struct grub_module_header *header; -diff --git a/include/grub/kernel.h b/include/grub/kernel.h -index 55849777eaa..98edc0863f6 100644 ---- a/include/grub/kernel.h -+++ b/include/grub/kernel.h -@@ -30,7 +30,9 @@ enum - OBJ_TYPE_PREFIX, - OBJ_TYPE_PUBKEY, - OBJ_TYPE_DTB, -- OBJ_TYPE_DISABLE_SHIM_LOCK -+ OBJ_TYPE_DISABLE_SHIM_LOCK, -+ OBJ_TYPE_GPG_PUBKEY, -+ OBJ_TYPE_X509_PUBKEY, - }; - - /* The module header. */ -diff --git a/include/grub/util/install.h b/include/grub/util/install.h -index cf4531e02b6..51f3b13ac13 100644 ---- a/include/grub/util/install.h -+++ b/include/grub/util/install.h -@@ -67,6 +67,8 @@ - N_("SBAT metadata"), 0 }, \ - { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \ - N_("disable shim_lock verifier"), 0 }, \ -+ { "x509key", 'x', N_("FILE"), 0, \ -+ N_("embed FILE as an x509 certificate for signature checking"), 0}, \ - { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\ - "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \ - 1}, \ -@@ -188,8 +190,9 @@ void - grub_install_generate_image (const char *dir, const char *prefix, - FILE *out, - const char *outname, char *mods[], -- char *memdisk_path, char **pubkey_paths, -- size_t npubkeys, -+ char *memdisk_path, -+ char **pubkey_paths, size_t npubkeys, -+ char **x509key_paths, size_t nx509keys, - char *config_path, - const struct grub_install_image_target_desc *image_target, - int note, size_t appsig_size, diff --git a/0175-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch b/0175-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch deleted file mode 100644 index 7b7d70c..0000000 --- a/0175-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch +++ /dev/null @@ -1,639 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 30 Jul 2020 01:35:10 +1000 -Subject: [PATCH] appended signatures: import GNUTLS's ASN.1 description files - -In order to parse PKCS#7 messages and X.509 certificates with libtasn1, -we need some information about how they are encoded. - -We get these from GNUTLS, which has the benefit that they support the -features we need and are well tested. - -The GNUTLS license is LGPLv2.1+, which is GPLv3 compatible, allowing -us to import it without issue. - -Signed-off-by: Daniel Axtens ---- - grub-core/commands/appendedsig/gnutls_asn1_tab.c | 121 ++++++ - grub-core/commands/appendedsig/pkix_asn1_tab.c | 484 +++++++++++++++++++++++ - 2 files changed, 605 insertions(+) - create mode 100644 grub-core/commands/appendedsig/gnutls_asn1_tab.c - create mode 100644 grub-core/commands/appendedsig/pkix_asn1_tab.c - -diff --git a/grub-core/commands/appendedsig/gnutls_asn1_tab.c b/grub-core/commands/appendedsig/gnutls_asn1_tab.c -new file mode 100644 -index 00000000000..ddd1314e63b ---- /dev/null -+++ b/grub-core/commands/appendedsig/gnutls_asn1_tab.c -@@ -0,0 +1,121 @@ -+#include -+#include -+ -+const asn1_static_node gnutls_asn1_tab[] = { -+ { "GNUTLS", 536872976, NULL }, -+ { NULL, 1073741836, NULL }, -+ { "RSAPublicKey", 1610612741, NULL }, -+ { "modulus", 1073741827, NULL }, -+ { "publicExponent", 3, NULL }, -+ { "RSAPrivateKey", 1610612741, NULL }, -+ { "version", 1073741827, NULL }, -+ { "modulus", 1073741827, NULL }, -+ { "publicExponent", 1073741827, NULL }, -+ { "privateExponent", 1073741827, NULL }, -+ { "prime1", 1073741827, NULL }, -+ { "prime2", 1073741827, NULL }, -+ { "exponent1", 1073741827, NULL }, -+ { "exponent2", 1073741827, NULL }, -+ { "coefficient", 1073741827, NULL }, -+ { "otherPrimeInfos", 16386, "OtherPrimeInfos"}, -+ { "ProvableSeed", 1610612741, NULL }, -+ { "algorithm", 1073741836, NULL }, -+ { "seed", 7, NULL }, -+ { "OtherPrimeInfos", 1612709899, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "OtherPrimeInfo"}, -+ { "OtherPrimeInfo", 1610612741, NULL }, -+ { "prime", 1073741827, NULL }, -+ { "exponent", 1073741827, NULL }, -+ { "coefficient", 3, NULL }, -+ { "AlgorithmIdentifier", 1610612741, NULL }, -+ { "algorithm", 1073741836, NULL }, -+ { "parameters", 541081613, NULL }, -+ { "algorithm", 1, NULL }, -+ { "DigestInfo", 1610612741, NULL }, -+ { "digestAlgorithm", 1073741826, "DigestAlgorithmIdentifier"}, -+ { "digest", 7, NULL }, -+ { "DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"}, -+ { "DSAPublicKey", 1073741827, NULL }, -+ { "DSAParameters", 1610612741, NULL }, -+ { "p", 1073741827, NULL }, -+ { "q", 1073741827, NULL }, -+ { "g", 3, NULL }, -+ { "DSASignatureValue", 1610612741, NULL }, -+ { "r", 1073741827, NULL }, -+ { "s", 3, NULL }, -+ { "DSAPrivateKey", 1610612741, NULL }, -+ { "version", 1073741827, NULL }, -+ { "p", 1073741827, NULL }, -+ { "q", 1073741827, NULL }, -+ { "g", 1073741827, NULL }, -+ { "Y", 1073741827, NULL }, -+ { "priv", 3, NULL }, -+ { "DHParameter", 1610612741, NULL }, -+ { "prime", 1073741827, NULL }, -+ { "base", 1073741827, NULL }, -+ { "privateValueLength", 16387, NULL }, -+ { "ECParameters", 1610612754, NULL }, -+ { "namedCurve", 12, NULL }, -+ { "ECPrivateKey", 1610612741, NULL }, -+ { "Version", 1073741827, NULL }, -+ { "privateKey", 1073741831, NULL }, -+ { "parameters", 1610637314, "ECParameters"}, -+ { NULL, 2056, "0"}, -+ { "publicKey", 536895494, NULL }, -+ { NULL, 2056, "1"}, -+ { "PrincipalName", 1610612741, NULL }, -+ { "name-type", 1610620931, NULL }, -+ { NULL, 2056, "0"}, -+ { "name-string", 536879115, NULL }, -+ { NULL, 1073743880, "1"}, -+ { NULL, 27, NULL }, -+ { "KRB5PrincipalName", 1610612741, NULL }, -+ { "realm", 1610620955, NULL }, -+ { NULL, 2056, "0"}, -+ { "principalName", 536879106, "PrincipalName"}, -+ { NULL, 2056, "1"}, -+ { "RSAPSSParameters", 1610612741, NULL }, -+ { "hashAlgorithm", 1610637314, "AlgorithmIdentifier"}, -+ { NULL, 2056, "0"}, -+ { "maskGenAlgorithm", 1610637314, "AlgorithmIdentifier"}, -+ { NULL, 2056, "1"}, -+ { "saltLength", 1610653699, NULL }, -+ { NULL, 1073741833, "20"}, -+ { NULL, 2056, "2"}, -+ { "trailerField", 536911875, NULL }, -+ { NULL, 1073741833, "1"}, -+ { NULL, 2056, "3"}, -+ { "GOSTParameters", 1610612741, NULL }, -+ { "publicKeyParamSet", 1073741836, NULL }, -+ { "digestParamSet", 16396, NULL }, -+ { "GOSTParametersOld", 1610612741, NULL }, -+ { "publicKeyParamSet", 1073741836, NULL }, -+ { "digestParamSet", 1073741836, NULL }, -+ { "encryptionParamSet", 16396, NULL }, -+ { "GOSTPrivateKey", 1073741831, NULL }, -+ { "GOSTPrivateKeyOld", 1073741827, NULL }, -+ { "IssuerSignTool", 1610612741, NULL }, -+ { "signTool", 1073741858, NULL }, -+ { "cATool", 1073741858, NULL }, -+ { "signToolCert", 1073741858, NULL }, -+ { "cAToolCert", 34, NULL }, -+ { "Gost28147-89-EncryptedKey", 1610612741, NULL }, -+ { "encryptedKey", 1073741831, NULL }, -+ { "maskKey", 1610637319, NULL }, -+ { NULL, 4104, "0"}, -+ { "macKey", 7, NULL }, -+ { "SubjectPublicKeyInfo", 1610612741, NULL }, -+ { "algorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "subjectPublicKey", 6, NULL }, -+ { "GostR3410-TransportParameters", 1610612741, NULL }, -+ { "encryptionParamSet", 1073741836, NULL }, -+ { "ephemeralPublicKey", 1610637314, "SubjectPublicKeyInfo"}, -+ { NULL, 4104, "0"}, -+ { "ukm", 7, NULL }, -+ { "GostR3410-KeyTransport", 536870917, NULL }, -+ { "sessionEncryptedKey", 1073741826, "Gost28147-89-EncryptedKey"}, -+ { "transportParameters", 536895490, "GostR3410-TransportParameters"}, -+ { NULL, 4104, "0"}, -+ { NULL, 0, NULL } -+}; -diff --git a/grub-core/commands/appendedsig/pkix_asn1_tab.c b/grub-core/commands/appendedsig/pkix_asn1_tab.c -new file mode 100644 -index 00000000000..adef69d95ce ---- /dev/null -+++ b/grub-core/commands/appendedsig/pkix_asn1_tab.c -@@ -0,0 +1,484 @@ -+#include -+#include -+ -+const asn1_static_node pkix_asn1_tab[] = { -+ { "PKIX1", 536875024, NULL }, -+ { NULL, 1073741836, NULL }, -+ { "PrivateKeyUsagePeriod", 1610612741, NULL }, -+ { "notBefore", 1610637349, NULL }, -+ { NULL, 4104, "0"}, -+ { "notAfter", 536895525, NULL }, -+ { NULL, 4104, "1"}, -+ { "AuthorityKeyIdentifier", 1610612741, NULL }, -+ { "keyIdentifier", 1610637319, NULL }, -+ { NULL, 4104, "0"}, -+ { "authorityCertIssuer", 1610637314, "GeneralNames"}, -+ { NULL, 4104, "1"}, -+ { "authorityCertSerialNumber", 536895490, "CertificateSerialNumber"}, -+ { NULL, 4104, "2"}, -+ { "SubjectKeyIdentifier", 1073741831, NULL }, -+ { "KeyUsage", 1073741830, NULL }, -+ { "DirectoryString", 1610612754, NULL }, -+ { "teletexString", 1612709918, NULL }, -+ { "MAX", 524298, "1"}, -+ { "printableString", 1612709919, NULL }, -+ { "MAX", 524298, "1"}, -+ { "universalString", 1612709920, NULL }, -+ { "MAX", 524298, "1"}, -+ { "utf8String", 1612709922, NULL }, -+ { "MAX", 524298, "1"}, -+ { "bmpString", 1612709921, NULL }, -+ { "MAX", 524298, "1"}, -+ { "ia5String", 538968093, NULL }, -+ { "MAX", 524298, "1"}, -+ { "SubjectAltName", 1073741826, "GeneralNames"}, -+ { "GeneralNames", 1612709899, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "GeneralName"}, -+ { "GeneralName", 1610612754, NULL }, -+ { "otherName", 1610620930, "AnotherName"}, -+ { NULL, 4104, "0"}, -+ { "rfc822Name", 1610620957, NULL }, -+ { NULL, 4104, "1"}, -+ { "dNSName", 1610620957, NULL }, -+ { NULL, 4104, "2"}, -+ { "x400Address", 1610620941, NULL }, -+ { NULL, 4104, "3"}, -+ { "directoryName", 1610620939, NULL }, -+ { NULL, 1073743880, "4"}, -+ { NULL, 2, "RelativeDistinguishedName"}, -+ { "ediPartyName", 1610620941, NULL }, -+ { NULL, 4104, "5"}, -+ { "uniformResourceIdentifier", 1610620957, NULL }, -+ { NULL, 4104, "6"}, -+ { "iPAddress", 1610620935, NULL }, -+ { NULL, 4104, "7"}, -+ { "registeredID", 536879116, NULL }, -+ { NULL, 4104, "8"}, -+ { "AnotherName", 1610612741, NULL }, -+ { "type-id", 1073741836, NULL }, -+ { "value", 541073421, NULL }, -+ { NULL, 1073743880, "0"}, -+ { "type-id", 1, NULL }, -+ { "IssuerAltName", 1073741826, "GeneralNames"}, -+ { "BasicConstraints", 1610612741, NULL }, -+ { "cA", 1610645508, NULL }, -+ { NULL, 131081, NULL }, -+ { "pathLenConstraint", 537411587, NULL }, -+ { "0", 10, "MAX"}, -+ { "CRLDistributionPoints", 1612709899, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "DistributionPoint"}, -+ { "DistributionPoint", 1610612741, NULL }, -+ { "distributionPoint", 1610637314, "DistributionPointName"}, -+ { NULL, 2056, "0"}, -+ { "reasons", 1610637314, "ReasonFlags"}, -+ { NULL, 4104, "1"}, -+ { "cRLIssuer", 536895490, "GeneralNames"}, -+ { NULL, 4104, "2"}, -+ { "DistributionPointName", 1610612754, NULL }, -+ { "fullName", 1610620930, "GeneralNames"}, -+ { NULL, 4104, "0"}, -+ { "nameRelativeToCRLIssuer", 536879106, "RelativeDistinguishedName"}, -+ { NULL, 4104, "1"}, -+ { "ReasonFlags", 1073741830, NULL }, -+ { "ExtKeyUsageSyntax", 1612709899, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 12, NULL }, -+ { "AuthorityInfoAccessSyntax", 1612709899, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "AccessDescription"}, -+ { "AccessDescription", 1610612741, NULL }, -+ { "accessMethod", 1073741836, NULL }, -+ { "accessLocation", 2, "GeneralName"}, -+ { "Attribute", 1610612741, NULL }, -+ { "type", 1073741836, NULL }, -+ { "values", 536870927, NULL }, -+ { NULL, 13, NULL }, -+ { "AttributeTypeAndValue", 1610612741, NULL }, -+ { "type", 1073741836, NULL }, -+ { "value", 13, NULL }, -+ { "Name", 1610612754, NULL }, -+ { "rdnSequence", 536870923, NULL }, -+ { NULL, 2, "RelativeDistinguishedName"}, -+ { "DistinguishedName", 1610612747, NULL }, -+ { NULL, 2, "RelativeDistinguishedName"}, -+ { "RelativeDistinguishedName", 1612709903, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "AttributeTypeAndValue"}, -+ { "Certificate", 1610612741, NULL }, -+ { "tbsCertificate", 1073741826, "TBSCertificate"}, -+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "signature", 6, NULL }, -+ { "TBSCertificate", 1610612741, NULL }, -+ { "version", 1610653699, NULL }, -+ { NULL, 1073741833, "0"}, -+ { NULL, 2056, "0"}, -+ { "serialNumber", 1073741826, "CertificateSerialNumber"}, -+ { "signature", 1073741826, "AlgorithmIdentifier"}, -+ { "issuer", 1073741826, "Name"}, -+ { "validity", 1073741826, "Validity"}, -+ { "subject", 1073741826, "Name"}, -+ { "subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"}, -+ { "issuerUniqueID", 1610637314, "UniqueIdentifier"}, -+ { NULL, 4104, "1"}, -+ { "subjectUniqueID", 1610637314, "UniqueIdentifier"}, -+ { NULL, 4104, "2"}, -+ { "extensions", 536895490, "Extensions"}, -+ { NULL, 2056, "3"}, -+ { "CertificateSerialNumber", 1073741827, NULL }, -+ { "Validity", 1610612741, NULL }, -+ { "notBefore", 1073741826, "Time"}, -+ { "notAfter", 2, "Time"}, -+ { "Time", 1610612754, NULL }, -+ { "utcTime", 1073741860, NULL }, -+ { "generalTime", 37, NULL }, -+ { "UniqueIdentifier", 1073741830, NULL }, -+ { "SubjectPublicKeyInfo", 1610612741, NULL }, -+ { "algorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "subjectPublicKey", 6, NULL }, -+ { "Extensions", 1612709899, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "Extension"}, -+ { "Extension", 1610612741, NULL }, -+ { "extnID", 1073741836, NULL }, -+ { "critical", 1610645508, NULL }, -+ { NULL, 131081, NULL }, -+ { "extnValue", 7, NULL }, -+ { "CertificateList", 1610612741, NULL }, -+ { "tbsCertList", 1073741826, "TBSCertList"}, -+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "signature", 6, NULL }, -+ { "TBSCertList", 1610612741, NULL }, -+ { "version", 1073758211, NULL }, -+ { "signature", 1073741826, "AlgorithmIdentifier"}, -+ { "issuer", 1073741826, "Name"}, -+ { "thisUpdate", 1073741826, "Time"}, -+ { "nextUpdate", 1073758210, "Time"}, -+ { "revokedCertificates", 1610629131, NULL }, -+ { NULL, 536870917, NULL }, -+ { "userCertificate", 1073741826, "CertificateSerialNumber"}, -+ { "revocationDate", 1073741826, "Time"}, -+ { "crlEntryExtensions", 16386, "Extensions"}, -+ { "crlExtensions", 536895490, "Extensions"}, -+ { NULL, 2056, "0"}, -+ { "AlgorithmIdentifier", 1610612741, NULL }, -+ { "algorithm", 1073741836, NULL }, -+ { "parameters", 541081613, NULL }, -+ { "algorithm", 1, NULL }, -+ { "Dss-Sig-Value", 1610612741, NULL }, -+ { "r", 1073741827, NULL }, -+ { "s", 3, NULL }, -+ { "Dss-Parms", 1610612741, NULL }, -+ { "p", 1073741827, NULL }, -+ { "q", 1073741827, NULL }, -+ { "g", 3, NULL }, -+ { "pkcs-7-ContentInfo", 1610612741, NULL }, -+ { "contentType", 1073741836, NULL }, -+ { "content", 541073421, NULL }, -+ { NULL, 1073743880, "0"}, -+ { "contentType", 1, NULL }, -+ { "pkcs-7-DigestInfo", 1610612741, NULL }, -+ { "digestAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "digest", 7, NULL }, -+ { "pkcs-7-SignedData", 1610612741, NULL }, -+ { "version", 1073741827, NULL }, -+ { "digestAlgorithms", 1073741826, "pkcs-7-DigestAlgorithmIdentifiers"}, -+ { "encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"}, -+ { "certificates", 1610637314, "pkcs-7-CertificateSet"}, -+ { NULL, 4104, "0"}, -+ { "crls", 1610637314, "pkcs-7-CertificateRevocationLists"}, -+ { NULL, 4104, "1"}, -+ { "signerInfos", 2, "pkcs-7-SignerInfos"}, -+ { "pkcs-7-DigestAlgorithmIdentifiers", 1610612751, NULL }, -+ { NULL, 2, "AlgorithmIdentifier"}, -+ { "pkcs-7-EncapsulatedContentInfo", 1610612741, NULL }, -+ { "eContentType", 1073741836, NULL }, -+ { "eContent", 536895501, NULL }, -+ { NULL, 2056, "0"}, -+ { "pkcs-7-CertificateRevocationLists", 1610612751, NULL }, -+ { NULL, 13, NULL }, -+ { "pkcs-7-CertificateChoices", 1610612754, NULL }, -+ { "certificate", 13, NULL }, -+ { "pkcs-7-CertificateSet", 1610612751, NULL }, -+ { NULL, 2, "pkcs-7-CertificateChoices"}, -+ { "IssuerAndSerialNumber", 1610612741, NULL }, -+ { "issuer", 1073741826, "Name"}, -+ { "serialNumber", 2, "CertificateSerialNumber"}, -+ { "pkcs-7-SignerInfo", 1610612741, NULL }, -+ { "version", 1073741827, NULL }, -+ { "sid", 1073741826, "SignerIdentifier"}, -+ { "digestAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "signedAttrs", 1610637314, "SignedAttributes"}, -+ { NULL, 4104, "0"}, -+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "signature", 1073741831, NULL }, -+ { "unsignedAttrs", 536895490, "SignedAttributes"}, -+ { NULL, 4104, "1"}, -+ { "SignedAttributes", 1612709903, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "Attribute"}, -+ { "SignerIdentifier", 1610612754, NULL }, -+ { "issuerAndSerialNumber", 1073741826, "IssuerAndSerialNumber"}, -+ { "subjectKeyIdentifier", 536879111, NULL }, -+ { NULL, 4104, "0"}, -+ { "pkcs-7-SignerInfos", 1610612751, NULL }, -+ { NULL, 2, "pkcs-7-SignerInfo"}, -+ { "pkcs-10-CertificationRequestInfo", 1610612741, NULL }, -+ { "version", 1073741827, NULL }, -+ { "subject", 1073741826, "Name"}, -+ { "subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"}, -+ { "attributes", 536879106, "Attributes"}, -+ { NULL, 4104, "0"}, -+ { "Attributes", 1610612751, NULL }, -+ { NULL, 2, "Attribute"}, -+ { "pkcs-10-CertificationRequest", 1610612741, NULL }, -+ { "certificationRequestInfo", 1073741826, "pkcs-10-CertificationRequestInfo"}, -+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "signature", 6, NULL }, -+ { "pkcs-9-at-challengePassword", 1879048204, NULL }, -+ { "iso", 1073741825, "1"}, -+ { "member-body", 1073741825, "2"}, -+ { "us", 1073741825, "840"}, -+ { "rsadsi", 1073741825, "113549"}, -+ { "pkcs", 1073741825, "1"}, -+ { NULL, 1073741825, "9"}, -+ { NULL, 1, "7"}, -+ { "pkcs-9-challengePassword", 1610612754, NULL }, -+ { "printableString", 1073741855, NULL }, -+ { "utf8String", 34, NULL }, -+ { "pkcs-9-localKeyId", 1073741831, NULL }, -+ { "pkcs-8-PrivateKeyInfo", 1610612741, NULL }, -+ { "version", 1073741827, NULL }, -+ { "privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "privateKey", 1073741831, NULL }, -+ { "attributes", 536895490, "Attributes"}, -+ { NULL, 4104, "0"}, -+ { "pkcs-8-EncryptedPrivateKeyInfo", 1610612741, NULL }, -+ { "encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "encryptedData", 2, "pkcs-8-EncryptedData"}, -+ { "pkcs-8-EncryptedData", 1073741831, NULL }, -+ { "pkcs-5-des-CBC-params", 1612709895, NULL }, -+ { NULL, 1048586, "8"}, -+ { "pkcs-5-des-EDE3-CBC-params", 1612709895, NULL }, -+ { NULL, 1048586, "8"}, -+ { "pkcs-5-aes128-CBC-params", 1612709895, NULL }, -+ { NULL, 1048586, "16"}, -+ { "pkcs-5-aes192-CBC-params", 1612709895, NULL }, -+ { NULL, 1048586, "16"}, -+ { "pkcs-5-aes256-CBC-params", 1612709895, NULL }, -+ { NULL, 1048586, "16"}, -+ { "Gost28147-89-Parameters", 1610612741, NULL }, -+ { "iv", 1073741831, NULL }, -+ { "encryptionParamSet", 12, NULL }, -+ { "pkcs-5-PBE-params", 1610612741, NULL }, -+ { "salt", 1073741831, NULL }, -+ { "iterationCount", 3, NULL }, -+ { "pkcs-5-PBES2-params", 1610612741, NULL }, -+ { "keyDerivationFunc", 1073741826, "AlgorithmIdentifier"}, -+ { "encryptionScheme", 2, "AlgorithmIdentifier"}, -+ { "pkcs-5-PBKDF2-params", 1610612741, NULL }, -+ { "salt", 1610612754, NULL }, -+ { "specified", 1073741831, NULL }, -+ { "otherSource", 2, "AlgorithmIdentifier"}, -+ { "iterationCount", 1611137027, NULL }, -+ { "1", 10, "MAX"}, -+ { "keyLength", 1611153411, NULL }, -+ { "1", 10, "MAX"}, -+ { "prf", 16386, "AlgorithmIdentifier"}, -+ { "pkcs-12-PFX", 1610612741, NULL }, -+ { "version", 1610874883, NULL }, -+ { "v3", 1, "3"}, -+ { "authSafe", 1073741826, "pkcs-7-ContentInfo"}, -+ { "macData", 16386, "pkcs-12-MacData"}, -+ { "pkcs-12-PbeParams", 1610612741, NULL }, -+ { "salt", 1073741831, NULL }, -+ { "iterations", 3, NULL }, -+ { "pkcs-12-MacData", 1610612741, NULL }, -+ { "mac", 1073741826, "pkcs-7-DigestInfo"}, -+ { "macSalt", 1073741831, NULL }, -+ { "iterations", 536903683, NULL }, -+ { NULL, 9, "1"}, -+ { "pkcs-12-AuthenticatedSafe", 1610612747, NULL }, -+ { NULL, 2, "pkcs-7-ContentInfo"}, -+ { "pkcs-12-SafeContents", 1610612747, NULL }, -+ { NULL, 2, "pkcs-12-SafeBag"}, -+ { "pkcs-12-SafeBag", 1610612741, NULL }, -+ { "bagId", 1073741836, NULL }, -+ { "bagValue", 1614815245, NULL }, -+ { NULL, 1073743880, "0"}, -+ { "badId", 1, NULL }, -+ { "bagAttributes", 536887311, NULL }, -+ { NULL, 2, "Attribute"}, -+ { "pkcs-12-CertBag", 1610612741, NULL }, -+ { "certId", 1073741836, NULL }, -+ { "certValue", 541073421, NULL }, -+ { NULL, 1073743880, "0"}, -+ { "certId", 1, NULL }, -+ { "pkcs-12-CRLBag", 1610612741, NULL }, -+ { "crlId", 1073741836, NULL }, -+ { "crlValue", 541073421, NULL }, -+ { NULL, 1073743880, "0"}, -+ { "crlId", 1, NULL }, -+ { "pkcs-12-SecretBag", 1610612741, NULL }, -+ { "secretTypeId", 1073741836, NULL }, -+ { "secretValue", 541073421, NULL }, -+ { NULL, 1073743880, "0"}, -+ { "secretTypeId", 1, NULL }, -+ { "pkcs-7-Data", 1073741831, NULL }, -+ { "pkcs-7-EncryptedData", 1610612741, NULL }, -+ { "version", 1073741827, NULL }, -+ { "encryptedContentInfo", 1073741826, "pkcs-7-EncryptedContentInfo"}, -+ { "unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"}, -+ { NULL, 4104, "1"}, -+ { "pkcs-7-EncryptedContentInfo", 1610612741, NULL }, -+ { "contentType", 1073741836, NULL }, -+ { "contentEncryptionAlgorithm", 1073741826, "pkcs-7-ContentEncryptionAlgorithmIdentifier"}, -+ { "encryptedContent", 536895495, NULL }, -+ { NULL, 4104, "0"}, -+ { "pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"}, -+ { "pkcs-7-UnprotectedAttributes", 1612709903, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "Attribute"}, -+ { "ProxyCertInfo", 1610612741, NULL }, -+ { "pCPathLenConstraint", 1611153411, NULL }, -+ { "0", 10, "MAX"}, -+ { "proxyPolicy", 2, "ProxyPolicy"}, -+ { "ProxyPolicy", 1610612741, NULL }, -+ { "policyLanguage", 1073741836, NULL }, -+ { "policy", 16391, NULL }, -+ { "certificatePolicies", 1612709899, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "PolicyInformation"}, -+ { "PolicyInformation", 1610612741, NULL }, -+ { "policyIdentifier", 1073741836, NULL }, -+ { "policyQualifiers", 538984459, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "PolicyQualifierInfo"}, -+ { "PolicyQualifierInfo", 1610612741, NULL }, -+ { "policyQualifierId", 1073741836, NULL }, -+ { "qualifier", 541065229, NULL }, -+ { "policyQualifierId", 1, NULL }, -+ { "CPSuri", 1073741853, NULL }, -+ { "UserNotice", 1610612741, NULL }, -+ { "noticeRef", 1073758210, "NoticeReference"}, -+ { "explicitText", 16386, "DisplayText"}, -+ { "NoticeReference", 1610612741, NULL }, -+ { "organization", 1073741826, "DisplayText"}, -+ { "noticeNumbers", 536870923, NULL }, -+ { NULL, 3, NULL }, -+ { "DisplayText", 1610612754, NULL }, -+ { "ia5String", 1612709917, NULL }, -+ { "200", 524298, "1"}, -+ { "visibleString", 1612709923, NULL }, -+ { "200", 524298, "1"}, -+ { "bmpString", 1612709921, NULL }, -+ { "200", 524298, "1"}, -+ { "utf8String", 538968098, NULL }, -+ { "200", 524298, "1"}, -+ { "OCSPRequest", 1610612741, NULL }, -+ { "tbsRequest", 1073741826, "TBSRequest"}, -+ { "optionalSignature", 536895490, "Signature"}, -+ { NULL, 2056, "0"}, -+ { "TBSRequest", 1610612741, NULL }, -+ { "version", 1610653699, NULL }, -+ { NULL, 1073741833, "0"}, -+ { NULL, 2056, "0"}, -+ { "requestorName", 1610637314, "GeneralName"}, -+ { NULL, 2056, "1"}, -+ { "requestList", 1610612747, NULL }, -+ { NULL, 2, "Request"}, -+ { "requestExtensions", 536895490, "Extensions"}, -+ { NULL, 2056, "2"}, -+ { "Signature", 1610612741, NULL }, -+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "signature", 1073741830, NULL }, -+ { "certs", 536895499, NULL }, -+ { NULL, 1073743880, "0"}, -+ { NULL, 2, "Certificate"}, -+ { "Request", 1610612741, NULL }, -+ { "reqCert", 1073741826, "CertID"}, -+ { "singleRequestExtensions", 536895490, "Extensions"}, -+ { NULL, 2056, "0"}, -+ { "CertID", 1610612741, NULL }, -+ { "hashAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "issuerNameHash", 1073741831, NULL }, -+ { "issuerKeyHash", 1073741831, NULL }, -+ { "serialNumber", 2, "CertificateSerialNumber"}, -+ { "OCSPResponse", 1610612741, NULL }, -+ { "responseStatus", 1073741826, "OCSPResponseStatus"}, -+ { "responseBytes", 536895490, "ResponseBytes"}, -+ { NULL, 2056, "0"}, -+ { "OCSPResponseStatus", 1610874901, NULL }, -+ { "successful", 1073741825, "0"}, -+ { "malformedRequest", 1073741825, "1"}, -+ { "internalError", 1073741825, "2"}, -+ { "tryLater", 1073741825, "3"}, -+ { "sigRequired", 1073741825, "5"}, -+ { "unauthorized", 1, "6"}, -+ { "ResponseBytes", 1610612741, NULL }, -+ { "responseType", 1073741836, NULL }, -+ { "response", 7, NULL }, -+ { "BasicOCSPResponse", 1610612741, NULL }, -+ { "tbsResponseData", 1073741826, "ResponseData"}, -+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"}, -+ { "signature", 1073741830, NULL }, -+ { "certs", 536895499, NULL }, -+ { NULL, 1073743880, "0"}, -+ { NULL, 2, "Certificate"}, -+ { "ResponseData", 1610612741, NULL }, -+ { "version", 1610653699, NULL }, -+ { NULL, 1073741833, "0"}, -+ { NULL, 2056, "0"}, -+ { "responderID", 1073741826, "ResponderID"}, -+ { "producedAt", 1073741861, NULL }, -+ { "responses", 1610612747, NULL }, -+ { NULL, 2, "SingleResponse"}, -+ { "responseExtensions", 536895490, "Extensions"}, -+ { NULL, 2056, "1"}, -+ { "ResponderID", 1610612754, NULL }, -+ { "byName", 1610620939, NULL }, -+ { NULL, 1073743880, "1"}, -+ { NULL, 2, "RelativeDistinguishedName"}, -+ { "byKey", 536879111, NULL }, -+ { NULL, 2056, "2"}, -+ { "SingleResponse", 1610612741, NULL }, -+ { "certID", 1073741826, "CertID"}, -+ { "certStatus", 1073741826, "CertStatus"}, -+ { "thisUpdate", 1073741861, NULL }, -+ { "nextUpdate", 1610637349, NULL }, -+ { NULL, 2056, "0"}, -+ { "singleExtensions", 536895490, "Extensions"}, -+ { NULL, 2056, "1"}, -+ { "CertStatus", 1610612754, NULL }, -+ { "good", 1610620948, NULL }, -+ { NULL, 4104, "0"}, -+ { "revoked", 1610620930, "RevokedInfo"}, -+ { NULL, 4104, "1"}, -+ { "unknown", 536879106, "UnknownInfo"}, -+ { NULL, 4104, "2"}, -+ { "RevokedInfo", 1610612741, NULL }, -+ { "revocationTime", 1073741861, NULL }, -+ { "revocationReason", 537157653, NULL }, -+ { NULL, 1073743880, "0"}, -+ { "unspecified", 1, "0"}, -+ { "UnknownInfo", 1073741844, NULL }, -+ { "NameConstraints", 1610612741, NULL }, -+ { "permittedSubtrees", 1610637314, "GeneralSubtrees"}, -+ { NULL, 4104, "0"}, -+ { "excludedSubtrees", 536895490, "GeneralSubtrees"}, -+ { NULL, 4104, "1"}, -+ { "GeneralSubtrees", 1612709899, NULL }, -+ { "MAX", 1074266122, "1"}, -+ { NULL, 2, "GeneralSubtree"}, -+ { "GeneralSubtree", 1610612741, NULL }, -+ { "base", 1073741826, "GeneralName"}, -+ { "minimum", 1610653699, NULL }, -+ { NULL, 1073741833, "0"}, -+ { NULL, 4104, "0"}, -+ { "maximum", 536895491, NULL }, -+ { NULL, 4104, "1"}, -+ { "TlsFeatures", 536870923, NULL }, -+ { NULL, 3, NULL }, -+ { NULL, 0, NULL } -+}; diff --git a/0176-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch b/0176-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch deleted file mode 100644 index 04bf1df..0000000 --- a/0176-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch +++ /dev/null @@ -1,1528 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 30 Jul 2020 01:33:46 +1000 -Subject: [PATCH] appended signatures: parse PKCS#7 signedData and X.509 - certificates - -This code allows us to parse: - - - PKCS#7 signedData messages. Only a single signerInfo is supported, - which is all that the Linux sign-file utility supports creating - out-of-the-box. Only RSA, SHA-256 and SHA-512 are supported. - Any certificate embedded in the PKCS#7 message will be ignored. - - - X.509 certificates: at least enough to verify the signatures on the - PKCS#7 messages. We expect that the certificates embedded in grub will - be leaf certificates, not CA certificates. The parser enforces this. - -Signed-off-by: Daniel Axtens ---- - grub-core/commands/appendedsig/asn1util.c | 102 +++ - grub-core/commands/appendedsig/pkcs7.c | 305 +++++++++ - grub-core/commands/appendedsig/x509.c | 958 +++++++++++++++++++++++++++ - grub-core/commands/appendedsig/appendedsig.h | 110 +++ - 4 files changed, 1475 insertions(+) - create mode 100644 grub-core/commands/appendedsig/asn1util.c - create mode 100644 grub-core/commands/appendedsig/pkcs7.c - create mode 100644 grub-core/commands/appendedsig/x509.c - create mode 100644 grub-core/commands/appendedsig/appendedsig.h - -diff --git a/grub-core/commands/appendedsig/asn1util.c b/grub-core/commands/appendedsig/asn1util.c -new file mode 100644 -index 00000000000..eff095a9df2 ---- /dev/null -+++ b/grub-core/commands/appendedsig/asn1util.c -@@ -0,0 +1,102 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "appendedsig.h" -+ -+asn1_node _gnutls_gnutls_asn = ASN1_TYPE_EMPTY; -+asn1_node _gnutls_pkix_asn = ASN1_TYPE_EMPTY; -+ -+extern const ASN1_ARRAY_TYPE gnutls_asn1_tab[]; -+extern const ASN1_ARRAY_TYPE pkix_asn1_tab[]; -+ -+/* -+ * Read a value from an ASN1 node, allocating memory to store it. -+ * -+ * It will work for anything where the size libtasn1 returns is right: -+ * - Integers -+ * - Octet strings -+ * - DER encoding of other structures -+ * It will _not_ work for things where libtasn1 size requires adjustment: -+ * - Strings that require an extra NULL byte at the end -+ * - Bit strings because libtasn1 returns the length in bits, not bytes. -+ * -+ * If the function returns a non-NULL value, the caller must free it. -+ */ -+void * -+grub_asn1_allocate_and_read (asn1_node node, const char *name, -+ const char *friendly_name, int *content_size) -+{ -+ int result; -+ grub_uint8_t *tmpstr = NULL; -+ int tmpstr_size = 0; -+ -+ result = asn1_read_value (node, name, NULL, &tmpstr_size); -+ if (result != ASN1_MEM_ERROR) -+ { -+ grub_snprintf (grub_errmsg, sizeof (grub_errmsg), -+ _ -+ ("Reading size of %s did not return expected status: %s"), -+ friendly_name, asn1_strerror (result)); -+ grub_errno = GRUB_ERR_BAD_FILE_TYPE; -+ return NULL; -+ } -+ -+ tmpstr = grub_malloc (tmpstr_size); -+ if (tmpstr == NULL) -+ { -+ grub_snprintf (grub_errmsg, sizeof (grub_errmsg), -+ "Could not allocate memory to store %s", friendly_name); -+ grub_errno = GRUB_ERR_OUT_OF_MEMORY; -+ return NULL; -+ } -+ -+ result = asn1_read_value (node, name, tmpstr, &tmpstr_size); -+ if (result != ASN1_SUCCESS) -+ { -+ grub_free (tmpstr); -+ grub_snprintf (grub_errmsg, sizeof (grub_errmsg), -+ "Error reading %s: %s", -+ friendly_name, asn1_strerror (result)); -+ grub_errno = GRUB_ERR_BAD_FILE_TYPE; -+ return NULL; -+ } -+ -+ *content_size = tmpstr_size; -+ -+ return tmpstr; -+} -+ -+int -+asn1_init (void) -+{ -+ int res; -+ res = asn1_array2tree (gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL); -+ if (res != ASN1_SUCCESS) -+ { -+ return res; -+ } -+ res = asn1_array2tree (pkix_asn1_tab, &_gnutls_pkix_asn, NULL); -+ return res; -+} -diff --git a/grub-core/commands/appendedsig/pkcs7.c b/grub-core/commands/appendedsig/pkcs7.c -new file mode 100644 -index 00000000000..dc6afe203f7 ---- /dev/null -+++ b/grub-core/commands/appendedsig/pkcs7.c -@@ -0,0 +1,305 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include "appendedsig.h" -+#include -+#include -+#include -+ -+ -+static char asn1_error[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; -+ -+/* -+ * RFC 5652 s 5.1 -+ */ -+const char *signedData_oid = "1.2.840.113549.1.7.2"; -+ -+/* -+ * RFC 4055 s 2.1 -+ */ -+const char *sha256_oid = "2.16.840.1.101.3.4.2.1"; -+const char *sha512_oid = "2.16.840.1.101.3.4.2.3"; -+ -+static grub_err_t -+process_content (grub_uint8_t * content, int size, -+ struct pkcs7_signedData *msg) -+{ -+ int res; -+ asn1_node signed_part; -+ grub_err_t err = GRUB_ERR_NONE; -+ char algo_oid[MAX_OID_LEN]; -+ int algo_oid_size = sizeof (algo_oid); -+ int algo_count; -+ char version; -+ int version_size = sizeof (version); -+ grub_uint8_t *result_buf; -+ int result_size = 0; -+ int crls_size = 0; -+ gcry_error_t gcry_err; -+ -+ res = asn1_create_element (_gnutls_pkix_asn, "PKIX1.pkcs-7-SignedData", -+ &signed_part); -+ if (res != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not create ASN.1 structure for PKCS#7 signed part."); -+ } -+ -+ res = asn1_der_decoding2 (&signed_part, content, &size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (res != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error reading PKCS#7 signed data: %s", asn1_error); -+ goto cleanup_signed_part; -+ } -+ -+ /* SignedData ::= SEQUENCE { -+ * version CMSVersion, -+ * digestAlgorithms DigestAlgorithmIdentifiers, -+ * encapContentInfo EncapsulatedContentInfo, -+ * certificates [0] IMPLICIT CertificateSet OPTIONAL, -+ * crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, -+ * signerInfos SignerInfos } -+ */ -+ -+ /* version per the algo in 5.1, must be 1 */ -+ res = asn1_read_value (signed_part, "version", &version, &version_size); -+ if (res != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error reading signedData version: %s", -+ asn1_strerror (res)); -+ goto cleanup_signed_part; -+ } -+ -+ if (version != 1) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Unexpected signature version v%d, only v1 supported", -+ version); -+ goto cleanup_signed_part; -+ } -+ -+ /* -+ * digestAlgorithms DigestAlgorithmIdentifiers -+ * -+ * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier -+ * DigestAlgorithmIdentifer is an X.509 AlgorithmIdentifier (10.1.1) -+ * -+ * RFC 4055 s 2.1: -+ * sha256Identifier AlgorithmIdentifier ::= { id-sha256, NULL } -+ * sha512Identifier AlgorithmIdentifier ::= { id-sha512, NULL } -+ * -+ * We only support 1 element in the set, and we do not check parameters atm. -+ */ -+ res = -+ asn1_number_of_elements (signed_part, "digestAlgorithms", &algo_count); -+ if (res != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error counting number of digest algorithms: %s", -+ asn1_strerror (res)); -+ goto cleanup_signed_part; -+ } -+ -+ if (algo_count != 1) -+ { -+ err = -+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ "Only 1 digest algorithm is supported"); -+ goto cleanup_signed_part; -+ } -+ -+ res = -+ asn1_read_value (signed_part, "digestAlgorithms.?1.algorithm", algo_oid, -+ &algo_oid_size); -+ if (res != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error reading digest algorithm: %s", -+ asn1_strerror (res)); -+ goto cleanup_signed_part; -+ } -+ -+ if (grub_strncmp (sha512_oid, algo_oid, algo_oid_size) == 0) -+ { -+ msg->hash = grub_crypto_lookup_md_by_name ("sha512"); -+ } -+ else if (grub_strncmp (sha256_oid, algo_oid, algo_oid_size) == 0) -+ { -+ msg->hash = grub_crypto_lookup_md_by_name ("sha256"); -+ } -+ else -+ { -+ err = -+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ "Only SHA-256 and SHA-512 hashes are supported, found OID %s", -+ algo_oid); -+ goto cleanup_signed_part; -+ } -+ -+ if (!msg->hash) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Hash algorithm for OID %s not loaded", algo_oid); -+ goto cleanup_signed_part; -+ } -+ -+ /* -+ * We ignore the certificates, but we don't permit CRLs. -+ * A CRL entry might be revoking the certificate we're using, and we have -+ * no way of dealing with that at the moment. -+ */ -+ res = asn1_read_value (signed_part, "crls", NULL, &crls_size); -+ if (res != ASN1_ELEMENT_NOT_FOUND) -+ { -+ err = -+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ "PKCS#7 messages with embedded CRLs are not supported"); -+ goto cleanup_signed_part; -+ } -+ -+ /* read the signature */ -+ result_buf = -+ grub_asn1_allocate_and_read (signed_part, "signerInfos.?1.signature", -+ "signature data", &result_size); -+ if (!result_buf) -+ { -+ err = grub_errno; -+ goto cleanup_signed_part; -+ } -+ -+ gcry_err = -+ gcry_mpi_scan (&(msg->sig_mpi), GCRYMPI_FMT_USG, result_buf, result_size, -+ NULL); -+ if (gcry_err != GPG_ERR_NO_ERROR) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error loading signature into MPI structure: %d", -+ gcry_err); -+ goto cleanup_result; -+ } -+ -+cleanup_result: -+ grub_free (result_buf); -+cleanup_signed_part: -+ asn1_delete_structure (&signed_part); -+ -+ return err; -+} -+ -+grub_err_t -+parse_pkcs7_signedData (void *sigbuf, grub_size_t data_size, -+ struct pkcs7_signedData *msg) -+{ -+ int res; -+ asn1_node content_info; -+ grub_err_t err = GRUB_ERR_NONE; -+ char content_oid[MAX_OID_LEN]; -+ grub_uint8_t *content; -+ int content_size; -+ int content_oid_size = sizeof (content_oid); -+ int size; -+ -+ if (data_size > GRUB_INT_MAX) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ "Cannot parse a PKCS#7 message where data size > INT_MAX"); -+ size = (int) data_size; -+ -+ res = asn1_create_element (_gnutls_pkix_asn, -+ "PKIX1.pkcs-7-ContentInfo", &content_info); -+ if (res != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not create ASN.1 structure for PKCS#7 data: %s", -+ asn1_strerror (res)); -+ } -+ -+ res = asn1_der_decoding2 (&content_info, sigbuf, &size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (res != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error decoding PKCS#7 message DER: %s", asn1_error); -+ goto cleanup; -+ } -+ -+ /* -+ * ContentInfo ::= SEQUENCE { -+ * contentType ContentType, -+ * content [0] EXPLICIT ANY DEFINED BY contentType } -+ * -+ * ContentType ::= OBJECT IDENTIFIER -+ */ -+ res = -+ asn1_read_value (content_info, "contentType", content_oid, -+ &content_oid_size); -+ if (res != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error reading PKCS#7 content type: %s", -+ asn1_strerror (res)); -+ goto cleanup; -+ } -+ -+ /* OID for SignedData defined in 5.1 */ -+ if (grub_strncmp (signedData_oid, content_oid, content_oid_size) != 0) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Unexpected content type in PKCS#7 message: OID %s", -+ content_oid); -+ goto cleanup; -+ } -+ -+ content = -+ grub_asn1_allocate_and_read (content_info, "content", -+ "PKCS#7 message content", &content_size); -+ if (!content) -+ { -+ err = grub_errno; -+ goto cleanup; -+ } -+ -+ err = process_content (content, content_size, msg); -+ grub_free (content); -+ -+cleanup: -+ asn1_delete_structure (&content_info); -+ return err; -+} -+ -+/* -+ * Release all the storage associated with the PKCS#7 message. -+ * If the caller dynamically allocated the message, it must free it. -+ */ -+void -+pkcs7_signedData_release (struct pkcs7_signedData *msg) -+{ -+ gcry_mpi_release (msg->sig_mpi); -+} -diff --git a/grub-core/commands/appendedsig/x509.c b/grub-core/commands/appendedsig/x509.c -new file mode 100644 -index 00000000000..2b38b3670a2 ---- /dev/null -+++ b/grub-core/commands/appendedsig/x509.c -@@ -0,0 +1,958 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "appendedsig.h" -+ -+static char asn1_error[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; -+ -+/* -+ * RFC 3279 2.3.1 RSA Keys -+ */ -+const char *rsaEncryption_oid = "1.2.840.113549.1.1.1"; -+ -+/* -+ * RFC 5280 Appendix A -+ */ -+const char *commonName_oid = "2.5.4.3"; -+ -+/* -+ * RFC 5280 4.2.1.3 Key Usage -+ */ -+const char *keyUsage_oid = "2.5.29.15"; -+ -+/* -+ * RFC 5280 4.2.1.9 Basic Constraints -+ */ -+const char *basicConstraints_oid = "2.5.29.19"; -+ -+/* -+ * RFC 3279 2.3.1 -+ * -+ * The RSA public key MUST be encoded using the ASN.1 type RSAPublicKey: -+ * -+ * RSAPublicKey ::= SEQUENCE { -+ * modulus INTEGER, -- n -+ * publicExponent INTEGER } -- e -+ * -+ * where modulus is the modulus n, and publicExponent is the public -+ * exponent e. -+ */ -+static grub_err_t -+grub_parse_rsa_pubkey (grub_uint8_t * der, int dersize, -+ struct x509_certificate *certificate) -+{ -+ int result; -+ asn1_node spk = ASN1_TYPE_EMPTY; -+ grub_uint8_t *m_data, *e_data; -+ int m_size, e_size; -+ grub_err_t err = GRUB_ERR_NONE; -+ gcry_error_t gcry_err; -+ -+ result = -+ asn1_create_element (_gnutls_gnutls_asn, "GNUTLS.RSAPublicKey", &spk); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Cannot create storage for public key ASN.1 data"); -+ } -+ -+ result = asn1_der_decoding2 (&spk, der, &dersize, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Cannot decode certificate public key DER: %s", -+ asn1_error); -+ goto cleanup; -+ } -+ -+ m_data = -+ grub_asn1_allocate_and_read (spk, "modulus", "RSA modulus", &m_size); -+ if (!m_data) -+ { -+ err = grub_errno; -+ goto cleanup; -+ } -+ -+ e_data = -+ grub_asn1_allocate_and_read (spk, "publicExponent", "RSA public exponent", -+ &e_size); -+ if (!e_data) -+ { -+ err = grub_errno; -+ goto cleanup_m_data; -+ } -+ -+ /* -+ * convert m, e to mpi -+ * -+ * nscanned is not set for FMT_USG, it's only set for FMT_PGP, -+ * so we can't verify it -+ */ -+ gcry_err = -+ gcry_mpi_scan (&certificate->mpis[0], GCRYMPI_FMT_USG, m_data, m_size, -+ NULL); -+ if (gcry_err != GPG_ERR_NO_ERROR) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error loading RSA modulus into MPI structure: %d", -+ gcry_err); -+ goto cleanup_e_data; -+ } -+ -+ gcry_err = -+ gcry_mpi_scan (&certificate->mpis[1], GCRYMPI_FMT_USG, e_data, e_size, -+ NULL); -+ if (gcry_err != GPG_ERR_NO_ERROR) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error loading RSA exponent into MPI structure: %d", -+ gcry_err); -+ goto cleanup_m_mpi; -+ } -+ -+ grub_free (e_data); -+ grub_free (m_data); -+ asn1_delete_structure (&spk); -+ return GRUB_ERR_NONE; -+ -+cleanup_m_mpi: -+ gcry_mpi_release (certificate->mpis[0]); -+cleanup_e_data: -+ grub_free (e_data); -+cleanup_m_data: -+ grub_free (m_data); -+cleanup: -+ asn1_delete_structure (&spk); -+ return err; -+} -+ -+ -+/* -+ * RFC 5280: -+ * SubjectPublicKeyInfo ::= SEQUENCE { -+ * algorithm AlgorithmIdentifier, -+ * subjectPublicKey BIT STRING } -+ * -+ * AlgorithmIdentifiers come from RFC 3279, we are not strictly compilant as we -+ * only support RSA Encryption. -+ */ -+ -+static grub_err_t -+grub_x509_read_subject_public_key (asn1_node asn, -+ struct x509_certificate *results) -+{ -+ int result; -+ grub_err_t err; -+ const char *algo_name = -+ "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm"; -+ const char *params_name = -+ "tbsCertificate.subjectPublicKeyInfo.algorithm.parameters"; -+ const char *pk_name = -+ "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey"; -+ char algo_oid[MAX_OID_LEN]; -+ int algo_size = sizeof (algo_oid); -+ char params_value[2]; -+ int params_size = sizeof (params_value); -+ grub_uint8_t *key_data = NULL; -+ int key_size = 0; -+ unsigned int key_type; -+ -+ /* algorithm: see notes for rsaEncryption_oid */ -+ result = asn1_read_value (asn, algo_name, algo_oid, &algo_size); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading x509 public key algorithm: %s", -+ asn1_strerror (result)); -+ } -+ -+ if (grub_strncmp (algo_oid, rsaEncryption_oid, sizeof (rsaEncryption_oid)) -+ != 0) -+ { -+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ "Unsupported x509 public key algorithm: %s", -+ algo_oid); -+ } -+ -+ /* -+ * RFC 3279 2.3.1 -+ * The rsaEncryption OID is intended to be used in the algorithm field -+ * of a value of type AlgorithmIdentifier. The parameters field MUST -+ * have ASN.1 type NULL for this algorithm identifier. -+ */ -+ result = asn1_read_value (asn, params_name, params_value, ¶ms_size); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading x509 public key parameters: %s", -+ asn1_strerror (result)); -+ } -+ -+ if (params_value[0] != ASN1_TAG_NULL) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Invalid x509 public key parameters: expected NULL"); -+ } -+ -+ /* -+ * RFC 3279 2.3.1: The DER encoded RSAPublicKey is the value of the BIT -+ * STRING subjectPublicKey. -+ */ -+ result = asn1_read_value_type (asn, pk_name, NULL, &key_size, &key_type); -+ if (result != ASN1_MEM_ERROR) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading size of x509 public key: %s", -+ asn1_strerror (result)); -+ } -+ if (key_type != ASN1_ETYPE_BIT_STRING) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Unexpected ASN.1 type when reading x509 public key: %x", -+ key_type); -+ } -+ -+ /* length is in bits */ -+ key_size = (key_size + 7) / 8; -+ -+ key_data = grub_malloc (key_size); -+ if (!key_data) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Out of memory for x509 public key"); -+ } -+ -+ result = asn1_read_value (asn, pk_name, key_data, &key_size); -+ if (result != ASN1_SUCCESS) -+ { -+ grub_free (key_data); -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading public key data"); -+ } -+ key_size = (key_size + 7) / 8; -+ -+ err = grub_parse_rsa_pubkey (key_data, key_size, results); -+ grub_free (key_data); -+ -+ return err; -+} -+ -+/* Decode a string as defined in Appendix A */ -+static grub_err_t -+decode_string (char *der, int der_size, char **string, -+ grub_size_t * string_size) -+{ -+ asn1_node strasn; -+ int result; -+ char *choice; -+ int choice_size = 0; -+ int tmp_size = 0; -+ grub_err_t err = GRUB_ERR_NONE; -+ -+ result = -+ asn1_create_element (_gnutls_pkix_asn, "PKIX1.DirectoryString", &strasn); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not create ASN.1 structure for certificate: %s", -+ asn1_strerror (result)); -+ } -+ -+ result = asn1_der_decoding2 (&strasn, der, &der_size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Could not parse DER for DirectoryString: %s", -+ asn1_error); -+ goto cleanup; -+ } -+ -+ choice = -+ grub_asn1_allocate_and_read (strasn, "", "DirectoryString choice", -+ &choice_size); -+ if (!choice) -+ { -+ err = grub_errno; -+ goto cleanup; -+ } -+ -+ if (grub_strncmp ("utf8String", choice, choice_size)) -+ { -+ err = -+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ "Only UTF-8 DirectoryStrings are supported, got %s", -+ choice); -+ goto cleanup_choice; -+ } -+ -+ result = asn1_read_value (strasn, "utf8String", NULL, &tmp_size); -+ if (result != ASN1_MEM_ERROR) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading size of UTF-8 string: %s", -+ asn1_strerror (result)); -+ goto cleanup_choice; -+ } -+ -+ /* read size does not include trailing null */ -+ tmp_size++; -+ -+ *string = grub_malloc (tmp_size); -+ if (!*string) -+ { -+ err = -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Cannot allocate memory for DirectoryString contents"); -+ goto cleanup_choice; -+ } -+ -+ result = asn1_read_value (strasn, "utf8String", *string, &tmp_size); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading out UTF-8 string in DirectoryString: %s", -+ asn1_strerror (result)); -+ grub_free (*string); -+ goto cleanup_choice; -+ } -+ *string_size = tmp_size + 1; -+ (*string)[tmp_size] = '\0'; -+ -+cleanup_choice: -+ grub_free (choice); -+cleanup: -+ asn1_delete_structure (&strasn); -+ return err; -+} -+ -+/* -+ * TBSCertificate ::= SEQUENCE { -+ * version [0] EXPLICIT Version DEFAULT v1, -+ * ... -+ * -+ * Version ::= INTEGER { v1(0), v2(1), v3(2) } -+ */ -+static grub_err_t -+check_version (asn1_node certificate) -+{ -+ int rc; -+ const char *name = "tbsCertificate.version"; -+ grub_uint8_t version; -+ int len = 1; -+ -+ rc = asn1_read_value (certificate, name, &version, &len); -+ -+ /* require version 3 */ -+ if (rc != ASN1_SUCCESS || len != 1) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading certificate version"); -+ -+ if (version != 0x02) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Invalid x509 certificate version, expected v3 (0x02), got 0x%02x", -+ version); -+ -+ return GRUB_ERR_NONE; -+} -+ -+/* -+ * This is an X.501 Name, which is complex. -+ * -+ * For simplicity, we extract only the CN. -+ */ -+static grub_err_t -+read_name (asn1_node asn, const char *name_path, char **name, -+ grub_size_t * name_size) -+{ -+ int seq_components, set_components; -+ int result; -+ int i, j; -+ char *top_path, *set_path, *type_path, *val_path; -+ char type[MAX_OID_LEN]; -+ int type_len = sizeof (type); -+ int string_size = 0; -+ char *string_der; -+ grub_err_t err; -+ -+ *name = NULL; -+ -+ top_path = grub_xasprintf ("%s.rdnSequence", name_path); -+ if (!top_path) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not allocate memory for %s name parsing path", -+ name_path); -+ -+ result = asn1_number_of_elements (asn, top_path, &seq_components); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error counting name components: %s", -+ asn1_strerror (result)); -+ goto cleanup; -+ } -+ -+ for (i = 1; i <= seq_components; i++) -+ { -+ set_path = grub_xasprintf ("%s.?%d", top_path, i); -+ if (!set_path) -+ { -+ err = -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not allocate memory for %s name set parsing path", -+ name_path); -+ goto cleanup_set; -+ } -+ /* this brings us, hopefully, to a set */ -+ result = asn1_number_of_elements (asn, set_path, &set_components); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error counting name sub-components components (element %d): %s", -+ i, asn1_strerror (result)); -+ goto cleanup_set; -+ } -+ for (j = 1; j <= set_components; j++) -+ { -+ type_path = grub_xasprintf ("%s.?%d.?%d.type", top_path, i, j); -+ if (!type_path) -+ { -+ err = -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not allocate memory for %s name component type path", -+ name_path); -+ goto cleanup_set; -+ } -+ type_len = sizeof (type); -+ result = asn1_read_value (asn, type_path, type, &type_len); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading %s name component type: %s", -+ name_path, asn1_strerror (result)); -+ goto cleanup_type; -+ } -+ -+ if (grub_strncmp (type, commonName_oid, type_len) != 0) -+ { -+ grub_free (type_path); -+ continue; -+ } -+ -+ val_path = grub_xasprintf ("%s.?%d.?%d.value", top_path, i, j); -+ if (!val_path) -+ { -+ err = -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not allocate memory for %s name component value path", -+ name_path); -+ goto cleanup_set; -+ } -+ -+ string_der = -+ grub_asn1_allocate_and_read (asn, val_path, name_path, -+ &string_size); -+ if (!string_der) -+ { -+ err = grub_errno; -+ goto cleanup_val_path; -+ } -+ -+ err = decode_string (string_der, string_size, name, name_size); -+ if (err) -+ goto cleanup_string; -+ -+ grub_free (string_der); -+ grub_free (type_path); -+ grub_free (val_path); -+ break; -+ } -+ grub_free (set_path); -+ -+ if (*name) -+ break; -+ } -+ -+ return GRUB_ERR_NONE; -+ -+cleanup_string: -+ grub_free (string_der); -+cleanup_val_path: -+ grub_free (val_path); -+cleanup_type: -+ grub_free (type_path); -+cleanup_set: -+ grub_free (set_path); -+cleanup: -+ grub_free (top_path); -+ return err; -+} -+ -+/* -+ * details here -+ */ -+static grub_err_t -+verify_key_usage (grub_uint8_t * value, int value_size) -+{ -+ asn1_node usageasn; -+ int result; -+ grub_err_t err = GRUB_ERR_NONE; -+ grub_uint8_t usage = 0xff; -+ int usage_size = 1; -+ -+ result = -+ asn1_create_element (_gnutls_pkix_asn, "PKIX1.KeyUsage", &usageasn); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not create ASN.1 structure for key usage"); -+ } -+ -+ result = asn1_der_decoding2 (&usageasn, value, &value_size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error parsing DER for Key Usage: %s", asn1_error); -+ goto cleanup; -+ } -+ -+ result = asn1_read_value (usageasn, "", &usage, &usage_size); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading Key Usage value: %s", -+ asn1_strerror (result)); -+ goto cleanup; -+ } -+ -+ /* Only the first bit is permitted to be set */ -+ if (usage != 0x80) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unexpected Key Usage value: %x", -+ usage); -+ goto cleanup; -+ } -+ -+cleanup: -+ asn1_delete_structure (&usageasn); -+ return err; -+} -+ -+/* -+ * BasicConstraints ::= SEQUENCE { -+ * cA BOOLEAN DEFAULT FALSE, -+ * pathLenConstraint INTEGER (0..MAX) OPTIONAL } -+ */ -+static grub_err_t -+verify_basic_constraints (grub_uint8_t * value, int value_size) -+{ -+ asn1_node basicasn; -+ int result; -+ grub_err_t err = GRUB_ERR_NONE; -+ char cA[6]; /* FALSE or TRUE */ -+ int cA_size = sizeof (cA); -+ -+ result = -+ asn1_create_element (_gnutls_pkix_asn, "PKIX1.BasicConstraints", -+ &basicasn); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not create ASN.1 structure for Basic Constraints"); -+ } -+ -+ result = asn1_der_decoding2 (&basicasn, value, &value_size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error parsing DER for Basic Constraints: %s", -+ asn1_error); -+ goto cleanup; -+ } -+ -+ result = asn1_read_value (basicasn, "cA", cA, &cA_size); -+ if (result == ASN1_ELEMENT_NOT_FOUND) -+ { -+ /* Not present, default is False, so this is OK */ -+ err = GRUB_ERR_NONE; -+ goto cleanup; -+ } -+ else if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading Basic Constraints cA value: %s", -+ asn1_strerror (result)); -+ goto cleanup; -+ } -+ -+ /* The certificate must not be a CA certificate */ -+ if (grub_strncmp ("FALSE", cA, cA_size) != 0) -+ { -+ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unexpected CA value: %s", -+ cA); -+ goto cleanup; -+ } -+ -+cleanup: -+ asn1_delete_structure (&basicasn); -+ return err; -+} -+ -+ -+/* -+ * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension -+ * -+ * Extension ::= SEQUENCE { -+ * extnID OBJECT IDENTIFIER, -+ * critical BOOLEAN DEFAULT FALSE, -+ * extnValue OCTET STRING -+ * -- contains the DER encoding of an ASN.1 value -+ * -- corresponding to the extension type identified -+ * -- by extnID -+ * } -+ * -+ * We require that a certificate: -+ * - contain the Digital Signature usage only -+ * - not be a CA -+ * - MUST not contain any other critical extensions (RFC 5280 s 4.2) -+ */ -+static grub_err_t -+verify_extensions (asn1_node cert) -+{ -+ int result; -+ int ext, num_extensions = 0; -+ int usage_present = 0, constraints_present = 0; -+ char *oid_path, *critical_path, *value_path; -+ char extnID[MAX_OID_LEN]; -+ int extnID_size; -+ grub_err_t err; -+ char critical[6]; /* we get either "TRUE" or "FALSE" */ -+ int critical_size; -+ grub_uint8_t *value; -+ int value_size; -+ -+ result = -+ asn1_number_of_elements (cert, "tbsCertificate.extensions", -+ &num_extensions); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error counting number of extensions: %s", -+ asn1_strerror (result)); -+ } -+ -+ if (num_extensions < 2) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Insufficient number of extensions for certificate, need at least 2, got %d", -+ num_extensions); -+ } -+ -+ for (ext = 1; ext <= num_extensions; ext++) -+ { -+ oid_path = grub_xasprintf ("tbsCertificate.extensions.?%d.extnID", ext); -+ -+ extnID_size = sizeof (extnID); -+ result = asn1_read_value (cert, oid_path, extnID, &extnID_size); -+ if (result != GRUB_ERR_NONE) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading extension OID: %s", -+ asn1_strerror (result)); -+ goto cleanup_oid_path; -+ } -+ -+ critical_path = -+ grub_xasprintf ("tbsCertificate.extensions.?%d.critical", ext); -+ critical_size = sizeof (critical); -+ result = -+ asn1_read_value (cert, critical_path, critical, &critical_size); -+ if (result == ASN1_ELEMENT_NOT_FOUND) -+ { -+ critical[0] = '\0'; -+ } -+ else if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading extension criticality: %s", -+ asn1_strerror (result)); -+ goto cleanup_critical_path; -+ } -+ -+ value_path = -+ grub_xasprintf ("tbsCertificate.extensions.?%d.extnValue", ext); -+ value = -+ grub_asn1_allocate_and_read (cert, value_path, -+ "certificate extension value", -+ &value_size); -+ if (!value) -+ { -+ err = grub_errno; -+ goto cleanup_value_path; -+ } -+ -+ /* -+ * Now we must see if we recognise the OID. -+ * If we have an unrecognised critical extension we MUST bail. -+ */ -+ if (grub_strncmp (keyUsage_oid, extnID, extnID_size) == 0) -+ { -+ err = verify_key_usage (value, value_size); -+ if (err != GRUB_ERR_NONE) -+ { -+ goto cleanup_value; -+ } -+ usage_present++; -+ } -+ else if (grub_strncmp (basicConstraints_oid, extnID, extnID_size) == 0) -+ { -+ err = verify_basic_constraints (value, value_size); -+ if (err != GRUB_ERR_NONE) -+ { -+ goto cleanup_value; -+ } -+ constraints_present++; -+ } -+ else if (grub_strncmp ("TRUE", critical, critical_size) == 0) -+ { -+ /* -+ * per the RFC, we must not process a certificate with -+ * a critical extension we do not understand. -+ */ -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Unhandled critical x509 extension with OID %s", -+ extnID); -+ goto cleanup_value; -+ } -+ -+ grub_free (value); -+ grub_free (value_path); -+ grub_free (critical_path); -+ grub_free (oid_path); -+ } -+ -+ if (usage_present != 1) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Unexpected number of Key Usage extensions - expected 1, got %d", -+ usage_present); -+ } -+ if (constraints_present != 1) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Unexpected number of basic constraints extensions - expected 1, got %d", -+ constraints_present); -+ } -+ return GRUB_ERR_NONE; -+ -+cleanup_value: -+ grub_free (value); -+cleanup_value_path: -+ grub_free (value_path); -+cleanup_critical_path: -+ grub_free (critical_path); -+cleanup_oid_path: -+ grub_free (oid_path); -+ return err; -+} -+ -+/* -+ * Parse a certificate whose DER-encoded form is in @data, of size @data_size. -+ * Return the results in @results, which must point to an allocated x509 certificate. -+ */ -+grub_err_t -+certificate_import (void *data, grub_size_t data_size, -+ struct x509_certificate *results) -+{ -+ int result = 0; -+ asn1_node cert; -+ grub_err_t err; -+ int size; -+ int tmp_size; -+ -+ if (data_size > GRUB_INT_MAX) -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ "Cannot parse a certificate where data size > INT_MAX"); -+ size = (int) data_size; -+ -+ result = asn1_create_element (_gnutls_pkix_asn, "PKIX1.Certificate", &cert); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not create ASN.1 structure for certificate: %s", -+ asn1_strerror (result)); -+ } -+ -+ result = asn1_der_decoding2 (&cert, data, &size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Could not parse DER for certificate: %s", asn1_error); -+ goto cleanup; -+ } -+ -+ /* -+ * TBSCertificate ::= SEQUENCE { -+ * version [0] EXPLICIT Version DEFAULT v1 -+ */ -+ err = check_version (cert); -+ if (err != GRUB_ERR_NONE) -+ { -+ goto cleanup; -+ } -+ -+ /* -+ * serialNumber CertificateSerialNumber, -+ * -+ * CertificateSerialNumber ::= INTEGER -+ */ -+ results->serial = -+ grub_asn1_allocate_and_read (cert, "tbsCertificate.serialNumber", -+ "certificate serial number", &tmp_size); -+ if (!results->serial) -+ { -+ err = grub_errno; -+ goto cleanup; -+ } -+ /* -+ * It's safe to cast the signed int to an unsigned here, we know -+ * length is non-negative -+ */ -+ results->serial_len = tmp_size; -+ -+ /* -+ * signature AlgorithmIdentifier, -+ * -+ * We don't load the signature or issuer at the moment, -+ * as we don't attempt x509 verification. -+ */ -+ -+ /* -+ * issuer Name, -+ * -+ * The RFC only requires the serial number to be unique within -+ * issuers, so to avoid ambiguity we _technically_ ought to make -+ * this available. -+ */ -+ -+ /* -+ * validity Validity, -+ * -+ * Validity ::= SEQUENCE { -+ * notBefore Time, -+ * notAfter Time } -+ * -+ * We can't validate this reasonably, we have no true time source on several -+ * platforms. For now we do not parse them. -+ */ -+ -+ /* -+ * subject Name, -+ * -+ * This is an X501 name, we parse out just the CN. -+ */ -+ err = -+ read_name (cert, "tbsCertificate.subject", &results->subject, -+ &results->subject_len); -+ if (err != GRUB_ERR_NONE) -+ goto cleanup_serial; -+ -+ /* -+ * TBSCertificate ::= SEQUENCE { -+ * ... -+ * subjectPublicKeyInfo SubjectPublicKeyInfo, -+ * ... -+ */ -+ err = grub_x509_read_subject_public_key (cert, results); -+ if (err != GRUB_ERR_NONE) -+ goto cleanup_name; -+ -+ /* -+ * TBSCertificate ::= SEQUENCE { -+ * ... -+ * extensions [3] EXPLICIT Extensions OPTIONAL -+ * -- If present, version MUST be v3 -+ * } -+ */ -+ -+ err = verify_extensions (cert); -+ if (err != GRUB_ERR_NONE) -+ goto cleanup_name; -+ -+ -+ /* -+ * We do not read or check the signature on the certificate: -+ * as discussed we do not try to validate the certificate but trust -+ * it implictly. -+ */ -+ -+ asn1_delete_structure (&cert); -+ return GRUB_ERR_NONE; -+ -+ -+cleanup_name: -+ grub_free (results->subject); -+cleanup_serial: -+ grub_free (results->serial); -+cleanup: -+ asn1_delete_structure (&cert); -+ return err; -+} -+ -+/* -+ * Release all the storage associated with the x509 certificate. -+ * If the caller dynamically allocated the certificate, it must free it. -+ * The caller is also responsible for maintenance of the linked list. -+ */ -+void -+certificate_release (struct x509_certificate *cert) -+{ -+ grub_free (cert->subject); -+ grub_free (cert->serial); -+ gcry_mpi_release (cert->mpis[0]); -+ gcry_mpi_release (cert->mpis[1]); -+} -diff --git a/grub-core/commands/appendedsig/appendedsig.h b/grub-core/commands/appendedsig/appendedsig.h -new file mode 100644 -index 00000000000..9792ef3901e ---- /dev/null -+++ b/grub-core/commands/appendedsig/appendedsig.h -@@ -0,0 +1,110 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+ -+extern asn1_node _gnutls_gnutls_asn; -+extern asn1_node _gnutls_pkix_asn; -+ -+#define MAX_OID_LEN 32 -+ -+/* -+ * One or more x509 certificates. -+ * -+ * We do limited parsing: extracting only the serial, CN and RSA public key. -+ */ -+struct x509_certificate -+{ -+ struct x509_certificate *next; -+ -+ grub_uint8_t *serial; -+ grub_size_t serial_len; -+ -+ char *subject; -+ grub_size_t subject_len; -+ -+ /* We only support RSA public keys. This encodes [modulus, publicExponent] */ -+ gcry_mpi_t mpis[2]; -+}; -+ -+/* -+ * A PKCS#7 signedData message. -+ * -+ * We make no attempt to match intelligently, so we don't save any info about -+ * the signer. We also support only 1 signerInfo, so we only store a single -+ * MPI for the signature. -+ */ -+struct pkcs7_signedData -+{ -+ const gcry_md_spec_t *hash; -+ gcry_mpi_t sig_mpi; -+}; -+ -+ -+/* Do libtasn1 init */ -+int asn1_init (void); -+ -+/* -+ * Import a DER-encoded certificate at 'data', of size 'size'. -+ * -+ * Place the results into 'results', which must be already allocated. -+ */ -+grub_err_t -+certificate_import (void *data, grub_size_t size, -+ struct x509_certificate *results); -+ -+/* -+ * Release all the storage associated with the x509 certificate. -+ * If the caller dynamically allocated the certificate, it must free it. -+ * The caller is also responsible for maintenance of the linked list. -+ */ -+void certificate_release (struct x509_certificate *cert); -+ -+/* -+ * Parse a PKCS#7 message, which must be a signedData message. -+ * -+ * The message must be in 'sigbuf' and of size 'data_size'. The result is -+ * placed in 'msg', which must already be allocated. -+ */ -+grub_err_t -+parse_pkcs7_signedData (void *sigbuf, grub_size_t data_size, -+ struct pkcs7_signedData *msg); -+ -+/* -+ * Release all the storage associated with the PKCS#7 message. -+ * If the caller dynamically allocated the message, it must free it. -+ */ -+void pkcs7_signedData_release (struct pkcs7_signedData *msg); -+ -+/* -+ * Read a value from an ASN1 node, allocating memory to store it. -+ * -+ * It will work for anything where the size libtasn1 returns is right: -+ * - Integers -+ * - Octet strings -+ * - DER encoding of other structures -+ * It will _not_ work for things where libtasn1 size requires adjustment: -+ * - Strings that require an extra NULL byte at the end -+ * - Bit strings because libtasn1 returns the length in bits, not bytes. -+ * -+ * If the function returns a non-NULL value, the caller must free it. -+ */ -+void *grub_asn1_allocate_and_read (asn1_node node, const char *name, -+ const char *friendly_name, -+ int *content_size); diff --git a/0177-appended-signatures-support-verifying-appended-signa.patch b/0177-appended-signatures-support-verifying-appended-signa.patch deleted file mode 100644 index 262efc0..0000000 --- a/0177-appended-signatures-support-verifying-appended-signa.patch +++ /dev/null @@ -1,716 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 30 Jul 2020 01:35:43 +1000 -Subject: [PATCH] appended signatures: support verifying appended signatures - -Building on the parsers and the ability to embed x509 certificates, as -well as the existing gcrypt functionality, add a module for verifying -appended signatures. - -This includes a verifier that requires that Linux kernels and grub modules -have appended signatures, and commands to manage the list of trusted -certificates for verification. - -Verification must be enabled by setting check_appended_signatures. If -GRUB is locked down when the module is loaded, verification will be -enabled and locked automatically. - -As with the PGP verifier, it is not a complete secure-boot solution: -other mechanisms, such as a password or lockdown, must be used to ensure -that a user cannot drop to the grub shell and disable verification. - -Signed-off-by: Daniel Axtens ---- - grub-core/Makefile.core.def | 12 + - grub-core/commands/appendedsig/appendedsig.c | 645 +++++++++++++++++++++++++++ - include/grub/file.h | 2 + - 3 files changed, 659 insertions(+) - create mode 100644 grub-core/commands/appendedsig/appendedsig.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index b4aaccf7b57..77321d218c8 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -980,6 +980,18 @@ module = { - cppflags = '-I$(srcdir)/lib/posix_wrap'; - }; - -+module = { -+ name = appendedsig; -+ common = commands/appendedsig/appendedsig.c; -+ common = commands/appendedsig/x509.c; -+ common = commands/appendedsig/pkcs7.c; -+ common = commands/appendedsig/asn1util.c; -+ common = commands/appendedsig/gnutls_asn1_tab.c; -+ common = commands/appendedsig/pkix_asn1_tab.c; -+ cflags = '$(CFLAGS_POSIX)'; -+ cppflags = '-I$(srcdir)/lib/posix_wrap'; -+}; -+ - module = { - name = hdparm; - common = commands/hdparm.c; -diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c -new file mode 100644 -index 00000000000..dc294cd339e ---- /dev/null -+++ b/grub-core/commands/appendedsig/appendedsig.c -@@ -0,0 +1,645 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020-2021 IBM Corporation. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "appendedsig.h" -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+const char magic[] = "~Module signature appended~\n"; -+ -+/* -+ * This structure is extracted from scripts/sign-file.c in the linux kernel -+ * source. It was licensed as LGPLv2.1+, which is GPLv3+ compatible. -+ */ -+struct module_signature -+{ -+ grub_uint8_t algo; /* Public-key crypto algorithm [0] */ -+ grub_uint8_t hash; /* Digest algorithm [0] */ -+ grub_uint8_t id_type; /* Key identifier type [PKEY_ID_PKCS7] */ -+ grub_uint8_t signer_len; /* Length of signer's name [0] */ -+ grub_uint8_t key_id_len; /* Length of key identifier [0] */ -+ grub_uint8_t __pad[3]; -+ grub_uint32_t sig_len; /* Length of signature data */ -+} GRUB_PACKED; -+ -+ -+/* This represents an entire, parsed, appended signature */ -+struct grub_appended_signature -+{ -+ grub_size_t signature_len; /* Length of PKCS#7 data + -+ * metadata + magic */ -+ -+ struct module_signature sig_metadata; /* Module signature metadata */ -+ struct pkcs7_signedData pkcs7; /* Parsed PKCS#7 data */ -+}; -+ -+/* Trusted certificates for verifying appended signatures */ -+struct x509_certificate *grub_trusted_key; -+ -+/* -+ * Force gcry_rsa to be a module dependency. -+ * -+ * If we use grub_crypto_pk_rsa, then then the gcry_rsa module won't be built -+ * in if you add 'appendedsig' to grub-install --modules. You would need to -+ * add 'gcry_rsa' too. That's confusing and seems suboptimal, especially when -+ * we only support RSA. -+ * -+ * Dynamic loading also causes some concerns. We can't load gcry_rsa from the -+ * the filesystem after we install the verifier - we won't be able to verify -+ * it without having it already present. We also shouldn't load it before we -+ * install the verifier, because that would mean it wouldn't be verified - an -+ * attacker could insert any code they wanted into the module. -+ * -+ * So instead, reference the internal symbol from gcry_rsa. That creates a -+ * direct dependency on gcry_rsa, so it will be built in when this module -+ * is built in. Being built in (assuming the core image is itself signed!) -+ * also resolves our concerns about loading from the filesystem. -+ */ -+extern gcry_pk_spec_t _gcry_pubkey_spec_rsa; -+ -+static int check_sigs = 0; -+ -+static const char * -+grub_env_read_sec (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val __attribute__ ((unused))) -+{ -+ if (check_sigs == 2) -+ return "forced"; -+ else if (check_sigs == 1) -+ return "enforce"; -+ else -+ return "no"; -+} -+ -+static char * -+grub_env_write_sec (struct grub_env_var *var __attribute__((unused)), -+ const char *val) -+{ -+ /* Do not allow the value to be changed if set to forced */ -+ if (check_sigs == 2) -+ return grub_strdup ("forced"); -+ -+ if ((*val == '2') || (*val == 'f')) -+ check_sigs = 2; -+ else if ((*val == '1') || (*val == 'e')) -+ check_sigs = 1; -+ else if ((*val == '0') || (*val == 'n')) -+ check_sigs = 0; -+ -+ return grub_strdup (grub_env_read_sec (NULL, NULL)); -+} -+ -+static grub_err_t -+read_cert_from_file (grub_file_t f, struct x509_certificate *certificate) -+{ -+ grub_err_t err; -+ grub_uint8_t *buf = NULL; -+ grub_ssize_t read_size; -+ grub_off_t total_read_size = 0; -+ grub_off_t file_size = grub_file_size (f); -+ -+ -+ if (file_size == GRUB_FILE_SIZE_UNKNOWN) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Cannot parse a certificate file of unknown size")); -+ -+ buf = grub_zalloc (file_size); -+ if (!buf) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("Could not allocate buffer for certificate file contents")); -+ -+ while (total_read_size < file_size) -+ { -+ read_size = -+ grub_file_read (f, &buf[total_read_size], -+ file_size - total_read_size); -+ if (read_size < 0) -+ { -+ err = grub_error (GRUB_ERR_READ_ERROR, -+ N_("Error reading certificate file")); -+ goto cleanup_buf; -+ } -+ total_read_size += read_size; -+ } -+ -+ err = certificate_import (buf, total_read_size, certificate); -+ if (err != GRUB_ERR_NONE) -+ goto cleanup_buf; -+ -+ return GRUB_ERR_NONE; -+ -+cleanup_buf: -+ grub_free (buf); -+ return err; -+} -+ -+static grub_err_t -+extract_appended_signature (grub_uint8_t * buf, grub_size_t bufsize, -+ struct grub_appended_signature *sig) -+{ -+ grub_err_t err; -+ grub_size_t pkcs7_size; -+ grub_size_t remaining_len; -+ grub_uint8_t *appsigdata = buf + bufsize - grub_strlen (magic); -+ -+ if (bufsize < grub_strlen (magic)) -+ return grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("File too short for signature magic")); -+ -+ if (grub_memcmp (appsigdata, (grub_uint8_t *) magic, grub_strlen (magic))) -+ return grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("Missing or invalid signature magic")); -+ -+ remaining_len = bufsize - grub_strlen (magic); -+ -+ if (remaining_len < sizeof (struct module_signature)) -+ return grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("File too short for signature metadata")); -+ -+ appsigdata -= sizeof (struct module_signature); -+ -+ /* extract the metadata */ -+ grub_memcpy (&(sig->sig_metadata), appsigdata, -+ sizeof (struct module_signature)); -+ -+ remaining_len -= sizeof (struct module_signature); -+ -+ if (sig->sig_metadata.id_type != 2) -+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("Wrong signature type")); -+ -+#ifdef GRUB_TARGET_WORDS_BIGENDIAN -+ pkcs7_size = sig->sig_metadata.sig_len; -+#else -+ pkcs7_size = __builtin_bswap32 (sig->sig_metadata.sig_len); -+#endif -+ -+ if (pkcs7_size > remaining_len) -+ return grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("File too short for PKCS#7 message")); -+ -+ grub_dprintf ("appendedsig", "sig len %" PRIuGRUB_SIZE "\n", pkcs7_size); -+ -+ sig->signature_len = -+ grub_strlen (magic) + sizeof (struct module_signature) + pkcs7_size; -+ -+ /* rewind pointer and parse pkcs7 data */ -+ appsigdata -= pkcs7_size; -+ -+ err = parse_pkcs7_signedData (appsigdata, pkcs7_size, &sig->pkcs7); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_verify_appended_signature (grub_uint8_t * buf, grub_size_t bufsize) -+{ -+ grub_err_t err = GRUB_ERR_NONE; -+ grub_size_t datasize; -+ void *context; -+ unsigned char *hash; -+ gcry_mpi_t hashmpi; -+ gcry_err_code_t rc; -+ struct x509_certificate *pk; -+ struct grub_appended_signature sig; -+ -+ if (!grub_trusted_key) -+ return grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("No trusted keys to verify against")); -+ -+ err = extract_appended_signature (buf, bufsize, &sig); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ -+ datasize = bufsize - sig.signature_len; -+ -+ context = grub_zalloc (sig.pkcs7.hash->contextsize); -+ if (!context) -+ return grub_errno; -+ -+ sig.pkcs7.hash->init (context); -+ sig.pkcs7.hash->write (context, buf, datasize); -+ sig.pkcs7.hash->final (context); -+ hash = sig.pkcs7.hash->read (context); -+ grub_dprintf ("appendedsig", -+ "data size %" PRIxGRUB_SIZE ", hash %02x%02x%02x%02x...\n", -+ datasize, hash[0], hash[1], hash[2], hash[3]); -+ -+ err = GRUB_ERR_BAD_SIGNATURE; -+ for (pk = grub_trusted_key; pk; pk = pk->next) -+ { -+ rc = grub_crypto_rsa_pad (&hashmpi, hash, sig.pkcs7.hash, pk->mpis[0]); -+ if (rc) -+ { -+ err = grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("Error padding hash for RSA verification: %d"), -+ rc); -+ goto cleanup; -+ } -+ -+ rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &sig.pkcs7.sig_mpi, -+ pk->mpis, NULL, NULL); -+ gcry_mpi_release (hashmpi); -+ -+ if (rc == 0) -+ { -+ grub_dprintf ("appendedsig", "verify with key '%s' succeeded\n", -+ pk->subject); -+ err = GRUB_ERR_NONE; -+ break; -+ } -+ -+ grub_dprintf ("appendedsig", "verify with key '%s' failed with %d\n", -+ pk->subject, rc); -+ } -+ -+ /* If we didn't verify, provide a neat message */ -+ if (err != GRUB_ERR_NONE) -+ err = grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("Failed to verify signature against a trusted key")); -+ -+cleanup: -+ grub_free (context); -+ pkcs7_signedData_release (&sig.pkcs7); -+ -+ return err; -+} -+ -+static grub_err_t -+grub_cmd_verify_signature (grub_command_t cmd __attribute__((unused)), -+ int argc, char **args) -+{ -+ grub_file_t f; -+ grub_err_t err = GRUB_ERR_NONE; -+ grub_uint8_t *data; -+ grub_ssize_t read_size; -+ grub_off_t file_size, total_read_size = 0; -+ -+ if (argc < 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); -+ -+ grub_dprintf ("appendedsig", "verifying %s\n", args[0]); -+ -+ f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE); -+ if (!f) -+ { -+ err = grub_errno; -+ goto cleanup; -+ } -+ -+ file_size = grub_file_size (f); -+ if (file_size == GRUB_FILE_SIZE_UNKNOWN) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Cannot verify the signature of a file of unknown size")); -+ -+ data = grub_malloc (file_size); -+ if (!data) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("Could not allocate data buffer size " -+ PRIuGRUB_UINT64_T " for verification"), file_size); -+ -+ while (total_read_size < file_size) -+ { -+ read_size = -+ grub_file_read (f, &data[total_read_size], -+ file_size - total_read_size); -+ if (read_size < 0) -+ { -+ err = grub_error (GRUB_ERR_READ_ERROR, -+ N_("Error reading file to verify")); -+ goto cleanup_data; -+ } -+ total_read_size += read_size; -+ } -+ -+ err = grub_verify_appended_signature (data, file_size); -+ -+cleanup_data: -+ grub_free (data); -+cleanup: -+ if (f) -+ grub_file_close (f); -+ return err; -+} -+ -+static grub_err_t -+grub_cmd_distrust (grub_command_t cmd __attribute__((unused)), -+ int argc, char **args) -+{ -+ unsigned long cert_num, i; -+ struct x509_certificate *cert, *prev; -+ -+ if (argc != 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("One argument expected")); -+ -+ grub_errno = GRUB_ERR_NONE; -+ cert_num = grub_strtoul (args[0], NULL, 10); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ -+ if (cert_num < 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Certificate number too small - numbers start at 1")); -+ -+ if (cert_num == 1) -+ { -+ cert = grub_trusted_key; -+ grub_trusted_key = cert->next; -+ -+ certificate_release (cert); -+ grub_free (cert); -+ return GRUB_ERR_NONE; -+ } -+ i = 2; -+ prev = grub_trusted_key; -+ cert = grub_trusted_key->next; -+ while (cert) -+ { -+ if (i == cert_num) -+ { -+ prev->next = cert->next; -+ certificate_release (cert); -+ grub_free (cert); -+ return GRUB_ERR_NONE; -+ } -+ i++; -+ prev = cert; -+ cert = cert->next; -+ } -+ -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("No certificate number %d found - only %d certificates in the store"), -+ cert_num, i - 1); -+} -+ -+static grub_err_t -+grub_cmd_trust (grub_command_t cmd __attribute__((unused)), -+ int argc, char **args) -+{ -+ grub_file_t certf; -+ struct x509_certificate *cert = NULL; -+ grub_err_t err; -+ -+ if (argc != 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); -+ -+ certf = grub_file_open (args[0], -+ GRUB_FILE_TYPE_CERTIFICATE_TRUST -+ | GRUB_FILE_TYPE_NO_DECOMPRESS); -+ if (!certf) -+ return grub_errno; -+ -+ -+ cert = grub_zalloc (sizeof (struct x509_certificate)); -+ if (!cert) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("Could not allocate memory for certificate")); -+ -+ err = read_cert_from_file (certf, cert); -+ grub_file_close (certf); -+ if (err != GRUB_ERR_NONE) -+ { -+ grub_free (cert); -+ return err; -+ } -+ grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n", -+ cert->subject); -+ -+ cert->next = grub_trusted_key; -+ grub_trusted_key = cert; -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_list (grub_command_t cmd __attribute__((unused)), -+ int argc __attribute__((unused)), -+ char **args __attribute__((unused))) -+{ -+ struct x509_certificate *cert; -+ int cert_num = 1; -+ grub_size_t i; -+ -+ for (cert = grub_trusted_key; cert; cert = cert->next) -+ { -+ grub_printf (N_("Certificate %d:\n"), cert_num); -+ -+ grub_printf (N_("\tSerial: ")); -+ for (i = 0; i < cert->serial_len - 1; i++) -+ { -+ grub_printf ("%02x:", cert->serial[i]); -+ } -+ grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]); -+ -+ grub_printf ("\tCN: %s\n\n", cert->subject); -+ cert_num++; -+ -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+appendedsig_init (grub_file_t io __attribute__((unused)), -+ enum grub_file_type type, -+ void **context __attribute__((unused)), -+ enum grub_verify_flags *flags) -+{ -+ if (!check_sigs) -+ { -+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; -+ return GRUB_ERR_NONE; -+ } -+ -+ switch (type & GRUB_FILE_TYPE_MASK) -+ { -+ case GRUB_FILE_TYPE_CERTIFICATE_TRUST: -+ /* -+ * This is a certificate to add to trusted keychain. -+ * -+ * This needs to be verified or blocked. Ideally we'd write an x509 -+ * verifier, but we lack the hubris required to take this on. Instead, -+ * require that it have an appended signature. -+ */ -+ -+ /* Fall through */ -+ -+ case GRUB_FILE_TYPE_LINUX_KERNEL: -+ case GRUB_FILE_TYPE_GRUB_MODULE: -+ /* -+ * Appended signatures are only defined for ELF binaries. -+ * Out of an abundance of caution, we only verify Linux kernels and -+ * GRUB modules at this point. -+ */ -+ *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK; -+ return GRUB_ERR_NONE; -+ -+ case GRUB_FILE_TYPE_ACPI_TABLE: -+ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE: -+ /* -+ * It is possible to use appended signature verification without -+ * lockdown - like the PGP verifier. When combined with an embedded -+ * config file in a signed grub binary, this could still be a meaningful -+ * secure-boot chain - so long as it isn't subverted by something like a -+ * rouge ACPI table or DT image. Defer them explicitly. -+ */ -+ *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH; -+ return GRUB_ERR_NONE; -+ -+ default: -+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; -+ return GRUB_ERR_NONE; -+ } -+} -+ -+static grub_err_t -+appendedsig_write (void *ctxt __attribute__((unused)), -+ void *buf, grub_size_t size) -+{ -+ return grub_verify_appended_signature (buf, size); -+} -+ -+struct grub_file_verifier grub_appendedsig_verifier = { -+ .name = "appendedsig", -+ .init = appendedsig_init, -+ .write = appendedsig_write, -+}; -+ -+static grub_ssize_t -+pseudo_read (struct grub_file *file, char *buf, grub_size_t len) -+{ -+ grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len); -+ return len; -+} -+ -+/* Filesystem descriptor. */ -+static struct grub_fs pseudo_fs = { -+ .name = "pseudo", -+ .fs_read = pseudo_read -+}; -+ -+static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust; -+ -+GRUB_MOD_INIT (appendedsig) -+{ -+ int rc; -+ struct grub_module_header *header; -+ -+ /* If in lockdown, immediately enter forced mode */ -+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED) -+ check_sigs = 2; -+ -+ grub_trusted_key = NULL; -+ -+ grub_register_variable_hook ("check_appended_signatures", -+ grub_env_read_sec, -+ grub_env_write_sec); -+ grub_env_export ("check_appended_signatures"); -+ -+ rc = asn1_init (); -+ if (rc) -+ grub_fatal ("Error initing ASN.1 data structures: %d: %s\n", rc, -+ asn1_strerror (rc)); -+ -+ FOR_MODULES (header) -+ { -+ struct grub_file pseudo_file; -+ struct x509_certificate *pk = NULL; -+ grub_err_t err; -+ -+ /* Not an ELF module, skip. */ -+ if (header->type != OBJ_TYPE_X509_PUBKEY) -+ continue; -+ -+ grub_memset (&pseudo_file, 0, sizeof (pseudo_file)); -+ pseudo_file.fs = &pseudo_fs; -+ pseudo_file.size = header->size - sizeof (struct grub_module_header); -+ pseudo_file.data = (char *) header + sizeof (struct grub_module_header); -+ -+ grub_dprintf ("appendedsig", -+ "Found an x509 key, size=%" PRIuGRUB_UINT64_T "\n", -+ pseudo_file.size); -+ -+ pk = grub_zalloc (sizeof (struct x509_certificate)); -+ if (!pk) -+ { -+ grub_fatal ("Out of memory loading initial certificates"); -+ } -+ -+ err = read_cert_from_file (&pseudo_file, pk); -+ if (err != GRUB_ERR_NONE) -+ grub_fatal ("Error loading initial key: %s", grub_errmsg); -+ -+ grub_dprintf ("appendedsig", "loaded certificate CN='%s'\n", pk->subject); -+ -+ pk->next = grub_trusted_key; -+ grub_trusted_key = pk; -+ } -+ -+ cmd_trust = -+ grub_register_command ("trust_certificate", grub_cmd_trust, -+ N_("X509_CERTIFICATE"), -+ N_("Add X509_CERTIFICATE to trusted certificates.")); -+ cmd_list = -+ grub_register_command ("list_certificates", grub_cmd_list, 0, -+ N_("Show the list of trusted x509 certificates.")); -+ cmd_verify = -+ grub_register_command ("verify_appended", grub_cmd_verify_signature, -+ N_("FILE"), -+ N_("Verify FILE against the trusted x509 certificates.")); -+ cmd_distrust = -+ grub_register_command ("distrust_certificate", grub_cmd_distrust, -+ N_("CERT_NUMBER"), -+ N_("Remove CERT_NUMBER (as listed by list_certificates) from trusted certificates.")); -+ -+ grub_verifier_register (&grub_appendedsig_verifier); -+ grub_dl_set_persistent (mod); -+} -+ -+GRUB_MOD_FINI (appendedsig) -+{ -+ /* -+ * grub_dl_set_persistent should prevent this from actually running, but -+ * it does still run under emu. -+ */ -+ -+ grub_verifier_unregister (&grub_appendedsig_verifier); -+ grub_unregister_command (cmd_verify); -+ grub_unregister_command (cmd_list); -+ grub_unregister_command (cmd_trust); -+ grub_unregister_command (cmd_distrust); -+} -diff --git a/include/grub/file.h b/include/grub/file.h -index 31567483ccf..96827a4f896 100644 ---- a/include/grub/file.h -+++ b/include/grub/file.h -@@ -80,6 +80,8 @@ enum grub_file_type - GRUB_FILE_TYPE_PUBLIC_KEY, - /* File holding public key to add to trused keys. */ - GRUB_FILE_TYPE_PUBLIC_KEY_TRUST, -+ /* File holding x509 certificiate to add to trusted keys. */ -+ GRUB_FILE_TYPE_CERTIFICATE_TRUST, - /* File of which we intend to print a blocklist to the user. */ - GRUB_FILE_TYPE_PRINT_BLOCKLIST, - /* File we intend to use for test loading or testing speed. */ diff --git a/0178-appended-signatures-verification-tests.patch b/0178-appended-signatures-verification-tests.patch deleted file mode 100644 index 9f6c3c6..0000000 --- a/0178-appended-signatures-verification-tests.patch +++ /dev/null @@ -1,897 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 30 Jul 2020 01:31:02 +1000 -Subject: [PATCH] appended signatures: verification tests - -These tests are run through all_functional_test and test a range -of commands and behaviours. - -Signed-off-by: Daniel Axtens ---- - grub-core/Makefile.core.def | 6 + - grub-core/tests/appended_signature_test.c | 281 +++++++++++++++ - grub-core/tests/lib/functional_test.c | 1 + - grub-core/tests/appended_signatures.h | 557 ++++++++++++++++++++++++++++++ - 4 files changed, 845 insertions(+) - create mode 100644 grub-core/tests/appended_signature_test.c - create mode 100644 grub-core/tests/appended_signatures.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 77321d218c8..6bddc841b85 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2161,6 +2161,12 @@ module = { - common = tests/setjmp_test.c; - }; - -+module = { -+ name = appended_signature_test; -+ common = tests/appended_signature_test.c; -+ common = tests/appended_signatures.h; -+}; -+ - module = { - name = signature_test; - common = tests/signature_test.c; -diff --git a/grub-core/tests/appended_signature_test.c b/grub-core/tests/appended_signature_test.c -new file mode 100644 -index 00000000000..88a485200d8 ---- /dev/null -+++ b/grub-core/tests/appended_signature_test.c -@@ -0,0 +1,281 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "appended_signatures.h" -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#define DEFINE_TEST_CASE(case_name) \ -+static char * \ -+get_ ## case_name (grub_size_t *sz) \ -+{ \ -+ char *ret; \ -+ *sz = case_name ## _len; \ -+ ret = grub_malloc (*sz); \ -+ if (ret) \ -+ grub_memcpy (ret, case_name, *sz); \ -+ return ret; \ -+} \ -+\ -+static struct grub_procfs_entry case_name ## _entry = \ -+{ \ -+ .name = #case_name, \ -+ .get_contents = get_ ## case_name \ -+} -+ -+#define DO_TEST(case_name, is_valid) \ -+{ \ -+ grub_procfs_register (#case_name, &case_name ## _entry); \ -+ do_verify ("(proc)/" #case_name, is_valid); \ -+ grub_procfs_unregister (&case_name ## _entry); \ -+} -+ -+ -+DEFINE_TEST_CASE (hi_signed); -+DEFINE_TEST_CASE (hi_signed_sha256); -+DEFINE_TEST_CASE (hj_signed); -+DEFINE_TEST_CASE (short_msg); -+DEFINE_TEST_CASE (unsigned_msg); -+DEFINE_TEST_CASE (hi_signed_2nd); -+ -+static char * -+get_certificate_der (grub_size_t * sz) -+{ -+ char *ret; -+ *sz = certificate_der_len; -+ ret = grub_malloc (*sz); -+ if (ret) -+ grub_memcpy (ret, certificate_der, *sz); -+ return ret; -+} -+ -+static struct grub_procfs_entry certificate_der_entry = { -+ .name = "certificate.der", -+ .get_contents = get_certificate_der -+}; -+ -+static char * -+get_certificate2_der (grub_size_t * sz) -+{ -+ char *ret; -+ *sz = certificate2_der_len; -+ ret = grub_malloc (*sz); -+ if (ret) -+ grub_memcpy (ret, certificate2_der, *sz); -+ return ret; -+} -+ -+static struct grub_procfs_entry certificate2_der_entry = { -+ .name = "certificate2.der", -+ .get_contents = get_certificate2_der -+}; -+ -+static char * -+get_certificate_printable_der (grub_size_t * sz) -+{ -+ char *ret; -+ *sz = certificate_printable_der_len; -+ ret = grub_malloc (*sz); -+ if (ret) -+ grub_memcpy (ret, certificate_printable_der, *sz); -+ return ret; -+} -+ -+static struct grub_procfs_entry certificate_printable_der_entry = { -+ .name = "certificate_printable.der", -+ .get_contents = get_certificate_printable_der -+}; -+ -+ -+static void -+do_verify (const char *f, int is_valid) -+{ -+ grub_command_t cmd; -+ char *args[] = { (char *) f, NULL }; -+ grub_err_t err; -+ -+ cmd = grub_command_find ("verify_appended"); -+ if (!cmd) -+ { -+ grub_test_assert (0, "can't find command `%s'", "verify_appended"); -+ return; -+ } -+ err = (cmd->func) (cmd, 1, args); -+ if (is_valid) -+ { -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "verification of %s failed: %d: %s", f, grub_errno, -+ grub_errmsg); -+ } -+ else -+ { -+ grub_test_assert (err == GRUB_ERR_BAD_SIGNATURE, -+ "verification of %s unexpectedly succeeded", f); -+ } -+ grub_errno = GRUB_ERR_NONE; -+ -+} -+ -+static void -+appended_signature_test (void) -+{ -+ grub_command_t cmd_trust, cmd_distrust; -+ char *trust_args[] = { (char *) "(proc)/certificate.der", NULL }; -+ char *trust_args2[] = { (char *) "(proc)/certificate2.der", NULL }; -+ char *trust_args_printable[] = { (char *) "(proc)/certificate_printable.der", -+ NULL }; -+ char *distrust_args[] = { (char *) "1", NULL }; -+ char *distrust2_args[] = { (char *) "2", NULL }; -+ grub_err_t err; -+ -+ grub_procfs_register ("certificate.der", &certificate_der_entry); -+ grub_procfs_register ("certificate2.der", &certificate2_der_entry); -+ grub_procfs_register ("certificate_printable.der", -+ &certificate_printable_der_entry); -+ -+ cmd_trust = grub_command_find ("trust_certificate"); -+ if (!cmd_trust) -+ { -+ grub_test_assert (0, "can't find command `%s'", "trust_certificate"); -+ return; -+ } -+ err = (cmd_trust->func) (cmd_trust, 1, trust_args); -+ -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "loading certificate failed: %d: %s", grub_errno, -+ grub_errmsg); -+ -+ /* If we have no certificate the remainder of the tests are meaningless */ -+ if (err != GRUB_ERR_NONE) -+ return; -+ -+ /* -+ * Reload the command: this works around some 'interesting' behaviour in the -+ * dynamic command dispatcher. The first time you call cmd->func you get a -+ * dispatcher that loads the module, finds the real cmd, calls it, and then -+ * releases some internal storage. This means it's not safe to call a second -+ * time and we need to reload it. -+ */ -+ cmd_trust = grub_command_find ("trust_certificate"); -+ -+ DO_TEST (hi_signed, 1); -+ DO_TEST (hi_signed_sha256, 1); -+ DO_TEST (hj_signed, 0); -+ DO_TEST (short_msg, 0); -+ DO_TEST (unsigned_msg, 0); -+ -+ /* -+ * in enforcing mode, we shouldn't be able to load a certificate that isn't -+ * signed by an existing trusted key. -+ * -+ * However, procfs files automatically skip the verification test, so we can't -+ * easily test this. -+ */ -+ -+ /* -+ * verify that testing with 2 trusted certs works -+ */ -+ DO_TEST (hi_signed_2nd, 0); -+ -+ err = (cmd_trust->func) (cmd_trust, 1, trust_args2); -+ -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "loading certificate 2 failed: %d: %s", grub_errno, -+ grub_errmsg); -+ -+ if (err != GRUB_ERR_NONE) -+ return; -+ -+ DO_TEST (hi_signed_2nd, 1); -+ DO_TEST (hi_signed, 1); -+ -+ /* -+ * Check certificate removal. They're added to the _top_ of the list and -+ * removed by position in the list. Current the list looks like [#2, #1]. -+ * -+ * First test removing the second certificate in the list, which is -+ * certificate #1, giving us just [#2]. -+ */ -+ cmd_distrust = grub_command_find ("distrust_certificate"); -+ if (!cmd_distrust) -+ { -+ grub_test_assert (0, "can't find command `%s'", "distrust_certificate"); -+ return; -+ } -+ -+ err = (cmd_distrust->func) (cmd_distrust, 1, distrust2_args); -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "distrusting certificate 1 failed: %d: %s", grub_errno, -+ grub_errmsg); -+ DO_TEST (hi_signed_2nd, 1); -+ DO_TEST (hi_signed, 0); -+ -+ /* -+ * Now reload certificate #1. This will make the list look like [#1, #2] -+ */ -+ err = (cmd_trust->func) (cmd_trust, 1, trust_args); -+ -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "reloading certificate 1 failed: %d: %s", grub_errno, -+ grub_errmsg); -+ DO_TEST (hi_signed, 1); -+ -+ /* Remove the first certificate in the list, giving us just [#2] */ -+ err = (cmd_distrust->func) (cmd_distrust, 1, distrust_args); -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "distrusting certificate 1 (first time) failed: %d: %s", -+ grub_errno, grub_errmsg); -+ DO_TEST (hi_signed_2nd, 1); -+ DO_TEST (hi_signed, 0); -+ -+ /* -+ * Remove the first certificate again, giving an empty list. -+ * -+ * verify_appended should fail if there are no certificates to verify against. -+ */ -+ err = (cmd_distrust->func) (cmd_distrust, 1, distrust_args); -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "distrusting certificate 1 (second time) failed: %d: %s", -+ grub_errno, grub_errmsg); -+ DO_TEST (hi_signed_2nd, 0); -+ -+ /* -+ * Lastly, check a certificate that uses printableString rather than -+ * utf8String loads properly. -+ */ -+ err = (cmd_trust->func) (cmd_trust, 1, trust_args_printable); -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "distrusting printable certificate failed: %d: %s", -+ grub_errno, grub_errmsg); -+ -+ grub_procfs_unregister (&certificate_der_entry); -+ grub_procfs_unregister (&certificate2_der_entry); -+ grub_procfs_unregister (&certificate_printable_der_entry); -+} -+ -+GRUB_FUNCTIONAL_TEST (appended_signature_test, appended_signature_test); -diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c -index 96781fb39b5..403fa5c789a 100644 ---- a/grub-core/tests/lib/functional_test.c -+++ b/grub-core/tests/lib/functional_test.c -@@ -73,6 +73,7 @@ grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)), - grub_dl_load ("xnu_uuid_test"); - grub_dl_load ("pbkdf2_test"); - grub_dl_load ("signature_test"); -+ grub_dl_load ("appended_signature_test"); - grub_dl_load ("sleep_test"); - grub_dl_load ("bswap_test"); - grub_dl_load ("ctz_test"); -diff --git a/grub-core/tests/appended_signatures.h b/grub-core/tests/appended_signatures.h -new file mode 100644 -index 00000000000..aa3dc6278e3 ---- /dev/null -+++ b/grub-core/tests/appended_signatures.h -@@ -0,0 +1,557 @@ -+unsigned char certificate_der[] = { -+ 0x30, 0x82, 0x03, 0x88, 0x30, 0x82, 0x02, 0x70, 0xa0, 0x03, 0x02, 0x01, -+ 0x02, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d, -+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30, -+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, -+ 0x05, 0x00, 0x30, 0x49, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, -+ 0x03, 0x0c, 0x1f, 0x47, 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, -+ 0x6e, 0x64, 0x65, 0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, -+ 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, -+ 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, -+ 0x01, 0x16, 0x0e, 0x64, 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, -+ 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x30, 0x30, -+ 0x37, 0x30, 0x39, 0x30, 0x36, 0x32, 0x32, 0x30, 0x37, 0x5a, 0x18, 0x0f, -+ 0x32, 0x31, 0x32, 0x30, 0x30, 0x36, 0x31, 0x35, 0x30, 0x36, 0x32, 0x32, -+ 0x30, 0x37, 0x5a, 0x30, 0x52, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, -+ 0x04, 0x03, 0x0c, 0x28, 0x47, 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, -+ 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, -+ 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, -+ 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x65, 0x79, 0x31, 0x1d, 0x30, 0x1b, -+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, -+ 0x0e, 0x64, 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, -+ 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, -+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, -+ 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, -+ 0xcd, 0xe8, 0x1c, 0x08, 0x68, 0x2e, 0xcb, 0xfe, 0x8c, 0x4b, 0x3b, 0x61, -+ 0xe7, 0x8e, 0x80, 0x58, 0x85, 0x85, 0xea, 0xc8, 0x3b, 0x42, 0xba, 0x72, -+ 0x84, 0x65, 0x20, 0xbc, 0x48, 0xa2, 0x25, 0x49, 0x6e, 0x1c, 0xb9, 0x7d, -+ 0xeb, 0xc1, 0x0c, 0xa8, 0xb7, 0xcc, 0x13, 0x78, 0xba, 0x11, 0xa4, 0x98, -+ 0xd7, 0xd0, 0x7c, 0xdd, 0xf5, 0x5a, 0xb7, 0xcd, 0x31, 0x0e, 0xcd, 0x9e, -+ 0xa7, 0x19, 0xf0, 0xbd, 0x0f, 0xa6, 0xfe, 0x8a, 0x11, 0x97, 0xed, 0x8b, -+ 0xe5, 0x16, 0xa6, 0x21, 0x13, 0x36, 0xad, 0x05, 0x49, 0xec, 0x29, 0x12, -+ 0x38, 0xa7, 0x4b, 0x0f, 0xa1, 0xfb, 0x72, 0xc0, 0xc0, 0x09, 0x67, 0x78, -+ 0xa8, 0xb6, 0xd6, 0x1a, 0x39, 0xc0, 0xa8, 0xbf, 0x5f, 0x14, 0x89, 0x5c, -+ 0xbc, 0x41, 0x0c, 0x0c, 0x5d, 0x42, 0x2e, 0x1c, 0xdf, 0x1f, 0x1d, 0xc9, -+ 0x43, 0x94, 0x5b, 0x6e, 0x8f, 0x15, 0x8c, 0x8f, 0x94, 0x73, 0x4f, 0x97, -+ 0x54, 0xf1, 0x86, 0x8a, 0xbc, 0xe4, 0xe4, 0x93, 0xc1, 0x5e, 0xc2, 0x3e, -+ 0x31, 0x5e, 0xd4, 0x85, 0x57, 0x14, 0xd0, 0x11, 0x07, 0x65, 0xf4, 0x7c, -+ 0x8f, 0x07, 0x57, 0xe1, 0x22, 0xd4, 0x78, 0x47, 0x65, 0x4e, 0xa9, 0xb3, -+ 0xaa, 0xce, 0xc7, 0x36, 0xfe, 0xda, 0x66, 0x02, 0xb6, 0x8d, 0x18, 0x2f, -+ 0x3b, 0x41, 0x8d, 0x02, 0x08, 0x72, 0x4b, 0x69, 0xbd, 0x1e, 0x58, 0xfc, -+ 0x1b, 0x64, 0x04, 0x52, 0x35, 0x35, 0xe2, 0x3d, 0x3e, 0xde, 0xd6, 0x64, -+ 0xf4, 0xec, 0x57, 0x7e, 0x65, 0x59, 0x00, 0xa6, 0xd3, 0x4b, 0x09, 0x93, -+ 0x2a, 0x95, 0x0f, 0x30, 0xb6, 0xa1, 0x8c, 0xe7, 0x8b, 0x49, 0xa4, 0x1d, -+ 0x25, 0x2d, 0x65, 0x48, 0x8a, 0x0f, 0xcf, 0x2a, 0xa2, 0xe1, 0xef, 0x72, -+ 0x92, 0xc3, 0xf5, 0x21, 0x37, 0x83, 0x9b, 0x6d, 0x0b, 0x1b, 0xb3, 0xa2, -+ 0x32, 0x38, 0x11, 0xb1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x5d, 0x30, -+ 0x5b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, -+ 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, -+ 0x03, 0x02, 0x07, 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, -+ 0x16, 0x04, 0x14, 0xe5, 0x2a, 0x4f, 0xf2, 0x84, 0x91, 0x57, 0x91, 0xaf, -+ 0x12, 0xd2, 0xf1, 0xa1, 0x87, 0x73, 0x0f, 0x90, 0x25, 0xa0, 0x7a, 0x30, -+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, -+ 0x56, 0xd1, 0xfd, 0xe2, 0x1e, 0x7e, 0x1c, 0x63, 0x4f, 0x47, 0xdb, 0xe4, -+ 0xc4, 0x51, 0x04, 0x03, 0x9a, 0x48, 0x35, 0x6e, 0x30, 0x0d, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, -+ 0x82, 0x01, 0x01, 0x00, 0x65, 0x82, 0xd5, 0x88, 0x30, 0xe2, 0x2c, 0x47, -+ 0xf3, 0x31, 0x39, 0xa1, 0x75, 0x9a, 0xb0, 0x8a, 0x6c, 0x4b, 0xac, 0xdf, -+ 0x09, 0x7b, 0x90, 0xb6, 0x9e, 0x76, 0x62, 0x94, 0xc1, 0x3a, 0x99, 0x49, -+ 0x68, 0x29, 0x47, 0x42, 0xc3, 0x06, 0xcb, 0x88, 0x75, 0xe6, 0x79, 0x13, -+ 0x8c, 0x4b, 0x49, 0x6a, 0xb5, 0x56, 0x95, 0xc0, 0x42, 0x21, 0x9b, 0xd4, -+ 0x61, 0xd0, 0x02, 0x41, 0xdd, 0x20, 0x61, 0xe5, 0x91, 0xdf, 0x75, 0x00, -+ 0x25, 0x0e, 0x99, 0x65, 0x5c, 0x54, 0x49, 0x32, 0xa3, 0xe2, 0xcd, 0xa1, -+ 0x5f, 0x40, 0xf3, 0xc5, 0x81, 0xd9, 0x3c, 0xa3, 0x63, 0x5a, 0x38, 0x79, -+ 0xab, 0x77, 0x98, 0xde, 0x8f, 0x4e, 0x9e, 0x26, 0xbc, 0x4e, 0x80, 0x9e, -+ 0x8f, 0xbe, 0xf1, 0x00, 0xb3, 0x78, 0xb9, 0x4b, 0x1d, 0xc7, 0xa4, 0x83, -+ 0x59, 0x56, 0x11, 0xd1, 0x11, 0x1e, 0x50, 0x39, 0xd5, 0x78, 0x14, 0xf3, -+ 0xb9, 0x1d, 0xda, 0xe4, 0xc4, 0x63, 0x74, 0x26, 0xab, 0xa3, 0xfd, 0x9d, -+ 0x58, 0xa2, 0xee, 0x7b, 0x28, 0x34, 0xa3, 0xbe, 0x85, 0x7e, 0xaa, 0x97, -+ 0xb7, 0x5b, 0x9d, 0xa9, 0x4d, 0x96, 0xdb, 0x6b, 0x21, 0xe1, 0x96, 0x5d, -+ 0xc7, 0xad, 0x23, 0x03, 0x9a, 0x16, 0xdb, 0xa4, 0x1f, 0x63, 0xef, 0xaf, -+ 0x1e, 0x4f, 0xf8, 0x27, 0xdc, 0x4b, 0xfc, 0x2b, 0x68, 0x2e, 0xa0, 0xd3, -+ 0xae, 0xf2, 0xce, 0xf5, 0xfc, 0x97, 0x92, 0xd2, 0x29, 0x0f, 0x4f, 0x4b, -+ 0x29, 0xeb, 0x06, 0xcb, 0xf8, 0x21, 0x6e, 0xbc, 0x8b, 0x5c, 0xc5, 0xc9, -+ 0xf7, 0xe2, 0x7c, 0x47, 0xcd, 0x43, 0x98, 0xc4, 0xa3, 0x9a, 0xd7, 0x3e, -+ 0xdc, 0x01, 0x13, 0x28, 0x96, 0xc4, 0x60, 0x83, 0xe2, 0x79, 0xa1, 0x46, -+ 0xef, 0xf5, 0xa4, 0x7b, 0x00, 0xe3, 0x3d, 0x7d, 0xbc, 0xa8, 0x98, 0x49, -+ 0xa8, 0xcf, 0x3b, 0x41, 0xb6, 0x09, 0x97, 0x07 -+}; -+unsigned int certificate_der_len = 908; -+ -+unsigned char hi_signed[] = { -+ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48, -+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82, -+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, -+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01, -+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49, -+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47, -+ 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, -+ 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, -+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64, -+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65, -+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d, -+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30, -+ 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xc7, 0x69, 0x35, 0x21, 0x66, -+ 0x4d, 0x50, 0xd4, 0x73, 0xde, 0xbd, 0x3a, 0xf6, 0x45, 0xe3, 0xe4, 0xd0, -+ 0xb6, 0xa1, 0xe7, 0xc0, 0xa2, 0xc9, 0xf4, 0xf0, 0x05, 0x8c, 0xa4, 0x16, -+ 0x9e, 0x81, 0x0d, 0x21, 0x68, 0xf3, 0xfe, 0x03, 0x96, 0x77, 0x31, 0x69, -+ 0x01, 0xd8, 0x26, 0xd9, 0x48, 0x95, 0xcf, 0xd1, 0x17, 0xb1, 0x0b, 0x6b, -+ 0x2c, 0xf1, 0xb0, 0xab, 0x65, 0x65, 0x56, 0xf8, 0x0c, 0xa7, 0xf7, 0xbb, -+ 0xf6, 0x5a, 0x55, 0x98, 0x14, 0x07, 0x8d, 0x2a, 0xbc, 0x16, 0x48, 0x94, -+ 0xab, 0x2f, 0x85, 0x97, 0x90, 0x51, 0x78, 0xa0, 0xda, 0x60, 0xb5, 0x41, -+ 0x4b, 0xe8, 0x78, 0xc5, 0xa6, 0x04, 0x9d, 0x54, 0x2a, 0x85, 0xfd, 0x86, -+ 0x0b, 0x6d, 0xc2, 0xd2, 0xad, 0x07, 0xff, 0x16, 0x42, 0x82, 0xe3, 0x5c, -+ 0xaa, 0x22, 0x59, 0x78, 0x92, 0xea, 0x94, 0xc3, 0x41, 0xb7, 0xa1, 0x86, -+ 0x44, 0xea, 0xd1, 0xdb, 0xe5, 0xac, 0x30, 0x32, 0xfb, 0x7d, 0x3f, 0xf7, -+ 0x8b, 0x11, 0x7f, 0x80, 0x3b, 0xe5, 0xc7, 0x82, 0x0f, 0x92, 0x07, 0x14, -+ 0x66, 0x01, 0x6e, 0x85, 0xab, 0x3a, 0x14, 0xcf, 0x76, 0xd1, 0x7e, 0x14, -+ 0x85, 0xca, 0x01, 0x73, 0x72, 0x38, 0xdc, 0xde, 0x30, 0x5c, 0xfb, 0xc0, -+ 0x3d, 0x93, 0xef, 0x9c, 0xbc, 0xf8, 0xcc, 0xd2, 0xbf, 0x47, 0xec, 0xf8, -+ 0x88, 0x9b, 0xe1, 0x43, 0xbe, 0xa7, 0x47, 0x96, 0xb6, 0x5d, 0x46, 0x0e, -+ 0x7a, 0x78, 0x38, 0x19, 0xbc, 0xb5, 0xbc, 0x9b, 0x3c, 0x39, 0x92, 0x70, -+ 0x0d, 0x9d, 0x8a, 0x35, 0xaf, 0xb4, 0x9e, 0xf4, 0xef, 0xc1, 0xb8, 0x25, -+ 0xd0, 0x14, 0x91, 0xd6, 0xc2, 0xb6, 0xc7, 0x3c, 0x72, 0x91, 0x0f, 0xad, -+ 0xde, 0xb2, 0x36, 0xf8, 0x4e, 0x59, 0xd4, 0xa4, 0x21, 0x9f, 0x03, 0x95, -+ 0x48, 0x01, 0xb4, 0x05, 0xc3, 0x39, 0x60, 0x51, 0x08, 0xd0, 0xbe, 0x00, -+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e, -+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, -+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, -+ 0x64, 0x7e, 0x0a -+}; -+unsigned int hi_signed_len = 495; -+ -+unsigned char hj_signed[] = { -+ 0x68, 0x6a, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48, -+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82, -+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, -+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01, -+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49, -+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47, -+ 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, -+ 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, -+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64, -+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65, -+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d, -+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30, -+ 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xc7, 0x69, 0x35, 0x21, 0x66, -+ 0x4d, 0x50, 0xd4, 0x73, 0xde, 0xbd, 0x3a, 0xf6, 0x45, 0xe3, 0xe4, 0xd0, -+ 0xb6, 0xa1, 0xe7, 0xc0, 0xa2, 0xc9, 0xf4, 0xf0, 0x05, 0x8c, 0xa4, 0x16, -+ 0x9e, 0x81, 0x0d, 0x21, 0x68, 0xf3, 0xfe, 0x03, 0x96, 0x77, 0x31, 0x69, -+ 0x01, 0xd8, 0x26, 0xd9, 0x48, 0x95, 0xcf, 0xd1, 0x17, 0xb1, 0x0b, 0x6b, -+ 0x2c, 0xf1, 0xb0, 0xab, 0x65, 0x65, 0x56, 0xf8, 0x0c, 0xa7, 0xf7, 0xbb, -+ 0xf6, 0x5a, 0x55, 0x98, 0x14, 0x07, 0x8d, 0x2a, 0xbc, 0x16, 0x48, 0x94, -+ 0xab, 0x2f, 0x85, 0x97, 0x90, 0x51, 0x78, 0xa0, 0xda, 0x60, 0xb5, 0x41, -+ 0x4b, 0xe8, 0x78, 0xc5, 0xa6, 0x04, 0x9d, 0x54, 0x2a, 0x85, 0xfd, 0x86, -+ 0x0b, 0x6d, 0xc2, 0xd2, 0xad, 0x07, 0xff, 0x16, 0x42, 0x82, 0xe3, 0x5c, -+ 0xaa, 0x22, 0x59, 0x78, 0x92, 0xea, 0x94, 0xc3, 0x41, 0xb7, 0xa1, 0x86, -+ 0x44, 0xea, 0xd1, 0xdb, 0xe5, 0xac, 0x30, 0x32, 0xfb, 0x7d, 0x3f, 0xf7, -+ 0x8b, 0x11, 0x7f, 0x80, 0x3b, 0xe5, 0xc7, 0x82, 0x0f, 0x92, 0x07, 0x14, -+ 0x66, 0x01, 0x6e, 0x85, 0xab, 0x3a, 0x14, 0xcf, 0x76, 0xd1, 0x7e, 0x14, -+ 0x85, 0xca, 0x01, 0x73, 0x72, 0x38, 0xdc, 0xde, 0x30, 0x5c, 0xfb, 0xc0, -+ 0x3d, 0x93, 0xef, 0x9c, 0xbc, 0xf8, 0xcc, 0xd2, 0xbf, 0x47, 0xec, 0xf8, -+ 0x88, 0x9b, 0xe1, 0x43, 0xbe, 0xa7, 0x47, 0x96, 0xb6, 0x5d, 0x46, 0x0e, -+ 0x7a, 0x78, 0x38, 0x19, 0xbc, 0xb5, 0xbc, 0x9b, 0x3c, 0x39, 0x92, 0x70, -+ 0x0d, 0x9d, 0x8a, 0x35, 0xaf, 0xb4, 0x9e, 0xf4, 0xef, 0xc1, 0xb8, 0x25, -+ 0xd0, 0x14, 0x91, 0xd6, 0xc2, 0xb6, 0xc7, 0x3c, 0x72, 0x91, 0x0f, 0xad, -+ 0xde, 0xb2, 0x36, 0xf8, 0x4e, 0x59, 0xd4, 0xa4, 0x21, 0x9f, 0x03, 0x95, -+ 0x48, 0x01, 0xb4, 0x05, 0xc3, 0x39, 0x60, 0x51, 0x08, 0xd0, 0xbe, 0x00, -+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e, -+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, -+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, -+ 0x64, 0x7e, 0x0a -+}; -+unsigned int hj_signed_len = 495; -+ -+unsigned char hi_signed_sha256[] = { -+ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48, -+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82, -+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, -+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01, -+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49, -+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47, -+ 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, -+ 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, -+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64, -+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65, -+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d, -+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30, -+ 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x7b, 0x5e, 0x82, 0x1d, 0x21, -+ 0xb6, 0x40, 0xd3, 0x33, 0x79, 0xa7, 0x52, 0x2b, 0xfc, 0x46, 0x51, 0x26, -+ 0xfe, 0x0f, 0x81, 0x90, 0x81, 0xab, 0x57, 0x5e, 0xf6, 0x45, 0x41, 0xa3, -+ 0x7b, 0x48, 0xdd, 0xd6, 0x59, 0x60, 0x51, 0x31, 0x14, 0x14, 0x7b, 0xb4, -+ 0x55, 0x7b, 0x4d, 0xfe, 0x09, 0x7a, 0x5d, 0xae, 0xc4, 0x58, 0x50, 0x80, -+ 0x75, 0xf2, 0x23, 0x20, 0x62, 0xe3, 0x7c, 0x26, 0x1d, 0x2a, 0x4d, 0x9f, -+ 0x89, 0xf0, 0x4f, 0x95, 0x8a, 0x80, 0x6e, 0x1a, 0xea, 0x87, 0xdb, 0x1f, -+ 0xf3, 0xda, 0x04, 0x91, 0x37, 0xea, 0x0a, 0xfb, 0x6c, 0xc9, 0x3d, 0x73, -+ 0xf9, 0x58, 0x7c, 0x15, 0x6b, 0xa2, 0x52, 0x5a, 0x97, 0xff, 0xd6, 0xb0, -+ 0xf1, 0xbf, 0xa5, 0x04, 0x6d, 0x91, 0xc1, 0x54, 0x05, 0xdc, 0x7f, 0x5d, -+ 0x19, 0xaf, 0x55, 0xec, 0x51, 0xfb, 0x66, 0x0a, 0xa4, 0x4e, 0x96, 0x47, -+ 0x43, 0x54, 0x7c, 0x64, 0xa8, 0xaa, 0xb4, 0x90, 0x02, 0xf3, 0xa7, 0x0b, -+ 0xb7, 0xbf, 0x06, 0xdb, 0x5e, 0x9c, 0x32, 0x6d, 0x45, 0x14, 0x1c, 0xaf, -+ 0x46, 0x30, 0x08, 0x55, 0x49, 0x78, 0xfa, 0x57, 0xda, 0x3d, 0xf5, 0xa0, -+ 0xef, 0x11, 0x0a, 0x81, 0x0d, 0x82, 0xcd, 0xaf, 0xdb, 0xda, 0x0e, 0x1a, -+ 0x44, 0xd1, 0xee, 0xc4, 0xb8, 0xde, 0x97, 0xb4, 0xda, 0xb4, 0x8b, 0x4f, -+ 0x58, 0x24, 0x59, 0xc0, 0xe0, 0x08, 0x97, 0x14, 0x68, 0xbe, 0x31, 0x09, -+ 0x5e, 0x67, 0x45, 0xf0, 0xcb, 0x81, 0x4f, 0x17, 0x44, 0x61, 0xe0, 0xe2, -+ 0xf0, 0xfc, 0x1e, 0xb9, 0x73, 0xaf, 0x42, 0xff, 0x33, 0xde, 0x61, 0x6b, -+ 0x7f, 0xc2, 0x69, 0x0d, 0x66, 0x54, 0xae, 0xf6, 0xde, 0x20, 0x47, 0x44, -+ 0x9b, 0x73, 0xd1, 0x07, 0x6e, 0x77, 0x37, 0x0a, 0xbb, 0x7f, 0xa0, 0x93, -+ 0x2d, 0x8d, 0x44, 0xba, 0xe2, 0xdd, 0x34, 0x32, 0xd7, 0x56, 0x71, 0x00, -+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e, -+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, -+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, -+ 0x64, 0x7e, 0x0a -+}; -+unsigned int hi_signed_sha256_len = 495; -+ -+unsigned char short_msg[] = { -+ 0x68, 0x69, 0x0a -+}; -+unsigned int short_msg_len = 3; -+ -+unsigned char unsigned_msg[] = { -+ 0x53, 0x65, 0x64, 0x20, 0x75, 0x74, 0x20, 0x70, 0x65, 0x72, 0x73, 0x70, -+ 0x69, 0x63, 0x69, 0x61, 0x74, 0x69, 0x73, 0x20, 0x75, 0x6e, 0x64, 0x65, -+ 0x20, 0x6f, 0x6d, 0x6e, 0x69, 0x73, 0x20, 0x69, 0x73, 0x74, 0x65, 0x20, -+ 0x6e, 0x61, 0x74, 0x75, 0x73, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, -+ 0x73, 0x69, 0x74, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x74, -+ 0x65, 0x6d, 0x20, 0x61, 0x63, 0x63, 0x75, 0x73, 0x61, 0x6e, 0x74, 0x69, -+ 0x75, 0x6d, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x71, 0x75, -+ 0x65, 0x20, 0x6c, 0x61, 0x75, 0x64, 0x61, 0x6e, 0x74, 0x69, 0x75, 0x6d, -+ 0x2c, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6d, 0x20, 0x72, 0x65, 0x6d, 0x20, -+ 0x61, 0x70, 0x65, 0x72, 0x69, 0x61, 0x6d, 0x2c, 0x20, 0x65, 0x61, 0x71, -+ 0x75, 0x65, 0x20, 0x69, 0x70, 0x73, 0x61, 0x20, 0x71, 0x75, 0x61, 0x65, -+ 0x20, 0x61, 0x62, 0x20, 0x69, 0x6c, 0x6c, 0x6f, 0x20, 0x69, 0x6e, 0x76, -+ 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x65, 0x20, 0x76, 0x65, 0x72, 0x69, 0x74, -+ 0x61, 0x74, 0x69, 0x73, 0x20, 0x65, 0x74, 0x20, 0x71, 0x75, 0x61, 0x73, -+ 0x69, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x6f, -+ 0x20, 0x62, 0x65, 0x61, 0x74, 0x61, 0x65, 0x20, 0x76, 0x69, 0x74, 0x61, -+ 0x65, 0x20, 0x64, 0x69, 0x63, 0x74, 0x61, 0x20, 0x73, 0x75, 0x6e, 0x74, -+ 0x20, 0x65, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6f, 0x2e, 0x20, -+ 0x4e, 0x65, 0x6d, 0x6f, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x20, 0x69, 0x70, -+ 0x73, 0x61, 0x6d, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x74, -+ 0x65, 0x6d, 0x20, 0x71, 0x75, 0x69, 0x61, 0x20, 0x76, 0x6f, 0x6c, 0x75, -+ 0x70, 0x74, 0x61, 0x73, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x73, 0x70, -+ 0x65, 0x72, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x20, 0x61, 0x75, 0x74, 0x20, -+ 0x6f, 0x64, 0x69, 0x74, 0x20, 0x61, 0x75, 0x74, 0x20, 0x66, 0x75, 0x67, -+ 0x69, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x64, 0x20, 0x71, 0x75, 0x69, 0x61, -+ 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x75, 0x6e, 0x74, 0x75, -+ 0x72, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x69, 0x20, 0x64, 0x6f, 0x6c, 0x6f, -+ 0x72, 0x65, 0x73, 0x20, 0x65, 0x6f, 0x73, 0x20, 0x71, 0x75, 0x69, 0x20, -+ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x20, 0x76, 0x6f, 0x6c, 0x75, -+ 0x70, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x20, 0x73, 0x65, 0x71, 0x75, 0x69, -+ 0x20, 0x6e, 0x65, 0x73, 0x63, 0x69, 0x75, 0x6e, 0x74, 0x2e, 0x20, 0x4e, -+ 0x65, 0x71, 0x75, 0x65, 0x20, 0x70, 0x6f, 0x72, 0x72, 0x6f, 0x20, 0x71, -+ 0x75, 0x69, 0x73, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x65, 0x73, 0x74, 0x2c, -+ 0x20, 0x71, 0x75, 0x69, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x65, 0x6d, -+ 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x71, 0x75, 0x69, 0x61, 0x20, -+ 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6d, -+ 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x65, -+ 0x74, 0x75, 0x72, 0x2c, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x63, -+ 0x69, 0x20, 0x76, 0x65, 0x6c, 0x69, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x64, -+ 0x20, 0x71, 0x75, 0x69, 0x61, 0x20, 0x6e, 0x6f, 0x6e, 0x20, 0x6e, 0x75, -+ 0x6d, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x65, 0x69, 0x75, 0x73, 0x20, 0x6d, -+ 0x6f, 0x64, 0x69, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x20, -+ 0x69, 0x6e, 0x63, 0x69, 0x64, 0x75, 0x6e, 0x74, 0x20, 0x75, 0x74, 0x20, -+ 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x65, 0x20, 0x65, 0x74, 0x20, 0x64, 0x6f, -+ 0x6c, 0x6f, 0x72, 0x65, 0x20, 0x6d, 0x61, 0x67, 0x6e, 0x61, 0x6d, 0x20, -+ 0x61, 0x6c, 0x69, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x71, 0x75, 0x61, 0x65, -+ 0x72, 0x61, 0x74, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x74, -+ 0x65, 0x6d, 0x2e, 0x20, 0x55, 0x74, 0x20, 0x65, 0x6e, 0x69, 0x6d, 0x20, -+ 0x61, 0x64, 0x20, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x20, 0x76, 0x65, -+ 0x6e, 0x69, 0x61, 0x6d, 0x2c, 0x20, 0x71, 0x75, 0x69, 0x73, 0x20, 0x6e, -+ 0x6f, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x20, 0x65, 0x78, 0x65, 0x72, 0x63, -+ 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x6d, 0x20, 0x75, 0x6c, -+ 0x6c, 0x61, 0x6d, 0x20, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x69, 0x73, -+ 0x20, 0x73, 0x75, 0x73, 0x63, 0x69, 0x70, 0x69, 0x74, 0x20, 0x6c, 0x61, -+ 0x62, 0x6f, 0x72, 0x69, 0x6f, 0x73, 0x61, 0x6d, 0x2c, 0x20, 0x6e, 0x69, -+ 0x73, 0x69, 0x20, 0x75, 0x74, 0x20, 0x61, 0x6c, 0x69, 0x71, 0x75, 0x69, -+ 0x64, 0x20, 0x65, 0x78, 0x20, 0x65, 0x61, 0x20, 0x63, 0x6f, 0x6d, 0x6d, -+ 0x6f, 0x64, 0x69, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x61, -+ 0x74, 0x75, 0x72, 0x3f, 0x20, 0x51, 0x75, 0x69, 0x73, 0x20, 0x61, 0x75, -+ 0x74, 0x65, 0x6d, 0x20, 0x76, 0x65, 0x6c, 0x20, 0x65, 0x75, 0x6d, 0x20, -+ 0x69, 0x75, 0x72, 0x65, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x68, 0x65, -+ 0x6e, 0x64, 0x65, 0x72, 0x69, 0x74, 0x20, 0x71, 0x75, 0x69, 0x20, 0x69, -+ 0x6e, 0x20, 0x65, 0x61, 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, -+ 0x74, 0x65, 0x20, 0x76, 0x65, 0x6c, 0x69, 0x74, 0x20, 0x65, 0x73, 0x73, -+ 0x65, 0x20, 0x71, 0x75, 0x61, 0x6d, 0x20, 0x6e, 0x69, 0x68, 0x69, 0x6c, -+ 0x20, 0x6d, 0x6f, 0x6c, 0x65, 0x73, 0x74, 0x69, 0x61, 0x65, 0x20, 0x63, -+ 0x6f, 0x6e, 0x73, 0x65, 0x71, 0x75, 0x61, 0x74, 0x75, 0x72, 0x2c, 0x20, -+ 0x76, 0x65, 0x6c, 0x20, 0x69, 0x6c, 0x6c, 0x75, 0x6d, 0x20, 0x71, 0x75, -+ 0x69, 0x20, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x65, 0x75, -+ 0x6d, 0x20, 0x66, 0x75, 0x67, 0x69, 0x61, 0x74, 0x20, 0x71, 0x75, 0x6f, -+ 0x20, 0x76, 0x6f, 0x6c, 0x75, 0x70, 0x74, 0x61, 0x73, 0x20, 0x6e, 0x75, -+ 0x6c, 0x6c, 0x61, 0x20, 0x70, 0x61, 0x72, 0x69, 0x61, 0x74, 0x75, 0x72, -+ 0x3f, 0x0a -+}; -+unsigned int unsigned_msg_len = 866; -+ -+unsigned char certificate2_der[] = { -+ 0x30, 0x82, 0x05, 0x52, 0x30, 0x82, 0x03, 0x3a, 0xa0, 0x03, 0x02, 0x01, -+ 0x02, 0x02, 0x14, 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, -+ 0x3a, 0x91, 0x07, 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x91, 0xff, 0x30, -+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, -+ 0x05, 0x00, 0x30, 0x3a, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, -+ 0x03, 0x0c, 0x2f, 0x47, 0x72, 0x75, 0x62, 0x20, 0x32, 0x6e, 0x64, 0x20, -+ 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, -+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, -+ 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, -+ 0x74, 0x79, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x37, 0x32, 0x38, -+ 0x31, 0x33, 0x32, 0x34, 0x32, 0x39, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x32, -+ 0x30, 0x30, 0x37, 0x30, 0x34, 0x31, 0x33, 0x32, 0x34, 0x32, 0x39, 0x5a, -+ 0x30, 0x2b, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, -+ 0x20, 0x47, 0x72, 0x75, 0x62, 0x20, 0x32, 0x6e, 0x64, 0x20, 0x43, 0x65, -+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, -+ 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x65, 0x79, 0x30, 0x82, 0x02, -+ 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, -+ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, -+ 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xb0, 0x2f, 0x50, 0x01, 0x9c, 0x0e, -+ 0xd6, 0x8c, 0x07, 0xca, 0xc1, 0xcf, 0xbc, 0x03, 0xdd, 0xd3, 0xfa, 0xe3, -+ 0x4f, 0x71, 0xc1, 0x30, 0xaa, 0x09, 0x96, 0xe4, 0xd0, 0x6c, 0x42, 0x93, -+ 0xdb, 0x35, 0xf6, 0x7e, 0x1b, 0x67, 0xc0, 0xc2, 0x2d, 0x5b, 0xec, 0xca, -+ 0x35, 0x06, 0x32, 0x6c, 0x7b, 0x2c, 0xd3, 0x71, 0x2b, 0xe9, 0x7a, 0x19, -+ 0xd1, 0xf2, 0xa0, 0x7f, 0xd7, 0x4d, 0x6e, 0x28, 0xbb, 0xae, 0x49, 0x4a, -+ 0xbc, 0xea, 0x47, 0x67, 0xb8, 0x36, 0xa6, 0xf5, 0x0d, 0x0e, 0x20, 0x14, -+ 0x0c, 0x66, 0x67, 0x28, 0xb5, 0x97, 0x8b, 0x1f, 0x5e, 0x32, 0x06, 0x29, -+ 0x9c, 0x99, 0x92, 0x0f, 0x73, 0xac, 0xfd, 0xd2, 0x1d, 0xf2, 0xa8, 0x55, -+ 0x9d, 0x1b, 0xd8, 0x3d, 0xb0, 0x76, 0x9a, 0xb6, 0x6c, 0x9f, 0x62, 0x37, -+ 0x2f, 0xc0, 0xef, 0x44, 0xb3, 0x0d, 0x4a, 0x3e, 0x4f, 0x7d, 0xbd, 0xdb, -+ 0xd8, 0x75, 0x5f, 0x68, 0xe3, 0xf0, 0xec, 0x82, 0x66, 0x7c, 0x31, 0x70, -+ 0xa9, 0xa1, 0x6f, 0x38, 0x9f, 0xdf, 0xf5, 0xf0, 0x7d, 0x23, 0x9d, 0x34, -+ 0xa5, 0x85, 0xd3, 0xdf, 0x68, 0x41, 0xfc, 0x4f, 0x89, 0x45, 0x3c, 0x24, -+ 0x81, 0xa6, 0xf2, 0x3c, 0x02, 0x26, 0x09, 0x48, 0xdd, 0xfe, 0x4b, 0xb6, -+ 0x66, 0xbf, 0x8f, 0xe5, 0x5f, 0xf0, 0x5d, 0x8a, 0x61, 0x2e, 0x5f, 0x9f, -+ 0x80, 0xd9, 0xd5, 0xe6, 0x41, 0xd8, 0x10, 0x5e, 0x7a, 0xc6, 0xdb, 0x89, -+ 0xc7, 0xca, 0x6c, 0x5b, 0xb1, 0x4e, 0x7d, 0x0c, 0x03, 0xfd, 0x50, 0xca, -+ 0xbf, 0xbb, 0xe2, 0x69, 0x4b, 0x4e, 0xc2, 0x3d, 0x75, 0xfa, 0xd1, 0xcc, -+ 0xd6, 0xf9, 0x39, 0xb9, 0xdc, 0x53, 0xad, 0x62, 0xfb, 0x1b, 0x94, 0x26, -+ 0x7f, 0x21, 0x54, 0x5c, 0xb7, 0xdc, 0xe7, 0x96, 0x8c, 0xce, 0x75, 0xe0, -+ 0x17, 0x01, 0x3a, 0x3c, 0x77, 0x6e, 0xa4, 0x8b, 0x7a, 0x83, 0x28, 0x7a, -+ 0xf7, 0xb0, 0x5f, 0xfc, 0x7f, 0x2d, 0x2e, 0xec, 0xf5, 0xeb, 0x9c, 0x63, -+ 0x74, 0xd0, 0xe5, 0xdc, 0x19, 0xe4, 0x71, 0xc5, 0x4a, 0x8a, 0x54, 0xa4, -+ 0xe0, 0x7d, 0x4e, 0xbf, 0x53, 0x30, 0xaf, 0xd0, 0xeb, 0x96, 0xc3, 0xbb, -+ 0x65, 0xf7, 0x67, 0xf5, 0xae, 0xd3, 0x96, 0xf2, 0x63, 0xc8, 0x69, 0xf7, -+ 0x47, 0xcb, 0x27, 0x79, 0xe1, 0xff, 0x2f, 0x68, 0xdf, 0x1e, 0xb3, 0xb8, -+ 0x0c, 0xc5, 0x58, 0x73, 0xcc, 0xfe, 0x8c, 0xda, 0x4e, 0x3b, 0x01, 0x04, -+ 0xcd, 0xcb, 0xb8, 0x3e, 0x06, 0xfd, 0x4c, 0x0a, 0x9f, 0x5e, 0x76, 0x8c, -+ 0x0c, 0x83, 0x75, 0x09, 0x08, 0xb2, 0xdb, 0xf4, 0x49, 0x4e, 0xa0, 0xf2, -+ 0x0c, 0x7b, 0x87, 0x38, 0x9e, 0x22, 0x67, 0xbd, 0xd1, 0x97, 0x57, 0x24, -+ 0xf1, 0x46, 0x07, 0xf9, 0xd2, 0x1b, 0xec, 0x25, 0x5e, 0x67, 0xd9, 0x66, -+ 0x23, 0x1b, 0xd3, 0xe4, 0xaa, 0xec, 0x88, 0xf0, 0x7e, 0x15, 0x83, 0x51, -+ 0x31, 0x67, 0x51, 0x76, 0x5f, 0x55, 0xd7, 0x36, 0xdf, 0x4a, 0x84, 0x0b, -+ 0x6f, 0x5c, 0xbb, 0x5b, 0x8f, 0x37, 0x23, 0x7f, 0xf8, 0x17, 0x84, 0xa2, -+ 0x70, 0x20, 0x07, 0x0c, 0x90, 0x3a, 0x04, 0xfd, 0xf0, 0x08, 0x4a, 0xb1, -+ 0x16, 0x0f, 0xe6, 0xf6, 0x40, 0x51, 0x83, 0xd2, 0x87, 0x40, 0x9c, 0x1c, -+ 0x9f, 0x13, 0x38, 0x17, 0xd3, 0x34, 0x58, 0xad, 0x05, 0x71, 0xa0, 0x73, -+ 0xca, 0x40, 0xa6, 0xa4, 0x81, 0x02, 0xee, 0xa8, 0x72, 0x41, 0xa1, 0x41, -+ 0x18, 0x64, 0x8a, 0x86, 0x8a, 0x5d, 0xe6, 0x4f, 0x0a, 0xc5, 0x95, 0x98, -+ 0xf9, 0x78, 0xfe, 0x19, 0x0d, 0xc9, 0xb3, 0x89, 0xc1, 0x2b, 0x09, 0xbe, -+ 0xf1, 0xd2, 0x04, 0x5d, 0xcc, 0x28, 0xf5, 0x4b, 0xd2, 0x20, 0x4f, 0xc5, -+ 0x41, 0x9d, 0x8c, 0x85, 0xd8, 0xb0, 0x68, 0x5e, 0xc1, 0x0c, 0xb7, 0x24, -+ 0x4d, 0x67, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x5d, 0x30, 0x5b, 0x30, -+ 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, -+ 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, -+ 0x07, 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, -+ 0x14, 0xac, 0xf5, 0x47, 0x17, 0xd9, 0x7d, 0xc1, 0xb1, 0xc4, 0x41, 0xe1, -+ 0x41, 0x60, 0xcb, 0x37, 0x11, 0x60, 0x28, 0x78, 0x5f, 0x30, 0x1f, 0x06, -+ 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x21, 0x94, -+ 0xfb, 0xf9, 0xb2, 0x43, 0xe9, 0x33, 0xd7, 0x50, 0x7d, 0xc7, 0x37, 0xdb, -+ 0xd5, 0x82, 0x5a, 0x4e, 0xbe, 0x1b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, -+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, -+ 0x01, 0x00, 0x96, 0x70, 0x65, 0x26, 0x42, 0xf8, 0xdc, 0x69, 0xde, 0xcf, -+ 0x41, 0x3a, 0x2e, 0x7f, 0x5b, 0xf1, 0xf9, 0x3b, 0x9b, 0xd2, 0x4e, 0x64, -+ 0x48, 0x81, 0xe4, 0x5d, 0x1e, 0x22, 0xce, 0x68, 0x63, 0x62, 0xe5, 0x1b, -+ 0x9b, 0xf2, 0xc7, 0x12, 0xda, 0x1e, 0x9b, 0x90, 0x84, 0x79, 0x48, 0x12, -+ 0xe6, 0x21, 0x6f, 0x2f, 0x7e, 0x18, 0x77, 0xdb, 0x8c, 0xc4, 0xd1, 0x0d, -+ 0x91, 0xbf, 0x39, 0x22, 0x0f, 0x64, 0xcf, 0x25, 0x2e, 0x8c, 0x1f, 0x91, -+ 0x81, 0xb5, 0xe9, 0x6c, 0x02, 0x3a, 0xf8, 0x07, 0xa2, 0x6f, 0x46, 0x5d, -+ 0x7b, 0xfd, 0x43, 0xff, 0x41, 0x0f, 0xe2, 0x57, 0x1c, 0xbd, 0x48, 0x60, -+ 0x53, 0x11, 0x48, 0x87, 0x88, 0x9d, 0x13, 0x82, 0x40, 0x68, 0x44, 0x2c, -+ 0xc6, 0xc8, 0x95, 0x27, 0x4f, 0xb6, 0xb9, 0x4a, 0x22, 0x0a, 0xfd, 0xe4, -+ 0x46, 0x8f, 0x35, 0x12, 0x98, 0x5a, 0x34, 0x6f, 0x2b, 0x57, 0x62, 0xa1, -+ 0x4d, 0x8d, 0x79, 0x37, 0xe4, 0x6b, 0x8a, 0x32, 0x5b, 0xcb, 0xef, 0x79, -+ 0x11, 0xed, 0xa7, 0xf8, 0x7a, 0x1c, 0xbd, 0x86, 0xdc, 0x0e, 0x2e, 0xfd, -+ 0xd3, 0x51, 0xbb, 0x73, 0xad, 0x00, 0xa0, 0x1b, 0xf9, 0x1d, 0xd1, 0x4a, -+ 0xe4, 0xd4, 0x02, 0x63, 0x2b, 0x39, 0x5f, 0x18, 0x08, 0x2f, 0x42, 0xb7, -+ 0x23, 0x4b, 0x48, 0x46, 0x1f, 0x63, 0x87, 0xae, 0x6d, 0xd5, 0xdb, 0x60, -+ 0xf8, 0x5f, 0xd3, 0x13, 0xec, 0xca, 0xdd, 0x60, 0x60, 0x79, 0x52, 0x70, -+ 0x47, 0xae, 0x1d, 0x38, 0x78, 0x71, 0xcf, 0xb3, 0x04, 0x03, 0xbe, 0xba, -+ 0x81, 0xba, 0x74, 0xb1, 0x30, 0x35, 0xdc, 0xea, 0x21, 0x4a, 0x9b, 0x70, -+ 0xfb, 0xd6, 0x60, 0x59, 0x78, 0x0c, 0x4d, 0x39, 0x19, 0x1d, 0xe5, 0x75, -+ 0xba, 0x07, 0xf4, 0x22, 0x37, 0x64, 0xb7, 0xf2, 0x9a, 0xc9, 0x11, 0x2d, -+ 0x8e, 0x58, 0xa6, 0xcf, 0x83, 0xf1, 0xcb, 0x6c, 0x7f, 0x02, 0xbd, 0xda, -+ 0x03, 0x92, 0xa9, 0x45, 0x24, 0x56, 0xc5, 0xbd, 0x41, 0xd1, 0x20, 0x86, -+ 0xc0, 0xb6, 0xb7, 0xe8, 0xa7, 0xb2, 0x46, 0xf7, 0x8e, 0xa9, 0x38, 0x0e, -+ 0x23, 0x77, 0x3c, 0x0d, 0x66, 0x83, 0x6a, 0x1a, 0x6b, 0x7f, 0x54, 0x11, -+ 0x58, 0x0d, 0x4a, 0xb5, 0x74, 0x60, 0xca, 0xed, 0xff, 0x91, 0x47, 0xd9, -+ 0x29, 0xe0, 0xaa, 0x8c, 0xa8, 0x8f, 0x10, 0x4c, 0x15, 0x7d, 0xce, 0x95, -+ 0xf9, 0x87, 0x1e, 0x18, 0x38, 0x18, 0xfc, 0xcc, 0xaf, 0x91, 0x17, 0x3f, -+ 0xfa, 0xf0, 0x8a, 0x09, 0x6f, 0xba, 0x4e, 0x53, 0xf7, 0xfa, 0x4f, 0x20, -+ 0xa3, 0xf4, 0x4a, 0x5a, 0xde, 0x17, 0x1c, 0x29, 0x6a, 0x6f, 0x03, 0x48, -+ 0xdf, 0xad, 0x4f, 0xe4, 0xbc, 0x71, 0xc4, 0x72, 0x32, 0x11, 0x84, 0xac, -+ 0x09, 0xd2, 0x18, 0x44, 0x35, 0xf1, 0xcd, 0xaf, 0xa8, 0x98, 0xe0, 0x8b, -+ 0xec, 0xa0, 0x83, 0x37, 0xc3, 0x35, 0x85, 0xd6, 0xd8, 0x1b, 0xe0, 0x75, -+ 0xdc, 0xfd, 0xde, 0xc9, 0xeb, 0xd5, 0x18, 0x0f, 0xd3, 0x4c, 0x2f, 0x71, -+ 0xdc, 0x48, 0xe3, 0x14, 0xeb, 0xda, 0x00, 0x24, 0x24, 0x9e, 0xa3, 0x8e, -+ 0x3e, 0x08, 0x6f, 0x22, 0x24, 0xd6, 0xc4, 0x85, 0x8f, 0x68, 0x00, 0x4a, -+ 0x82, 0x4c, 0x33, 0x6e, 0xa5, 0x35, 0x7b, 0xeb, 0x4b, 0xdc, 0xa0, 0xa6, -+ 0x65, 0x6f, 0x5a, 0x7a, 0xdf, 0x8a, 0x01, 0x52, 0xa1, 0x6c, 0xff, 0x59, -+ 0x22, 0x7f, 0xe1, 0x96, 0x1b, 0x19, 0xb8, 0xf9, 0x5d, 0x44, 0x9f, 0x91, -+ 0x03, 0x3c, 0x3d, 0xa1, 0x2a, 0xb6, 0x5a, 0x51, 0xa0, 0xce, 0x4a, 0x88, -+ 0x22, 0x72, 0x9c, 0xdc, 0xc0, 0x47, 0x76, 0x35, 0x84, 0x75, 0x9b, 0x87, -+ 0x5c, 0xd3, 0xcf, 0xe7, 0xdd, 0xa3, 0x57, 0x14, 0xdf, 0x00, 0xfd, 0x19, -+ 0x2a, 0x7d, 0x89, 0x27, 0x1c, 0x78, 0x97, 0x04, 0x58, 0x48 -+}; -+unsigned int certificate2_der_len = 1366; -+ -+unsigned char hi_signed_2nd[] = { -+ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x02, 0xb1, 0x06, 0x09, 0x2a, 0x86, 0x48, -+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0xa2, 0x30, 0x82, -+ 0x02, 0x9e, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, -+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x02, -+ 0x7b, 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x01, 0x30, 0x52, 0x30, 0x3a, -+ 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x47, -+ 0x72, 0x75, 0x62, 0x20, 0x32, 0x6e, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, -+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, -+ 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, -+ 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02, 0x14, -+ 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, 0x3a, 0x91, 0x07, -+ 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x91, 0xff, 0x30, 0x0b, 0x06, 0x09, -+ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0d, 0x06, -+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, -+ 0x04, 0x82, 0x02, 0x00, 0x0e, 0xc2, 0x30, 0x38, 0x81, 0x23, 0x68, 0x90, -+ 0xae, 0x5f, 0xce, 0xf7, 0x27, 0xb1, 0x8c, 0x2e, 0x12, 0x10, 0xc6, 0x99, -+ 0xdc, 0x4d, 0x4b, 0x79, 0xda, 0xe4, 0x32, 0x10, 0x46, 0x1c, 0x16, 0x07, -+ 0x87, 0x66, 0x55, 0xff, 0x64, 0x1c, 0x61, 0x25, 0xd5, 0xb9, 0xe1, 0xfe, -+ 0xea, 0x5a, 0xcd, 0x56, 0xa5, 0xc3, 0xbe, 0xb1, 0x61, 0xc7, 0x6f, 0x5f, -+ 0x69, 0x20, 0x64, 0x50, 0x6f, 0x12, 0x78, 0xb6, 0x0c, 0x72, 0x44, 0x4f, -+ 0x60, 0x0f, 0x9f, 0xa2, 0x83, 0x3b, 0xc2, 0x83, 0xd5, 0x14, 0x1f, 0x6f, -+ 0x3e, 0xb2, 0x47, 0xb5, 0x58, 0xc5, 0xa7, 0xb4, 0x82, 0x53, 0x2e, 0x53, -+ 0x95, 0x4e, 0x3d, 0xe4, 0x62, 0xe8, 0xa1, 0xaf, 0xae, 0xbf, 0xa9, 0xd2, -+ 0x22, 0x07, 0xbe, 0x71, 0x37, 0x2c, 0x5a, 0xa7, 0x6c, 0xaf, 0x14, 0xc0, -+ 0x6c, 0x2f, 0xbf, 0x4f, 0x15, 0xc2, 0x0f, 0x8b, 0xdc, 0x68, 0x45, 0xdf, -+ 0xf3, 0xa5, 0x7f, 0x11, 0x6a, 0x54, 0xcd, 0x67, 0xb9, 0x2e, 0x7d, 0x05, -+ 0xe3, 0x1c, 0x1d, 0xcc, 0x77, 0x8e, 0x97, 0xb1, 0xa0, 0x11, 0x09, 0x3d, -+ 0x90, 0x54, 0xfc, 0x7e, 0xbb, 0xbb, 0x21, 0x23, 0x03, 0x44, 0xbf, 0x7d, -+ 0x2c, 0xc9, 0x15, 0x42, 0xe5, 0xa0, 0x3b, 0xa2, 0xd1, 0x5b, 0x73, 0x81, -+ 0xff, 0xfa, 0x90, 0xfc, 0x27, 0x7b, 0x2f, 0x86, 0x9c, 0x1d, 0x14, 0x36, -+ 0x94, 0xa2, 0x6e, 0xe8, 0x9d, 0xa0, 0x5f, 0xfc, 0x5a, 0x0d, 0xa4, 0xd5, -+ 0x2f, 0x8d, 0xd6, 0x00, 0xfa, 0x93, 0x5b, 0x09, 0x7f, 0x42, 0x78, 0xcc, -+ 0x8c, 0x49, 0xda, 0xd9, 0xf6, 0x43, 0xe7, 0xe1, 0x3c, 0xa2, 0xe2, 0x70, -+ 0xe2, 0x6a, 0x99, 0xc5, 0xd6, 0xa2, 0xe3, 0x0b, 0xd4, 0x09, 0xac, 0x94, -+ 0xaf, 0xb7, 0xf0, 0xb3, 0x0c, 0x1e, 0xf5, 0x16, 0x4f, 0x53, 0x9a, 0xe3, -+ 0xcc, 0xe2, 0x0c, 0x4a, 0xb9, 0xe6, 0x06, 0xbb, 0xf7, 0x41, 0x43, 0x20, -+ 0x04, 0xee, 0x99, 0x2f, 0xd8, 0x9f, 0xda, 0x3f, 0xfd, 0x49, 0xb8, 0xc2, -+ 0xbd, 0xd9, 0xc5, 0x72, 0xfd, 0xe3, 0xce, 0x1c, 0xbc, 0xe4, 0x39, 0xac, -+ 0x2a, 0x99, 0xe9, 0xb4, 0x3e, 0x74, 0x10, 0xeb, 0xd5, 0x14, 0xcc, 0xdb, -+ 0xf1, 0x04, 0x63, 0x36, 0xfb, 0x1f, 0x2b, 0xe2, 0x73, 0xd4, 0xd8, 0x49, -+ 0x31, 0xa8, 0x55, 0xcc, 0xa7, 0x76, 0x36, 0x6e, 0x18, 0xdc, 0xb9, 0xb0, -+ 0x29, 0x99, 0xcf, 0x49, 0xbf, 0xf9, 0xdb, 0x7f, 0x24, 0x42, 0x02, 0xcb, -+ 0xc1, 0xaa, 0xcb, 0xba, 0x18, 0x85, 0x86, 0xc7, 0xf4, 0x1c, 0x62, 0x76, -+ 0xbc, 0x73, 0xfb, 0xe4, 0x15, 0xb8, 0xdd, 0x5d, 0xa6, 0x68, 0x39, 0xa5, -+ 0x3d, 0x33, 0xaf, 0xd5, 0x92, 0x4d, 0x48, 0xdb, 0x22, 0xc0, 0xdc, 0x49, -+ 0x5f, 0x7b, 0xa8, 0xd2, 0x62, 0x2d, 0xa7, 0x39, 0x93, 0x48, 0xe7, 0x6b, -+ 0x23, 0xba, 0xd4, 0xe0, 0xc1, 0x29, 0x55, 0xc4, 0x34, 0xe3, 0xac, 0x25, -+ 0xa7, 0x15, 0xad, 0xab, 0xb3, 0xb7, 0x25, 0xca, 0x37, 0x88, 0x40, 0x2e, -+ 0x47, 0x6e, 0x92, 0x20, 0x09, 0x2e, 0x5a, 0xec, 0xf2, 0xfb, 0xb3, 0xa0, -+ 0x16, 0xb6, 0x93, 0xf2, 0xf5, 0x8b, 0xfe, 0xaf, 0x25, 0xee, 0x2e, 0x98, -+ 0x6c, 0x0a, 0xfe, 0xae, 0x0b, 0x57, 0xf5, 0x9f, 0x3c, 0x80, 0xe9, 0x8b, -+ 0xaf, 0x92, 0x8a, 0xad, 0xe7, 0xa0, 0xe4, 0xe6, 0x0a, 0xa0, 0xc7, 0x83, -+ 0xb5, 0x48, 0x58, 0x5f, 0x55, 0x9e, 0x9b, 0x27, 0xcd, 0x31, 0x1f, 0x3e, -+ 0x50, 0x5a, 0x91, 0xad, 0x21, 0x1b, 0x97, 0x5b, 0xe8, 0xfa, 0x29, 0x8a, -+ 0xa4, 0x17, 0xe8, 0xab, 0x87, 0x02, 0xd6, 0x18, 0x8c, 0x9f, 0x65, 0xb7, -+ 0x2a, 0xfa, 0xde, 0x5f, 0x77, 0x30, 0x6c, 0x04, 0x22, 0xe6, 0x58, 0x26, -+ 0x14, 0x0d, 0x9c, 0x41, 0x0a, 0x82, 0x77, 0xdb, 0x40, 0xa1, 0x58, 0xac, -+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xb5, -+ 0x7e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, -+ 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, -+ 0x65, 0x64, 0x7e, 0x0a -+}; -+unsigned int hi_signed_2nd_len = 736; -+ -+unsigned char certificate_printable_der[] = { -+ 0x30, 0x82, 0x03, 0x39, 0x30, 0x82, 0x02, 0x21, 0xa0, 0x03, 0x02, 0x01, -+ 0x02, 0x02, 0x09, 0x00, 0xde, 0xf6, 0x22, 0xc4, 0xf2, 0xf1, 0x86, 0x02, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x0b, 0x05, 0x00, 0x30, 0x2a, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, -+ 0x04, 0x03, 0x13, 0x1f, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, -+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, -+ 0x43, 0x41, 0x20, 0x32, 0x20, 0x28, 0x62, 0x65, 0x74, 0x61, 0x29, 0x30, -+ 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30, 0x33, 0x31, 0x31, 0x34, 0x31, -+ 0x39, 0x32, 0x33, 0x5a, 0x17, 0x0d, 0x33, 0x37, 0x31, 0x30, 0x32, 0x35, -+ 0x31, 0x34, 0x31, 0x39, 0x32, 0x33, 0x5a, 0x30, 0x2f, 0x31, 0x2d, 0x30, -+ 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x52, 0x65, 0x64, 0x20, -+ 0x48, 0x61, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42, -+ 0x6f, 0x6f, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, -+ 0x33, 0x20, 0x28, 0x62, 0x65, 0x74, 0x61, 0x29, 0x30, 0x82, 0x01, 0x22, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, -+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xda, 0xa1, 0xed, 0x8d, 0x8e, 0x15, -+ 0x5c, 0xf8, 0x01, 0x77, 0x48, 0x4a, 0x60, 0x96, 0xf9, 0x27, 0xfa, 0xe2, -+ 0xb1, 0x69, 0x0f, 0x51, 0x19, 0x52, 0x7e, 0xc4, 0x34, 0x8e, 0xe1, 0x9b, -+ 0x9c, 0xa4, 0xb1, 0x5c, 0xd6, 0x81, 0x98, 0x78, 0xfe, 0xa9, 0xe5, 0x0b, -+ 0x00, 0xba, 0x9c, 0x64, 0x7e, 0xc7, 0xcc, 0x72, 0xb1, 0x73, 0x4b, 0x11, -+ 0x07, 0x52, 0xf0, 0x20, 0x96, 0x8b, 0x99, 0x39, 0xde, 0xdb, 0xfa, 0x3d, -+ 0x45, 0xe2, 0x98, 0x7b, 0x0c, 0x41, 0xe4, 0x0c, 0xb5, 0x5d, 0x92, 0x74, -+ 0x39, 0x96, 0xe1, 0x97, 0x97, 0xa1, 0xad, 0x2e, 0xcc, 0xd0, 0x1b, 0x4d, -+ 0x9d, 0xbd, 0x3e, 0xa9, 0x36, 0x8e, 0xcc, 0xc7, 0x5f, 0x6a, 0x7d, 0x39, -+ 0x5e, 0x0b, 0x8d, 0xca, 0xe4, 0x83, 0xe9, 0x3b, 0x5c, 0x86, 0x47, 0xd4, -+ 0xba, 0x7d, 0x98, 0x26, 0xa1, 0xf4, 0xe8, 0x90, 0x6b, 0x0f, 0xf1, 0x6b, -+ 0x8c, 0xe3, 0xa2, 0x80, 0x3c, 0x96, 0xf1, 0x0a, 0xb6, 0x66, 0xc0, 0x4b, -+ 0x61, 0xf7, 0x74, 0xcd, 0xd3, 0x7b, 0x8e, 0x5e, 0x39, 0xda, 0x99, 0x20, -+ 0x33, 0x93, 0xd3, 0xf0, 0x7f, 0xad, 0x35, 0xe9, 0x88, 0x8d, 0x9c, 0xbf, -+ 0x65, 0xf1, 0x47, 0x02, 0xf9, 0x7c, 0xed, 0x27, 0x5f, 0x4a, 0x65, 0x3c, -+ 0xcf, 0x5f, 0x0e, 0x88, 0x95, 0x74, 0xde, 0xfb, 0x9e, 0x2e, 0x91, 0x9b, -+ 0x45, 0x37, 0xc8, 0x85, 0xff, 0xe3, 0x41, 0x70, 0xfe, 0xd5, 0xef, 0x0e, -+ 0x82, 0x22, 0x08, 0xb7, 0x3b, 0x44, 0x3e, 0xdc, 0x5b, 0x7f, 0xba, 0xbf, -+ 0xe6, 0x58, 0x9d, 0x02, 0x6e, 0x75, 0xbf, 0x50, 0xec, 0xcf, 0x3f, 0xa5, -+ 0x91, 0x0a, 0xe2, 0x59, 0x2c, 0xc3, 0xe7, 0x05, 0x03, 0xe8, 0xf2, 0x6f, -+ 0x2a, 0x04, 0x68, 0x9a, 0x31, 0x32, 0x8f, 0x04, 0x35, 0xcd, 0x1f, 0x34, -+ 0xcc, 0x4f, 0x79, 0x5a, 0x99, 0x8d, 0x9d, 0x5c, 0xf5, 0x02, 0x03, 0x01, -+ 0x00, 0x01, 0xa3, 0x5d, 0x30, 0x5b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, -+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, -+ 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x1d, 0x06, -+ 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x65, 0xc5, 0xbe, 0xca, -+ 0xe6, 0x59, 0x6a, 0xfd, 0x6c, 0x71, 0xc4, 0xa7, 0x98, 0xc6, 0x25, 0x8d, -+ 0x7b, 0x67, 0x05, 0xd0, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, -+ 0x18, 0x30, 0x16, 0x80, 0x14, 0x81, 0xf8, 0xee, 0x47, 0x5c, 0x3e, 0xed, -+ 0xfb, 0xce, 0xa5, 0x84, 0xbe, 0xd7, 0xae, 0xdb, 0xd3, 0x7d, 0x64, 0xb3, -+ 0x2a, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, -+ 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x66, 0x1e, 0x3d, -+ 0x1d, 0x53, 0x33, 0xde, 0x4e, 0xc7, 0xc4, 0xf4, 0xdf, 0xda, 0x18, 0x19, -+ 0x8a, 0xa9, 0xff, 0xe2, 0x63, 0x2b, 0xbe, 0xf2, 0x61, 0x63, 0xe2, 0xf6, -+ 0xed, 0x47, 0x1a, 0x71, 0x02, 0xec, 0x2a, 0xef, 0x89, 0x77, 0xe3, 0xfd, -+ 0x86, 0x69, 0xf1, 0x3f, 0x0d, 0xf9, 0x6e, 0xf9, 0x3b, 0xad, 0x26, 0x47, -+ 0xb7, 0xf2, 0x0d, 0xad, 0x23, 0xa3, 0x67, 0x3b, 0xcb, 0x6d, 0x9e, 0x03, -+ 0x0f, 0xbc, 0x69, 0x73, 0x9f, 0xd4, 0xa5, 0x0f, 0x6f, 0xf8, 0xab, 0x4d, -+ 0x36, 0xd1, 0xe0, 0xe0, 0x5d, 0x20, 0x43, 0x90, 0xc4, 0x65, 0x61, 0x93, -+ 0xe2, 0x0f, 0x51, 0x59, 0x0a, 0xf7, 0x88, 0x70, 0x57, 0xb9, 0x04, 0xa9, -+ 0x32, 0x57, 0x9c, 0xb3, 0x57, 0x38, 0x8b, 0x8e, 0x46, 0xc8, 0x32, 0x6c, -+ 0xb4, 0xf3, 0x96, 0x7f, 0x4b, 0xf0, 0x88, 0xf9, 0x7f, 0xe2, 0x71, 0xe1, -+ 0x8b, 0xe2, 0x14, 0xf1, 0x4b, 0x25, 0x00, 0x48, 0x1c, 0x7e, 0xe5, 0x8d, -+ 0x65, 0x2d, 0xeb, 0x72, 0x4f, 0x92, 0x44, 0xf3, 0xe6, 0xe0, 0xd0, 0xdf, -+ 0x85, 0xa8, 0x13, 0x4a, 0xfb, 0x99, 0xca, 0x14, 0x2c, 0x97, 0x80, 0x93, -+ 0x27, 0xd3, 0x20, 0xf8, 0x6d, 0x29, 0x28, 0x2c, 0xb9, 0x77, 0xea, 0xb1, -+ 0x63, 0xbd, 0x7d, 0x53, 0xfd, 0x4a, 0x62, 0x64, 0x0b, 0x98, 0xa8, 0xae, -+ 0x11, 0xfc, 0x6e, 0x8d, 0x63, 0xd4, 0x15, 0x55, 0xc6, 0x4c, 0x74, 0xf5, -+ 0x5f, 0xa0, 0xb9, 0x2c, 0x2d, 0x9a, 0x7a, 0x87, 0x6e, 0xf0, 0x5e, 0x25, -+ 0xed, 0xfc, 0xd8, 0xc4, 0x34, 0x33, 0x32, 0xad, 0x01, 0xd4, 0x4b, 0x49, -+ 0x51, 0xc2, 0x07, 0x7f, 0x90, 0x6d, 0xea, 0xf5, 0x4c, 0x41, 0x71, 0x64, -+ 0xeb, 0x1f, 0x29, 0xa3, 0x1f, 0x64, 0xa2, 0x1e, 0x0e, 0x6f, 0xa1, 0x67, -+ 0x99, 0x8d, 0x98, 0x1c, 0xb8, 0x53, 0x9d, 0x30, 0x1d, 0xae, 0x32, 0x56, -+ 0xd2 -+}; -+unsigned int certificate_printable_der_len = 829; diff --git a/0179-appended-signatures-documentation.patch b/0179-appended-signatures-documentation.patch deleted file mode 100644 index 864cfa3..0000000 --- a/0179-appended-signatures-documentation.patch +++ /dev/null @@ -1,341 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 1 Oct 2020 13:02:09 +1000 -Subject: [PATCH] appended signatures: documentation - -This explains how appended signatures can be used to form part of -a secure boot chain, and documents the commands and variables -introduced. - -Signed-off-by: Daniel Axtens ---- - docs/grub.texi | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 182 insertions(+), 17 deletions(-) - -diff --git a/docs/grub.texi b/docs/grub.texi -index afbde7c1f7b..4816be85611 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -3214,6 +3214,7 @@ These variables have special meaning to GRUB. - - @menu - * biosnum:: -+* check_appended_signatures:: - * check_signatures:: - * chosen:: - * cmdpath:: -@@ -3273,11 +3274,18 @@ For an alternative approach which also changes BIOS drive mappings for the - chain-loaded system, @pxref{drivemap}. - - -+@node check_appended_signatures -+@subsection check_appended_signatures -+ -+This variable controls whether GRUB enforces appended signature validation on -+certain loaded files. @xref{Using appended signatures}. -+ -+ - @node check_signatures - @subsection check_signatures - --This variable controls whether GRUB enforces digital signature --validation on loaded files. @xref{Using digital signatures}. -+This variable controls whether GRUB enforces GPG-style digital signature -+validation on loaded files. @xref{Using GPG-style digital signatures}. - - @node chosen - @subsection chosen -@@ -3994,6 +4002,7 @@ you forget a command, you can run the command @command{help} - * date:: Display or set current date and time - * devicetree:: Load a device tree blob - * distrust:: Remove a pubkey from trusted keys -+* distrust_certificate:: Remove a certificate from the list of trusted certificates - * drivemap:: Map a drive to another - * echo:: Display a line of text - * eval:: Evaluate agruments as GRUB commands -@@ -4010,6 +4019,7 @@ you forget a command, you can run the command @command{help} - * keystatus:: Check key modifier status - * linux:: Load a Linux kernel - * linux16:: Load a Linux kernel (16-bit mode) -+* list_certificates:: List trusted certificates - * list_env:: List variables in environment block - * list_trusted:: List trusted public keys - * load_env:: Load variables from environment block -@@ -4047,8 +4057,10 @@ you forget a command, you can run the command @command{help} - * test:: Check file types and compare values - * true:: Do nothing, successfully - * trust:: Add public key to list of trusted keys -+* trust_certificate:: Add an x509 certificate to the list of trusted certificates - * unset:: Unset an environment variable - @comment * vbeinfo:: List available video modes -+* verify_appended:: Verify appended digital signature - * verify_detached:: Verify detached digital signature - * videoinfo:: List available video modes - @comment * xen_*:: Xen boot commands for AArch64 -@@ -4376,9 +4388,28 @@ These keys are used to validate signatures when environment variable - @code{check_signatures} is set to @code{enforce} - (@pxref{check_signatures}), and by some invocations of - @command{verify_detached} (@pxref{verify_detached}). @xref{Using --digital signatures}, for more information. -+GPG-style digital signatures}, for more information. - @end deffn - -+ -+@node distrust_certificate -+@subsection distrust_certificate -+ -+@deffn Command distrust_certificate cert_number -+Remove the x509 certificate numbered @var{cert_number} from GRUB's keyring of -+trusted x509 certificates for verifying appended signatures. -+ -+@var{cert_number} is the certificate number as listed by -+@command{list_certificates} (@pxref{list_certificates}). -+ -+These certificates are used to validate appended signatures when environment -+variable @code{check_appended_signatures} is set to @code{enforce} or -+@code{forced} (@pxref{check_appended_signatures}), and by -+@command{verify_appended} (@pxref{verify_appended}). See -+@xref{Using appended signatures} for more information. -+@end deffn -+ -+ - @node drivemap - @subsection drivemap - -@@ -4636,6 +4667,21 @@ This command is only available on x86 systems. - @end deffn - - -+@node list_certificates -+@subsection list_certificates -+ -+@deffn Command list_certificates -+List all x509 certificates trusted by GRUB for validating appended signatures. -+The output is a numbered list of certificates, showing the certificate's serial -+number and Common Name. -+ -+The certificate number can be used as an argument to -+@command{distrust_certificate} (@pxref{distrust_certificate}). -+ -+See @xref{Using appended signatures} for more information. -+@end deffn -+ -+ - @node list_env - @subsection list_env - -@@ -4655,7 +4701,7 @@ The output is in GPG's v4 key fingerprint format (i.e., the output of - @code{gpg --fingerprint}). The least significant four bytes (last - eight hexadecimal digits) can be used as an argument to - @command{distrust} (@pxref{distrust}). --@xref{Using digital signatures}, for more information about uses for -+@xref{Using GPG-style digital signatures}, for more information about uses for - these keys. - @end deffn - -@@ -4690,8 +4736,13 @@ When used with care, @option{--skip-sig} and the whitelist enable an - administrator to configure a system to boot only signed - configurations, but to allow the user to select from among multiple - configurations, and to enable ``one-shot'' boot attempts and --``savedefault'' behavior. @xref{Using digital signatures}, for more -+``savedefault'' behavior. @xref{Using GPG-style digital signatures}, for more - information. -+ -+Extra care should be taken when combining this command with appended signatures -+(@pxref{Using appended signatures}), as this file is not validated by an -+appended signature and could set @code{check_appended_signatures=no} if GRUB is -+not in @pxref{Lockdown} mode. - @end deffn - - -@@ -4987,7 +5038,7 @@ read. It is possible to modify a digitally signed environment block - file from within GRUB using this command, such that its signature will - no longer be valid on subsequent boots. Care should be taken in such - advanced configurations to avoid rendering the system --unbootable. @xref{Using digital signatures}, for more information. -+unbootable. @xref{Using GPG-style digital signatures}, for more information. - @end deffn - - -@@ -5387,11 +5438,32 @@ signatures when environment variable @code{check_signatures} is set to - must itself be properly signed. The @option{--skip-sig} option can be - used to disable signature-checking when reading @var{pubkey_file} - itself. It is expected that @option{--skip-sig} is useful for testing --and manual booting. @xref{Using digital signatures}, for more -+and manual booting. @xref{Using GPG-style digital signatures}, for more - information. - @end deffn - - -+@node trust_certificate -+@subsection trust_certificate -+ -+@deffn Command trust_certificate x509_certificate -+Read an DER-formatted x509 certificate from the file @var{x509_certificate} -+and add it to GRUB's internal list of trusted x509 certificates. These -+certificates are used to validate appended signatures when the environment -+variable @code{check_appended_signatures} is set to @code{enforce} or -+@code{forced}. -+ -+Note that if @code{check_appended_signatures} is set to @code{enforce} or -+@code{forced} when @command{trust_certificate} is executed, then -+@var{x509_certificate} must itself bear an appended signature. (It is not -+sufficient that @var{x509_certificate} be signed by a trusted certificate -+according to the x509 rules: grub does not include support for validating -+signatures within x509 certificates themselves.) -+ -+See @xref{Using appended signatures} for more information. -+@end deffn -+ -+ - @node unset - @subsection unset - -@@ -5410,6 +5482,18 @@ only on PC BIOS platforms. - @end deffn - @end ignore - -+@node verify_appended -+@subsection verify_appended -+ -+@deffn Command verify_appended file -+Verifies an appended signature on @var{file} against the trusted certificates -+known to GRUB (See @pxref{list_certificates}, @pxref{trust_certificate}, and -+@pxref{distrust_certificate}). -+ -+Exit code @code{$?} is set to 0 if the signature validates -+successfully. If validation fails, it is set to a non-zero value. -+See @xref{Using appended signatures}, for more information. -+@end deffn - - @node verify_detached - @subsection verify_detached -@@ -5428,7 +5512,7 @@ tried. - - Exit code @code{$?} is set to 0 if the signature validates - successfully. If validation fails, it is set to a non-zero value. --@xref{Using digital signatures}, for more information. -+@xref{Using GPG-style digital signatures}, for more information. - @end deffn - - @node videoinfo -@@ -5811,13 +5895,14 @@ environment variables and commands are listed in the same order. - @chapter Security - - @menu --* Authentication and authorisation:: Users and access control --* Using digital signatures:: Booting digitally signed code --* UEFI secure boot and shim:: Booting digitally signed PE files --* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation --* Measured Boot:: Measuring boot components --* Lockdown:: Lockdown when booting on a secure setup --* Signing GRUB itself:: Ensuring the integrity of the GRUB core image -+* Authentication and authorisation:: Users and access control -+* Using GPG-style digital signatures:: Booting digitally signed code -+* Using appended signatures:: An alternative approach to booting digitally signed code -+* UEFI secure boot and shim:: Booting digitally signed PE files -+* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation -+* Measured Boot:: Measuring boot components -+* Lockdown:: Lockdown when booting on a secure setup -+* Signing GRUB itself:: Ensuring the integrity of the GRUB core image - @end menu - - @node Authentication and authorisation -@@ -5891,8 +5976,8 @@ generating configuration files with authentication. You can use - adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} - commands. - --@node Using digital signatures --@section Using digital signatures in GRUB -+@node Using GPG-style digital signatures -+@section Using GPG-style digital signatures in GRUB - - GRUB's @file{core.img} can optionally provide enforcement that all files - subsequently read from disk are covered by a valid digital signature. -@@ -5985,6 +6070,86 @@ or BIOS) configuration to cause the machine to boot from a different - (attacker-controlled) device. GRUB is at best only one link in a - secure boot chain. - -+@node Using appended signatures -+@section Using appended signatures in GRUB -+ -+GRUB supports verifying Linux-style 'appended signatures' for secure boot. -+Appended signatures are PKCS#7 messages containing a signature over the -+contents of a file, plus some metadata, appended to the end of a file. A file -+with an appended signature ends with the magic string: -+ -+@example -+~Module signature appended~\n -+@end example -+ -+where @code{\n} represents the line-feed character, @code{0x0a}. -+ -+Certificates can be managed at boot time using the @pxref{trust_certificate}, -+@pxref{distrust_certificate} and @pxref{list_certificates} commands. -+Certificates can also be built in to the core image using the @code{--x509} -+parameter to @command{grub-install} or @command{grub-mkimage}. -+ -+A file can be explictly verified using the @pxref{verify_appended} command. -+ -+Only signatures made with the SHA-256 or SHA-512 hash algorithm are supported, -+and only RSA signatures are supported. -+ -+A file can be signed with the @command{sign-file} utility supplied with the -+Linux kernel source. For example, if you have @code{signing.key} as the private -+key and @code{certificate.der} as the x509 certificate containing the public key: -+ -+@example -+sign-file SHA256 signing.key certificate.der vmlinux vmlinux.signed -+@end example -+ -+Enforcement of signature verification is controlled by the -+@code{check_appended_signatures} variable. -+ -+@itemize -+@item @samp{no}: no verification is performed. This is the default when GRUB -+ is not in @pxref{Lockdown} mode. -+@item @samp{enforce}: verification is performed. Verification can be disabled -+ by setting the variable back to @samp{no}. -+@item @samp{forced}: verification is performed and cannot be disabled. This is -+ set when GRUB is in Lockdown when the appendedsig module is loaded. -+@end itemize -+ -+Unlike GPG-style signatures, not all files loaded by GRUB are required to be -+signed. Once verification is turned on, the following file types will have -+appended signatures verified: -+ -+@itemize -+@item Linux kernels -+@item GRUB modules, except those built into the core image -+@item Any new certificate files to be trusted -+@end itemize -+ -+ACPI tables and Device Tree images will not be checked for appended signatures -+but must be verified by another mechanism such as GPG-style signatures before -+they will be loaded. -+ -+Unless lockdown mode is enabled, signature checking does @strong{not} -+stop an attacker with console access from dropping manually to the GRUB -+console and executing: -+ -+@example -+set check_appended_signatures=no -+@end example -+ -+Refer to the section on password-protecting GRUB (@pxref{Authentication -+and authorisation}) for more information on preventing this. -+ -+Additionally, unless lockdown mode is enabled: -+ -+@itemize -+@item Special care must be taken around the @command{loadenv} command, which -+ can be used to turn off @code{check_appended_signature}. -+ -+@item If the grub configuration file is loaded from the disk, anyone who can -+ modify the file on disk can turn off @code{check_appended_signature}. -+ Consider embedding the configuration into the core grub image. -+@end itemize -+ - @node UEFI secure boot and shim - @section UEFI secure boot and shim support - diff --git a/0180-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch b/0180-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch deleted file mode 100644 index 40c3b3e..0000000 --- a/0180-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 28 Sep 2020 11:11:17 +1000 -Subject: [PATCH] ieee1275: enter lockdown based on /ibm,secure-boot - -If the 'ibm,secure-boot' property of the root node is 2 or greater, -enter lockdown. - -Signed-off-by: Daniel Axtens ---- - grub-core/Makefile.core.def | 1 + - grub-core/kern/ieee1275/init.c | 27 +++++++++++++++++++++++++++ - include/grub/lockdown.h | 3 ++- - docs/grub.texi | 4 ++-- - 4 files changed, 32 insertions(+), 3 deletions(-) - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 6bddc841b85..3f3459b2c70 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -323,6 +323,7 @@ kernel = { - powerpc_ieee1275 = kern/powerpc/cache.S; - powerpc_ieee1275 = kern/powerpc/dl.c; - powerpc_ieee1275 = kern/powerpc/compiler-rt.S; -+ powerpc_ieee1275 = kern/lockdown.c; - - sparc64_ieee1275 = kern/sparc64/cache.S; - sparc64_ieee1275 = kern/sparc64/dl.c; -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index 937c1bc44cb..fc7d9712729 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -44,6 +44,7 @@ - #ifdef __sparc__ - #include - #endif -+#include - - /* The minimal heap size we can live with. */ - #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) -@@ -271,6 +272,30 @@ grub_parse_cmdline (void) - } - } - -+static void -+grub_get_ieee1275_secure_boot (void) -+{ -+ grub_ieee1275_phandle_t root; -+ int rc; -+ grub_uint32_t is_sb; -+ -+ grub_ieee1275_finddevice ("/", &root); -+ -+ rc = grub_ieee1275_get_integer_property (root, "ibm,secure-boot", &is_sb, -+ sizeof (is_sb), 0); -+ -+ /* ibm,secure-boot: -+ * 0 - disabled -+ * 1 - audit -+ * 2 - enforce -+ * 3 - enforce + OS-specific behaviour -+ * -+ * We only support enforce. -+ */ -+ if (rc >= 0 && is_sb >= 2) -+ grub_lockdown (); -+} -+ - grub_addr_t grub_modbase; - - void -@@ -296,6 +321,8 @@ grub_machine_init (void) - #else - grub_install_get_time_ms (grub_rtc_get_time_ms); - #endif -+ -+ grub_get_ieee1275_secure_boot (); - } - - void -diff --git a/include/grub/lockdown.h b/include/grub/lockdown.h -index 40531fa823b..ebfee4bf06e 100644 ---- a/include/grub/lockdown.h -+++ b/include/grub/lockdown.h -@@ -24,7 +24,8 @@ - #define GRUB_LOCKDOWN_DISABLED 0 - #define GRUB_LOCKDOWN_ENABLED 1 - --#ifdef GRUB_MACHINE_EFI -+#if defined(GRUB_MACHINE_EFI) || \ -+ (defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275)) - extern void - EXPORT_FUNC (grub_lockdown) (void); - extern int -diff --git a/docs/grub.texi b/docs/grub.texi -index 4816be85611..a4da9c2a1b9 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -6227,8 +6227,8 @@ Measured boot is currently only supported on EFI platforms. - @section Lockdown when booting on a secure setup - - The GRUB can be locked down when booted on a secure boot environment, for example --if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will --be restricted and some operations/commands cannot be executed. -+if UEFI or Power secure boot is enabled. On a locked down configuration, the -+GRUB will be restricted and some operations/commands cannot be executed. - - The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. - Otherwise it does not exit. diff --git a/0181-ieee1275-drop-HEAP_MAX_ADDR-HEAP_MIN_SIZE.patch b/0181-ieee1275-drop-HEAP_MAX_ADDR-HEAP_MIN_SIZE.patch deleted file mode 100644 index 52fa9d2..0000000 --- a/0181-ieee1275-drop-HEAP_MAX_ADDR-HEAP_MIN_SIZE.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 14 Apr 2021 20:10:23 +1000 -Subject: [PATCH] ieee1275: drop HEAP_MAX_ADDR, HEAP_MIN_SIZE - -HEAP_MAX_ADDR is confusing. Currently it is set to 32MB, except -on ieee1275 on x86, where it is 64MB. - -There is a comment which purports to explain it: - -/* If possible, we will avoid claiming heap above this address, because it - seems to cause relocation problems with OSes that link at 4 MiB */ - -This doesn't make a lot of sense when the constants are well above 4MB -already. It was not always this way. Prior to -commit 7b5d0fe4440c ("Increase heap limit") in 2010, HEAP_MAX_SIZE and -HEAP_MAX_ADDR were indeed 4MB. However, when the constants were increased -the comment was left unchanged. - -It's been over a decade. It doesn't seem like we have problems with -claims over 4MB on powerpc or x86 ieee1275. (sparc does things completely -differently and never used the constant.) - -Drop the constant and the check. - -The only use of HEAP_MIN_SIZE was to potentially override the -HEAP_MAX_ADDR check. It is now unused. Remove it. - -Signed-off-by: Daniel Axtens ---- - grub-core/kern/ieee1275/init.c | 17 ----------------- - 1 file changed, 17 deletions(-) - -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index fc7d9712729..0dcd114ce54 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -46,9 +46,6 @@ - #endif - #include - --/* The minimal heap size we can live with. */ --#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) -- - /* The maximum heap size we're going to claim */ - #ifdef __i386__ - #define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024) -@@ -56,14 +53,6 @@ - #define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024) - #endif - --/* If possible, we will avoid claiming heap above this address, because it -- seems to cause relocation problems with OSes that link at 4 MiB */ --#ifdef __i386__ --#define HEAP_MAX_ADDR (unsigned long) (64 * 1024 * 1024) --#else --#define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024) --#endif -- - extern char _end[]; - - #ifdef __sparc__ -@@ -185,12 +174,6 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - if (*total + len > HEAP_MAX_SIZE) - len = HEAP_MAX_SIZE - *total; - -- /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */ -- if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */ -- (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */ -- (*total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */ -- len = HEAP_MAX_ADDR - addr; -- - /* In theory, firmware should already prevent this from happening by not - listing our own image in /memory/available. The check below is intended - as a safeguard in case that doesn't happen. However, it doesn't protect diff --git a/0182-ieee1275-claim-more-memory.patch b/0182-ieee1275-claim-more-memory.patch deleted file mode 100644 index 001a9df..0000000 --- a/0182-ieee1275-claim-more-memory.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 15 Apr 2020 23:28:29 +1000 -Subject: [PATCH] ieee1275: claim more memory - -On powerpc-ieee1275, we are running out of memory trying to verify -anything. This is because: - - - we have to load an entire file into memory to verify it. This is - extremely difficult to change with appended signatures. - - We only have 32MB of heap. - - Distro kernels are now often around 30MB. - -So we want to claim more memory from OpenFirmware for our heap. - -There are some complications: - - - The grub mm code isn't the only thing that will make claims on - memory from OpenFirmware: - - * PFW/SLOF will have claimed some for their own use. - - * The ieee1275 loader will try to find other bits of memory that we - haven't claimed to place the kernel and initrd when we go to boot. - - * Once we load Linux, it will also try to claim memory. It claims - memory without any reference to /memory/available, it just starts - at min(top of RMO, 768MB) and works down. So we need to avoid this - area. See arch/powerpc/kernel/prom_init.c as of v5.11. - - - The smallest amount of memory a ppc64 KVM guest can have is 256MB. - It doesn't work with distro kernels but can work with custom kernels. - We should maintain support for that. (ppc32 can boot with even less, - and we shouldn't break that either.) - - - Even if a VM has more memory, the memory OpenFirmware makes available - as Real Memory Area can be restricted. A freshly created LPAR on a - PowerVM machine is likely to have only 256MB available to OpenFirmware - even if it has many gigabytes of memory allocated. - -EFI systems will attempt to allocate 1/4th of the available memory, -clamped to between 1M and 1600M. That seems like a good sort of -approach, we just need to figure out if 1/4 is the right fraction -for us. - -We don't know in advance how big the kernel and initrd are going to be, -which makes figuring out how much memory we can take a bit tricky. - -To figure out how much memory we should leave unused, I looked at: - - - an Ubuntu 20.04.1 ppc64le pseries KVM guest: - vmlinux: ~30MB - initrd: ~50MB - - - a RHEL8.2 ppc64le pseries KVM guest: - vmlinux: ~30MB - initrd: ~30MB - -Ubuntu VMs struggle to boot with just 256MB under SLOF. -RHEL likewise has a higher minimum supported memory figure. -So lets first consider a distro kernel and 512MB of addressible memory. -(This is the default case for anything booting under PFW.) Say we lose -131MB to PFW (based on some tests). This leaves us 381MB. 1/4 of 381MB -is ~95MB. That should be enough to verify a 30MB vmlinux and should -leave plenty of space to load Linux and the initrd. - -If we consider 256MB of RMA under PFW, we have just 125MB remaining. 1/4 -of that is a smidge under 32MB, which gives us very poor odds of verifying -a distro-sized kernel. However, if we need 80MB just to put the kernel -and initrd in memory, we can't claim any more than 45MB anyway. So 1/4 -will do. We'll come back to this later. - -grub is always built as a 32-bit binary, even if it's loading a ppc64 -kernel. So we can't address memory beyond 4GB. This gives a natural cap -of 1GB for powerpc-ieee1275. - -Also apply this 1/4 approach to i386-ieee1275, but keep the 32MB cap. - -make check still works for both i386 and powerpc and I've booted -powerpc grub with this change under SLOF and PFW. - -Signed-off-by: Daniel Axtens ---- - grub-core/kern/ieee1275/init.c | 81 +++++++++++++++++++++++++++++++++--------- - docs/grub-dev.texi | 6 ++-- - 2 files changed, 69 insertions(+), 18 deletions(-) - -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index 0dcd114ce54..c61d91a0285 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -46,11 +46,12 @@ - #endif - #include - --/* The maximum heap size we're going to claim */ -+/* The maximum heap size we're going to claim. Not used by sparc. -+ We allocate 1/4 of the available memory under 4G, up to this limit. */ - #ifdef __i386__ - #define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024) --#else --#define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024) -+#else // __powerpc__ -+#define HEAP_MAX_SIZE (unsigned long) (1 * 1024 * 1024 * 1024) - #endif - - extern char _end[]; -@@ -147,16 +148,45 @@ grub_claim_heap (void) - + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000); - } - #else --/* Helper for grub_claim_heap. */ -+/* Helper for grub_claim_heap on powerpc. */ -+static int -+heap_size (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, -+ void *data) -+{ -+ grub_uint32_t total = *(grub_uint32_t *)data; -+ -+ if (type != GRUB_MEMORY_AVAILABLE) -+ return 0; -+ -+ /* Do not consider memory beyond 4GB */ -+ if (addr > 0xffffffffUL) -+ return 0; -+ -+ if (addr + len > 0xffffffffUL) -+ len = 0xffffffffUL - addr; -+ -+ total += len; -+ *(grub_uint32_t *)data = total; -+ -+ return 0; -+} -+ - static int - heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - void *data) - { -- unsigned long *total = data; -+ grub_uint32_t total = *(grub_uint32_t *)data; - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - -+ /* Do not consider memory beyond 4GB */ -+ if (addr > 0xffffffffUL) -+ return 0; -+ -+ if (addr + len > 0xffffffffUL) -+ len = 0xffffffffUL - addr; -+ - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM)) - { - if (addr + len <= 0x180000) -@@ -170,10 +200,6 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - } - len -= 1; /* Required for some firmware. */ - -- /* Never exceed HEAP_MAX_SIZE */ -- if (*total + len > HEAP_MAX_SIZE) -- len = HEAP_MAX_SIZE - *total; -- - /* In theory, firmware should already prevent this from happening by not - listing our own image in /memory/available. The check below is intended - as a safeguard in case that doesn't happen. However, it doesn't protect -@@ -185,6 +211,18 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - len = 0; - } - -+ /* If this block contains 0x30000000 (768MB), do not claim below that. -+ Linux likes to claim memory at min(RMO top, 768MB) and works down -+ without reference to /memory/available. */ -+ if ((addr < 0x30000000) && ((addr + len) > 0x30000000)) -+ { -+ len = len - (0x30000000 - addr); -+ addr = 0x30000000; -+ } -+ -+ if (len > total) -+ len = total; -+ - if (len) - { - grub_err_t err; -@@ -193,10 +231,12 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - if (err) - return err; - grub_mm_init_region ((void *) (grub_addr_t) addr, len); -+ total -= len; - } - -- *total += len; -- if (*total >= HEAP_MAX_SIZE) -+ *(grub_uint32_t *)data = total; -+ -+ if (total == 0) - return 1; - - return 0; -@@ -205,13 +245,22 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - static void - grub_claim_heap (void) - { -- unsigned long total = 0; -+ grub_uint32_t total = 0; - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) -- heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN, -- 1, &total); -- else -- grub_machine_mmap_iterate (heap_init, &total); -+ { -+ heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN, -+ 1, &total); -+ return; -+ } -+ -+ grub_machine_mmap_iterate (heap_size, &total); -+ -+ total = total / 4; -+ if (total > HEAP_MAX_SIZE) -+ total = HEAP_MAX_SIZE; -+ -+ grub_machine_mmap_iterate (heap_init, &total); - } - #endif - -diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 19f708ee662..90083772c8a 100644 ---- a/docs/grub-dev.texi -+++ b/docs/grub-dev.texi -@@ -1047,7 +1047,9 @@ space is limited to 4GiB. GRUB allocates pages from EFI for its heap, at most - 1.6 GiB. - - On i386-ieee1275 and powerpc-ieee1275 GRUB uses same stack as IEEE1275. --It allocates at most 32MiB for its heap. -+ -+On i386-ieee1275, GRUB allocates at most 32MiB for its heap. On -+powerpc-ieee1275, GRUB allocates up to 1GiB. - - On sparc64-ieee1275 stack is 256KiB and heap is 2MiB. - -@@ -1075,7 +1077,7 @@ In short: - @item i386-qemu @tab 60 KiB @tab < 4 GiB - @item *-efi @tab ? @tab < 1.6 GiB - @item i386-ieee1275 @tab ? @tab < 32 MiB --@item powerpc-ieee1275 @tab ? @tab < 32 MiB -+@item powerpc-ieee1275 @tab ? @tab < 1 GiB - @item sparc64-ieee1275 @tab 256KiB @tab 2 MiB - @item arm-uboot @tab 256KiB @tab 2 MiB - @item mips(el)-qemu_mips @tab 2MiB @tab 253 MiB diff --git a/0183-ieee1275-request-memory-with-ibm-client-architecture.patch b/0183-ieee1275-request-memory-with-ibm-client-architecture.patch deleted file mode 100644 index 6e6c1f0..0000000 --- a/0183-ieee1275-request-memory-with-ibm-client-architecture.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 16 Apr 2021 11:48:46 +1000 -Subject: [PATCH] ieee1275: request memory with ibm,client-architecture-support - -On PowerVM, the first time we boot a Linux partition, we may only get -256MB of real memory area, even if the partition has more memory. - -This isn't really enough. Fortunately, the Power Architecture Platform -Reference (PAPR) defines a method we can call to ask for more memory. -This is part of the broad and powerful ibm,client-architecture-support -(CAS) method. - -CAS can do an enormous amount of things on a PAPR platform: as well as -asking for memory, you can set the supported processor level, the interrupt -controller, hash vs radix mmu, and so on. We want to touch as little of -this as possible because we don't want to step on the toes of the future OS. - -If: - - - we are running under what we think is PowerVM (compatible property of / - begins with "IBM"), and - - - the full amount of RMA is less than 512MB (as determined by the reg - property of /memory) - -then call CAS as follows: (refer to the Linux on Power Architecture -Reference, LoPAR, which is public, at B.5.2.3): - - - Use the "any" PVR value and supply 2 option vectors. - - - Set option vector 1 (PowerPC Server Processor Architecture Level) - to "ignore". - - - Set option vector 2 with default or Linux-like options, including a - min-rma-size of 512MB. - -This will cause a CAS reboot and the partition will restart with 512MB -of RMA. Grub will notice the 512MB and not call CAS again. - -(A partition can be configured with only 256MB of memory, which would -mean this request couldn't be satisfied, but PFW refuses to load with -only 256MB of memory, so it's a bit moot. SLOF will run fine with 256MB, -but we will never call CAS under qemu/SLOF because /compatible won't -begin with "IBM".) - -One of the first things Linux does while still running under OpenFirmware -is to call CAS with a much fuller set of options (including asking for -512MB of memory). This includes a much more restrictive set of PVR values -and processor support levels, and this will induce another reboot. On this -reboot grub will again notice the higher RMA, and not call CAS. We will get -to Linux, Linux will call CAS but because the values are now set for Linux -this will not induce another CAS reboot and we will finally boot. - -On all subsequent boots, everything will be configured with 512MB of RMA -and all the settings Linux likes, so there will be no further CAS reboots. - -(phyp is super sticky with the RMA size - it persists even on cold boots. -So if you've ever booted Linux in a partition, you'll probably never have -grub call CAS. It'll only ever fire the first time a partition loads grub, -or if you deliberately lower the amount of memory your partition has below -512MB.) - -Signed-off-by: Daniel Axtens ---- - grub-core/kern/ieee1275/cmain.c | 3 + - grub-core/kern/ieee1275/init.c | 144 ++++++++++++++++++++++++++++++++++++++- - include/grub/ieee1275/ieee1275.h | 8 ++- - 3 files changed, 152 insertions(+), 3 deletions(-) - -diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c -index 04df9d2c667..6435628ec57 100644 ---- a/grub-core/kern/ieee1275/cmain.c -+++ b/grub-core/kern/ieee1275/cmain.c -@@ -127,6 +127,9 @@ grub_ieee1275_find_options (void) - break; - } - } -+ -+ if (grub_strncmp (tmp, "IBM,", 4) == 0) -+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY); - } - - if (is_smartfirmware) -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index c61d91a0285..9704715c837 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -242,6 +242,135 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - return 0; - } - -+/* How much memory does OF believe it has? (regardless of whether -+ it's accessible or not) */ -+static grub_err_t -+grub_ieee1275_total_mem (grub_uint64_t *total) -+{ -+ grub_ieee1275_phandle_t root; -+ grub_ieee1275_phandle_t memory; -+ grub_uint32_t reg[4]; -+ grub_ssize_t reg_size; -+ grub_uint32_t address_cells = 1; -+ grub_uint32_t size_cells = 1; -+ grub_uint64_t size; -+ -+ /* If we fail to get to the end, report 0. */ -+ *total = 0; -+ -+ /* Determine the format of each entry in `reg'. */ -+ grub_ieee1275_finddevice ("/", &root); -+ grub_ieee1275_get_integer_property (root, "#address-cells", &address_cells, -+ sizeof address_cells, 0); -+ grub_ieee1275_get_integer_property (root, "#size-cells", &size_cells, -+ sizeof size_cells, 0); -+ -+ if (size_cells > address_cells) -+ address_cells = size_cells; -+ -+ /* Load `/memory/reg'. */ -+ if (grub_ieee1275_finddevice ("/memory", &memory)) -+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, -+ "couldn't find /memory node"); -+ if (grub_ieee1275_get_integer_property (memory, "reg", reg, -+ sizeof reg, ®_size)) -+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, -+ "couldn't examine /memory/reg property"); -+ if (reg_size < 0 || (grub_size_t) reg_size > sizeof (reg)) -+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, -+ "/memory response buffer exceeded"); -+ -+ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS)) -+ { -+ address_cells = 1; -+ size_cells = 1; -+ } -+ -+ /* Decode only the size */ -+ size = reg[address_cells]; -+ if (size_cells == 2) -+ size = (size << 32) | reg[address_cells + 1]; -+ -+ *total = size; -+ -+ return grub_errno; -+} -+ -+/* Based on linux - arch/powerpc/kernel/prom_init.c */ -+struct option_vector2 { -+ grub_uint8_t byte1; -+ grub_uint16_t reserved; -+ grub_uint32_t real_base; -+ grub_uint32_t real_size; -+ grub_uint32_t virt_base; -+ grub_uint32_t virt_size; -+ grub_uint32_t load_base; -+ grub_uint32_t min_rma; -+ grub_uint32_t min_load; -+ grub_uint8_t min_rma_percent; -+ grub_uint8_t max_pft_size; -+} __attribute__((packed)); -+ -+struct pvr_entry { -+ grub_uint32_t mask; -+ grub_uint32_t entry; -+}; -+ -+struct cas_vector { -+ struct { -+ struct pvr_entry terminal; -+ } pvr_list; -+ grub_uint8_t num_vecs; -+ grub_uint8_t vec1_size; -+ grub_uint8_t vec1; -+ grub_uint8_t vec2_size; -+ struct option_vector2 vec2; -+} __attribute__((packed)); -+ -+/* Call ibm,client-architecture-support to try to get more RMA. -+ We ask for 512MB which should be enough to verify a distro kernel. -+ We ignore most errors: if we don't succeed we'll proceed with whatever -+ memory we have. */ -+static void -+grub_ieee1275_ibm_cas (void) -+{ -+ int rc; -+ grub_ieee1275_ihandle_t root; -+ struct cas_args { -+ struct grub_ieee1275_common_hdr common; -+ grub_ieee1275_cell_t method; -+ grub_ieee1275_ihandle_t ihandle; -+ grub_ieee1275_cell_t cas_addr; -+ grub_ieee1275_cell_t result; -+ } args; -+ struct cas_vector vector = { -+ .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */ -+ .num_vecs = 2 - 1, -+ .vec1_size = 0, -+ .vec1 = 0x80, /* ignore */ -+ .vec2_size = 1 + sizeof(struct option_vector2) - 2, -+ .vec2 = { -+ 0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48 -+ }, -+ }; -+ -+ INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); -+ args.method = (grub_ieee1275_cell_t)"ibm,client-architecture-support"; -+ rc = grub_ieee1275_open("/", &root); -+ if (rc) { -+ grub_error (GRUB_ERR_IO, "could not open root when trying to call CAS"); -+ return; -+ } -+ args.ihandle = root; -+ args.cas_addr = (grub_ieee1275_cell_t)&vector; -+ -+ grub_printf("Calling ibm,client-architecture-support..."); -+ IEEE1275_CALL_ENTRY_FN (&args); -+ grub_printf("done\n"); -+ -+ grub_ieee1275_close(root); -+} -+ - static void - grub_claim_heap (void) - { -@@ -249,11 +378,22 @@ grub_claim_heap (void) - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) - { -- heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN, -- 1, &total); -+ heap_init (GRUB_IEEE1275_STATIC_HEAP_START, -+ GRUB_IEEE1275_STATIC_HEAP_LEN, 1, &total); - return; - } - -+ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY)) -+ { -+ grub_uint64_t rma_size; -+ grub_err_t err; -+ -+ err = grub_ieee1275_total_mem (&rma_size); -+ /* if we have an error, don't call CAS, just hope for the best */ -+ if (!err && rma_size < (512 * 1024 * 1024)) -+ grub_ieee1275_ibm_cas(); -+ } -+ - grub_machine_mmap_iterate (heap_size, &total); - - total = total / 4; -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index b5a1d49bbc3..e0a6c2ce1e6 100644 ---- a/include/grub/ieee1275/ieee1275.h -+++ b/include/grub/ieee1275/ieee1275.h -@@ -149,7 +149,13 @@ enum grub_ieee1275_flag - - GRUB_IEEE1275_FLAG_RAW_DEVNAMES, - -- GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT -+ GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT, -+ -+ /* On PFW, the first time we boot a Linux partition, we may only get 256MB -+ of real memory area, even if the partition has more memory. Set this flag -+ if we think we're running under PFW. Then, if this flag is set, and the -+ RMA is only 256MB in size, try asking for more with CAS. */ -+ GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY, - }; - - extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff --git a/0184-appendedsig-x509-Also-handle-the-Extended-Key-Usage-.patch b/0184-appendedsig-x509-Also-handle-the-Extended-Key-Usage-.patch deleted file mode 100644 index a237a21..0000000 --- a/0184-appendedsig-x509-Also-handle-the-Extended-Key-Usage-.patch +++ /dev/null @@ -1,315 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Sat, 8 May 2021 02:27:58 +0200 -Subject: [PATCH] appendedsig/x509: Also handle the Extended Key Usage - extension - -Red Hat certificates have both Key Usage and Extended Key Usage extensions -present, but the appended signatures x509 parser doesn't handle the latter -and so buils due finding an unrecognised critical extension: - -Error loading initial key: -../../grub-core/commands/appendedsig/x509.c:780:Unhandled critical x509 extension with OID 2.5.29.37 - -Fix this by also parsing the Extended Key Usage extension and handle it by -verifying that the certificate has a single purpose, that is code signing. - -Signed-off-by: Javier Martinez Canillas -Signed-off-by: Daniel Axtens ---- - grub-core/commands/appendedsig/x509.c | 94 ++++++++++++++++++++++++++++++- - grub-core/tests/appended_signature_test.c | 29 +++++++++- - grub-core/tests/appended_signatures.h | 81 ++++++++++++++++++++++++++ - 3 files changed, 201 insertions(+), 3 deletions(-) - -diff --git a/grub-core/commands/appendedsig/x509.c b/grub-core/commands/appendedsig/x509.c -index 2b38b3670a2..42ec65c54aa 100644 ---- a/grub-core/commands/appendedsig/x509.c -+++ b/grub-core/commands/appendedsig/x509.c -@@ -47,6 +47,12 @@ const char *keyUsage_oid = "2.5.29.15"; - */ - const char *basicConstraints_oid = "2.5.29.19"; - -+/* -+ * RFC 5280 4.2.1.12 Extended Key Usage -+ */ -+const char *extendedKeyUsage_oid = "2.5.29.37"; -+const char *codeSigningUsage_oid = "1.3.6.1.5.5.7.3.3"; -+ - /* - * RFC 3279 2.3.1 - * -@@ -637,6 +643,77 @@ cleanup: - return err; - } - -+/* -+ * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId -+ * -+ * KeyPurposeId ::= OBJECT IDENTIFIER -+ */ -+static grub_err_t -+verify_extended_key_usage (grub_uint8_t * value, int value_size) -+{ -+ asn1_node extendedasn; -+ int result, count; -+ grub_err_t err = GRUB_ERR_NONE; -+ char usage[MAX_OID_LEN]; -+ int usage_size = sizeof (usage); -+ -+ result = -+ asn1_create_element (_gnutls_pkix_asn, "PKIX1.ExtKeyUsageSyntax", -+ &extendedasn); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not create ASN.1 structure for Extended Key Usage"); -+ } -+ -+ result = asn1_der_decoding2 (&extendedasn, value, &value_size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error parsing DER for Extended Key Usage: %s", -+ asn1_error); -+ goto cleanup; -+ } -+ -+ /* -+ * If EKUs are present, there must be exactly 1 and it must be a -+ * codeSigning usage. -+ */ -+ result = asn1_number_of_elements(extendedasn, "", &count); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error counting number of Extended Key Usages: %s", -+ asn1_strerror (result)); -+ goto cleanup; -+ } -+ -+ result = asn1_read_value (extendedasn, "?1", usage, &usage_size); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading Extended Key Usage: %s", -+ asn1_strerror (result)); -+ goto cleanup; -+ } -+ -+ if (grub_strncmp (codeSigningUsage_oid, usage, usage_size) != 0) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Unexpected Extended Key Usage OID, got: %s", -+ usage); -+ goto cleanup; -+ } -+ -+cleanup: -+ asn1_delete_structure (&extendedasn); -+ return err; -+} - - /* - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension -@@ -660,7 +737,7 @@ verify_extensions (asn1_node cert) - { - int result; - int ext, num_extensions = 0; -- int usage_present = 0, constraints_present = 0; -+ int usage_present = 0, constraints_present = 0, extended_usage_present = 0; - char *oid_path, *critical_path, *value_path; - char extnID[MAX_OID_LEN]; - int extnID_size; -@@ -754,6 +831,15 @@ verify_extensions (asn1_node cert) - } - constraints_present++; - } -+ else if (grub_strncmp (extendedKeyUsage_oid, extnID, extnID_size) == 0) -+ { -+ err = verify_extended_key_usage (value, value_size); -+ if (err != GRUB_ERR_NONE) -+ { -+ goto cleanup_value; -+ } -+ extended_usage_present++; -+ } - else if (grub_strncmp ("TRUE", critical, critical_size) == 0) - { - /* -@@ -785,6 +871,12 @@ verify_extensions (asn1_node cert) - "Unexpected number of basic constraints extensions - expected 1, got %d", - constraints_present); - } -+ if (extended_usage_present > 1) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Unexpected number of Extended Key Usage extensions - expected 0 or 1, got %d", -+ extended_usage_present); -+ } - return GRUB_ERR_NONE; - - cleanup_value: -diff --git a/grub-core/tests/appended_signature_test.c b/grub-core/tests/appended_signature_test.c -index 88a485200d8..dbba0616621 100644 ---- a/grub-core/tests/appended_signature_test.c -+++ b/grub-core/tests/appended_signature_test.c -@@ -111,6 +111,22 @@ static struct grub_procfs_entry certificate_printable_der_entry = { - .get_contents = get_certificate_printable_der - }; - -+static char * -+get_certificate_eku_der (grub_size_t * sz) -+{ -+ char *ret; -+ *sz = certificate_eku_der_len; -+ ret = grub_malloc (*sz); -+ if (ret) -+ grub_memcpy (ret, certificate_eku_der, *sz); -+ return ret; -+} -+ -+static struct grub_procfs_entry certificate_eku_der_entry = { -+ .name = "certificate_eku.der", -+ .get_contents = get_certificate_eku_der -+}; -+ - - static void - do_verify (const char *f, int is_valid) -@@ -149,6 +165,7 @@ appended_signature_test (void) - char *trust_args2[] = { (char *) "(proc)/certificate2.der", NULL }; - char *trust_args_printable[] = { (char *) "(proc)/certificate_printable.der", - NULL }; -+ char *trust_args_eku[] = { (char *) "(proc)/certificate_eku.der", NULL }; - char *distrust_args[] = { (char *) "1", NULL }; - char *distrust2_args[] = { (char *) "2", NULL }; - grub_err_t err; -@@ -157,6 +174,7 @@ appended_signature_test (void) - grub_procfs_register ("certificate2.der", &certificate2_der_entry); - grub_procfs_register ("certificate_printable.der", - &certificate_printable_der_entry); -+ grub_procfs_register ("certificate_eku.der", &certificate_eku_der_entry); - - cmd_trust = grub_command_find ("trust_certificate"); - if (!cmd_trust) -@@ -266,16 +284,23 @@ appended_signature_test (void) - - /* - * Lastly, check a certificate that uses printableString rather than -- * utf8String loads properly. -+ * utf8String loads properly, and that a certificate with an appropriate -+ * extended key usage loads. - */ - err = (cmd_trust->func) (cmd_trust, 1, trust_args_printable); - grub_test_assert (err == GRUB_ERR_NONE, -- "distrusting printable certificate failed: %d: %s", -+ "trusting printable certificate failed: %d: %s", -+ grub_errno, grub_errmsg); -+ -+ err = (cmd_trust->func) (cmd_trust, 1, trust_args_eku); -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "trusting certificate with extended key usage failed: %d: %s", - grub_errno, grub_errmsg); - - grub_procfs_unregister (&certificate_der_entry); - grub_procfs_unregister (&certificate2_der_entry); - grub_procfs_unregister (&certificate_printable_der_entry); -+ grub_procfs_unregister (&certificate_eku_der_entry); - } - - GRUB_FUNCTIONAL_TEST (appended_signature_test, appended_signature_test); -diff --git a/grub-core/tests/appended_signatures.h b/grub-core/tests/appended_signatures.h -index aa3dc6278e3..2e5ebd7d8bd 100644 ---- a/grub-core/tests/appended_signatures.h -+++ b/grub-core/tests/appended_signatures.h -@@ -555,3 +555,84 @@ unsigned char certificate_printable_der[] = { - 0xd2 - }; - unsigned int certificate_printable_der_len = 829; -+ -+unsigned char certificate_eku_der[] = { -+ 0x30, 0x82, 0x03, 0x90, 0x30, 0x82, 0x02, 0x78, 0xa0, 0x03, 0x02, 0x01, -+ 0x02, 0x02, 0x09, 0x00, 0xd3, 0x9c, 0x41, 0x33, 0xdd, 0x6b, 0x5f, 0x45, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x0b, 0x05, 0x00, 0x30, 0x47, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, -+ 0x04, 0x03, 0x0c, 0x18, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, -+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, -+ 0x43, 0x41, 0x20, 0x36, 0x31, 0x22, 0x30, 0x20, 0x06, 0x09, 0x2a, 0x86, -+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x73, 0x65, 0x63, -+ 0x61, 0x6c, 0x65, 0x72, 0x74, 0x40, 0x72, 0x65, 0x64, 0x68, 0x61, 0x74, -+ 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, -+ 0x31, 0x35, 0x31, 0x34, 0x30, 0x30, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x33, -+ 0x38, 0x30, 0x31, 0x31, 0x37, 0x31, 0x34, 0x30, 0x30, 0x34, 0x34, 0x5a, -+ 0x30, 0x4e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, -+ 0x1f, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, 0x53, 0x65, 0x63, -+ 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, 0x53, 0x69, 0x67, -+ 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x36, 0x30, 0x32, 0x31, 0x22, 0x30, 0x20, -+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, -+ 0x13, 0x73, 0x65, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x40, 0x72, 0x65, -+ 0x64, 0x68, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, -+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xaa, 0x6f, 0xbb, 0x92, 0x77, 0xd7, 0x15, -+ 0xef, 0x88, 0x80, 0x88, 0xc0, 0xe7, 0x89, 0xeb, 0x35, 0x76, 0xf4, 0x85, -+ 0x05, 0x0f, 0x19, 0xe4, 0x5f, 0x25, 0xdd, 0xc1, 0xa2, 0xe5, 0x5c, 0x06, -+ 0xfb, 0xf1, 0x06, 0xb5, 0x65, 0x45, 0xcb, 0xbd, 0x19, 0x33, 0x54, 0xb5, -+ 0x1a, 0xcd, 0xe4, 0xa8, 0x35, 0x2a, 0xfe, 0x9c, 0x53, 0xf4, 0xc6, 0x76, -+ 0xdb, 0x1f, 0x8a, 0xd4, 0x7b, 0x18, 0x11, 0xaf, 0xa3, 0x90, 0xd4, 0xdd, -+ 0x4d, 0xd5, 0x42, 0xcc, 0x14, 0x9a, 0x64, 0x6b, 0xc0, 0x7f, 0xaa, 0x1c, -+ 0x94, 0x47, 0x4d, 0x79, 0xbd, 0x57, 0x9a, 0xbf, 0x99, 0x4e, 0x96, 0xa9, -+ 0x31, 0x2c, 0xa9, 0xe7, 0x14, 0x65, 0x86, 0xc8, 0xac, 0x79, 0x5e, 0x78, -+ 0xa4, 0x3c, 0x00, 0x24, 0xd3, 0xf7, 0xe1, 0xf5, 0x12, 0xad, 0xa0, 0x29, -+ 0xe5, 0xfe, 0x80, 0xae, 0xf8, 0xaa, 0x60, 0x36, 0xe7, 0xe8, 0x94, 0xcb, -+ 0xe9, 0xd1, 0xcc, 0x0b, 0x4d, 0xf7, 0xde, 0xeb, 0x52, 0xd2, 0x73, 0x09, -+ 0x28, 0xdf, 0x48, 0x99, 0x53, 0x9f, 0xc5, 0x9a, 0xd4, 0x36, 0xa3, 0xc6, -+ 0x5e, 0x8d, 0xbe, 0xd5, 0xdc, 0x76, 0xb4, 0x74, 0xb8, 0x26, 0x18, 0x27, -+ 0xfb, 0xf2, 0xfb, 0xd0, 0x9b, 0x3d, 0x7f, 0x10, 0xe2, 0xab, 0x44, 0xc7, -+ 0x88, 0x7f, 0xb4, 0x3d, 0x3e, 0xa3, 0xff, 0x6d, 0x06, 0x4b, 0x3e, 0x55, -+ 0xb2, 0x84, 0xf4, 0xad, 0x54, 0x88, 0x81, 0xc3, 0x9c, 0xf8, 0xb6, 0x68, -+ 0x96, 0x38, 0x8b, 0xcd, 0x90, 0x6d, 0x25, 0x4b, 0xbf, 0x0c, 0x44, 0x90, -+ 0xa5, 0x5b, 0x98, 0xd0, 0x40, 0x2f, 0xbb, 0x0d, 0xa8, 0x4b, 0x8a, 0x62, -+ 0x82, 0x46, 0x46, 0x18, 0x38, 0xae, 0x82, 0x07, 0xd0, 0xb4, 0x2f, 0x16, -+ 0x79, 0x55, 0x9f, 0x1b, 0xc5, 0x08, 0x6d, 0x85, 0xdf, 0x3f, 0xa9, 0x9b, -+ 0x4b, 0xc6, 0x28, 0xd3, 0x58, 0x72, 0x3d, 0x37, 0x11, 0x02, 0x03, 0x01, -+ 0x00, 0x01, 0xa3, 0x78, 0x30, 0x76, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, -+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, -+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, -+ 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, -+ 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, -+ 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6c, -+ 0xe4, 0x6c, 0x27, 0xaa, 0xcd, 0x0d, 0x4b, 0x74, 0x21, 0xa4, 0xf6, 0x5f, -+ 0x87, 0xb5, 0x31, 0xfe, 0x10, 0xbb, 0xa7, 0x30, 0x1f, 0x06, 0x03, 0x55, -+ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe8, 0x6a, 0x1c, 0xab, -+ 0x2c, 0x48, 0xf9, 0x60, 0x36, 0xa2, 0xf0, 0x7b, 0x8e, 0xd2, 0x9d, 0xb4, -+ 0x2a, 0x28, 0x98, 0xc8, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, -+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, -+ 0x55, 0x34, 0xe2, 0xfa, 0xf6, 0x89, 0x86, 0xad, 0x92, 0x21, 0xec, 0xb9, -+ 0x54, 0x0e, 0x18, 0x47, 0x0d, 0x1b, 0xa7, 0x58, 0xad, 0x69, 0xe4, 0xef, -+ 0x3b, 0xe6, 0x8d, 0xdd, 0xda, 0x0c, 0x45, 0xf6, 0xe8, 0x96, 0xa4, 0x29, -+ 0x0f, 0xbb, 0xcf, 0x16, 0xae, 0x93, 0xd0, 0xcb, 0x2a, 0x26, 0x1a, 0x7b, -+ 0xfc, 0x51, 0x22, 0x76, 0x98, 0x31, 0xa7, 0x0f, 0x29, 0x35, 0x79, 0xbf, -+ 0xe2, 0x4f, 0x0f, 0x14, 0xf5, 0x1f, 0xcb, 0xbf, 0x87, 0x65, 0x13, 0x32, -+ 0xa3, 0x19, 0x4a, 0xd1, 0x3f, 0x45, 0xd4, 0x4b, 0xe2, 0x00, 0x26, 0xa9, -+ 0x3e, 0xd7, 0xa5, 0x37, 0x9f, 0xf5, 0xad, 0x61, 0xe2, 0x40, 0xa9, 0x74, -+ 0x24, 0x53, 0xf2, 0x78, 0xeb, 0x10, 0x9b, 0x2c, 0x27, 0x88, 0x46, 0xcb, -+ 0xe4, 0x60, 0xca, 0xf5, 0x06, 0x24, 0x40, 0x2a, 0x97, 0x3a, 0xcc, 0xd0, -+ 0x81, 0xb1, 0x15, 0xa3, 0x4f, 0xd0, 0x2b, 0x4f, 0xca, 0x6e, 0xaa, 0x24, -+ 0x31, 0xb3, 0xac, 0xa6, 0x75, 0x05, 0xfe, 0x8a, 0xf4, 0x41, 0xc4, 0x06, -+ 0x8a, 0xc7, 0x0a, 0x83, 0x4e, 0x49, 0xd4, 0x3f, 0x83, 0x50, 0xec, 0x57, -+ 0x04, 0x97, 0x14, 0x49, 0xf5, 0xe1, 0xb1, 0x7a, 0x9c, 0x09, 0x4f, 0x61, -+ 0x87, 0xc3, 0x97, 0x22, 0x17, 0xc2, 0xeb, 0xcc, 0x32, 0x81, 0x31, 0x21, -+ 0x3f, 0x10, 0x57, 0x5b, 0x43, 0xbe, 0xcd, 0x68, 0x82, 0xbe, 0xe5, 0xc1, -+ 0x65, 0x94, 0x7e, 0xc2, 0x34, 0x76, 0x2b, 0xcf, 0x89, 0x3c, 0x2b, 0x81, -+ 0x23, 0x72, 0x95, 0xcf, 0xc9, 0x67, 0x19, 0x2a, 0xd5, 0x5c, 0xca, 0xa3, -+ 0x46, 0xbd, 0x48, 0x06, 0x0b, 0xa6, 0xa3, 0x96, 0x50, 0x28, 0xc7, 0x7e, -+ 0xcf, 0x62, 0xf2, 0xfa, 0xc4, 0xf2, 0x53, 0xe3, 0xc9, 0xe8, 0x2e, 0xdd, -+ 0x29, 0x37, 0x07, 0x47, 0xff, 0xff, 0x8a, 0x32, 0xbd, 0xa2, 0xb7, 0x21, -+ 0x89, 0xa0, 0x55, 0xf7 -+}; -+unsigned int certificate_eku_der_len = 916; diff --git a/0185-ieee1275-ofdisk-retry-on-open-failure.patch b/0185-ieee1275-ofdisk-retry-on-open-failure.patch deleted file mode 100644 index 275d14f..0000000 --- a/0185-ieee1275-ofdisk-retry-on-open-failure.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Diego Domingos -Date: Wed, 10 Mar 2021 14:17:52 -0500 -Subject: [PATCH] ieee1275/ofdisk: retry on open failure - -This patch aims to make grub more robust when booting from SAN/Multipath disks. - -If a path is failing intermittently so grub will retry the OPEN and READ the -disk (grub_ieee1275_open and grub_ieee1275_read) until the total amount of times -specified in MAX_RETRIES. - -Signed-off-by: Diego Domingos ---- - grub-core/disk/ieee1275/ofdisk.c | 25 ++++++++++++++++++++----- - include/grub/ieee1275/ofdisk.h | 8 ++++++++ - 2 files changed, 28 insertions(+), 5 deletions(-) - -diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c -index ea7f78ac7d8..55346849d35 100644 ---- a/grub-core/disk/ieee1275/ofdisk.c -+++ b/grub-core/disk/ieee1275/ofdisk.c -@@ -225,7 +225,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) - char *buf, *bufptr; - unsigned i; - -- if (grub_ieee1275_open (alias->path, &ihandle)) -+ -+ RETRY_IEEE1275_OFDISK_OPEN(alias->path, &ihandle) -+ if (! ihandle) - return; - - /* This method doesn't need memory allocation for the table. Open -@@ -305,7 +307,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) - return; - } - -- if (grub_ieee1275_open (alias->path, &ihandle)) -+ RETRY_IEEE1275_OFDISK_OPEN(alias->path, &ihandle); -+ -+ if (! ihandle) - { - grub_free (buf); - grub_free (table); -@@ -495,7 +499,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) - last_ihandle = 0; - last_devpath = NULL; - -- grub_ieee1275_open (op->open_path, &last_ihandle); -+ RETRY_IEEE1275_OFDISK_OPEN(op->open_path, &last_ihandle); - if (! last_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - last_devpath = op->open_path; -@@ -571,7 +575,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector) - last_ihandle = 0; - last_devpath = NULL; - -- grub_ieee1275_open (disk->data, &last_ihandle); -+ RETRY_IEEE1275_OFDISK_OPEN(disk->data, &last_ihandle); - if (! last_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - last_devpath = disk->data; -@@ -598,12 +602,23 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, - return err; - grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size, - &actual); -- if (actual != (grub_ssize_t) (size << disk->log_sector_size)) -+ int i = 0; -+ while(actual != (grub_ssize_t) (size << disk->log_sector_size)){ -+ if (i>MAX_RETRIES){ - return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " - "from `%s'"), - (unsigned long long) sector, - disk->name); -+ } -+ last_devpath = NULL; -+ err = grub_ofdisk_prepare (disk, sector); -+ if (err) -+ return err; - -+ grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size, -+ &actual); -+ i++; -+ } - return 0; - } - -diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h -index 2f69e3f191d..7d2d5409305 100644 ---- a/include/grub/ieee1275/ofdisk.h -+++ b/include/grub/ieee1275/ofdisk.h -@@ -22,4 +22,12 @@ - extern void grub_ofdisk_init (void); - extern void grub_ofdisk_fini (void); - -+#define MAX_RETRIES 20 -+ -+ -+#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) unsigned retry_i=0;for(retry_i=0; retry_i < MAX_RETRIES; retry_i++){ \ -+ if(!grub_ieee1275_open(device, last_ihandle)) \ -+ break; \ -+ grub_dprintf("ofdisk","Opening disk %s failed. Retrying...\n",device); } -+ - #endif /* ! GRUB_INIT_HEADER */ diff --git a/0186-Allow-chainloading-EFI-apps-from-loop-mounts.patch b/0186-Allow-chainloading-EFI-apps-from-loop-mounts.patch deleted file mode 100644 index 66e61a7..0000000 --- a/0186-Allow-chainloading-EFI-apps-from-loop-mounts.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitri John Ledkov -Date: Fri, 11 Jun 2021 13:51:20 +0200 -Subject: [PATCH] Allow chainloading EFI apps from loop mounts. - -Signed-off-by: Dimitri John Ledkov -Signed-off-by: Robbie Harwood ---- - grub-core/disk/loopback.c | 9 +-------- - grub-core/loader/efi/chainloader.c | 23 +++++++++++++++++++++++ - include/grub/loopback.h | 30 ++++++++++++++++++++++++++++++ - 3 files changed, 54 insertions(+), 8 deletions(-) - create mode 100644 include/grub/loopback.h - -diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c -index 41bebd14fe3..99f47924ec2 100644 ---- a/grub-core/disk/loopback.c -+++ b/grub-core/disk/loopback.c -@@ -21,20 +21,13 @@ - #include - #include - #include -+#include - #include - #include - #include - - GRUB_MOD_LICENSE ("GPLv3+"); - --struct grub_loopback --{ -- char *devname; -- grub_file_t file; -- struct grub_loopback *next; -- unsigned long id; --}; -- - static struct grub_loopback *loopback_list; - static unsigned long last_id = 0; - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index d41e8ea14a8..3af6b122926 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -901,6 +902,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_efi_status_t status; - grub_efi_boot_services_t *b; - grub_device_t dev = 0; -+ grub_device_t orig_dev = 0; - grub_efi_device_path_t *dp = 0; - char *filename; - void *boot_image = 0; -@@ -958,6 +960,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - if (! dev) - goto fail; - -+ /* if device is loopback, use underlying dev */ -+ if (dev->disk->dev->id == GRUB_DISK_DEVICE_LOOPBACK_ID) -+ { -+ struct grub_loopback *d; -+ orig_dev = dev; -+ d = dev->disk->data; -+ dev = d->file->device; -+ } -+ - if (dev->disk) - dev_handle = grub_efidisk_get_device_handle (dev->disk); - else if (dev->net && dev->net->server) -@@ -1065,6 +1076,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - } - #endif - -+ if (orig_dev) -+ { -+ dev = orig_dev; -+ orig_dev = 0; -+ } -+ - rc = grub_linuxefi_secure_validate((void *)(unsigned long)address, fsize); - grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc); - if (rc > 0) -@@ -1087,6 +1104,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - // -1 fall-through to fail - - fail: -+ if (orig_dev) -+ { -+ dev = orig_dev; -+ orig_dev = 0; -+ } -+ - if (dev) - grub_device_close (dev); - -diff --git a/include/grub/loopback.h b/include/grub/loopback.h -new file mode 100644 -index 00000000000..3b9a9e32e80 ---- /dev/null -+++ b/include/grub/loopback.h -@@ -0,0 +1,30 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2019 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOOPBACK_HEADER -+#define GRUB_LOOPBACK_HEADER 1 -+ -+struct grub_loopback -+{ -+ char *devname; -+ grub_file_t file; -+ struct grub_loopback *next; -+ unsigned long id; -+}; -+ -+#endif /* ! GRUB_LOOPBACK_HEADER */ diff --git a/0187-efinet-Add-DHCP-proxy-support.patch b/0187-efinet-Add-DHCP-proxy-support.patch deleted file mode 100644 index dcaac6f..0000000 --- a/0187-efinet-Add-DHCP-proxy-support.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ian Page Hands -Date: Tue, 8 Jun 2021 13:48:56 -0400 -Subject: [PATCH] efinet: Add DHCP proxy support - -If a proxyDHCP configuration is used, the server name, server IP and boot -file values should be taken from the DHCP proxy offer instead of the DHCP -server ack packet. Currently that case is not handled, add support for it. - -Signed-off-by: Ian Page Hands -Signed-off-by: Robbie Harwood ---- - grub-core/net/drivers/efi/efinet.c | 25 +++++++++++++++++++++++-- - 1 file changed, 23 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index e11d759f19a..1a24f38a21a 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -850,10 +850,31 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - else - { - grub_dprintf ("efinet", "using ipv4 and dhcp\n"); -+ -+ struct grub_net_bootp_packet *dhcp_ack = &pxe_mode->dhcp_ack; -+ -+ if (pxe_mode->proxy_offer_received) -+ { -+ grub_dprintf ("efinet", "proxy offer receive"); -+ struct grub_net_bootp_packet *proxy_offer = &pxe_mode->proxy_offer; -+ -+ if (proxy_offer && dhcp_ack->boot_file[0] == '\0') -+ { -+ grub_dprintf ("efinet", "setting values from proxy offer"); -+ /* Here we got a proxy offer and the dhcp_ack has a nil boot_file -+ * Copy the proxy DHCP offer details into the bootp_packet we are -+ * sending forward as they are the deatils we need. -+ */ -+ *dhcp_ack->server_name = *proxy_offer->server_name; -+ *dhcp_ack->boot_file = *proxy_offer->boot_file; -+ dhcp_ack->server_ip = proxy_offer->server_ip; -+ } -+ } -+ - grub_net_configure_by_dhcp_ack (card->name, card, 0, - (struct grub_net_bootp_packet *) -- packet_buf, -- packet_bufsz, -+ &pxe_mode->dhcp_ack, -+ sizeof (pxe_mode->dhcp_ack), - 1, device, path); - grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); - } diff --git a/0188-fs-ext2-Ignore-checksum-seed-incompat-feature.patch b/0188-fs-ext2-Ignore-checksum-seed-incompat-feature.patch deleted file mode 100644 index b4a5fd4..0000000 --- a/0188-fs-ext2-Ignore-checksum-seed-incompat-feature.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Jun 2021 00:01:29 +0200 -Subject: [PATCH] fs/ext2: Ignore checksum seed incompat feature - -This incompat feature is used to denote that the filesystem stored its -metadata checksum seed in the superblock. This is used to allow tune2fs -to change the UUID on a mounted metadata_csum filesystem without having -to rewrite all the disk metadata. - -But GRUB doesn't use the metadata checksum in anyway, so can just ignore -this feature if is enabled. This is consistent with GRUB filesystem code -in general which just does a best effort to access the filesystem's data. - -It may be removed from the ignored list in the future if supports to do -metadata checksumming verification is added to the read-only FS driver. - -Suggested-by: Eric Sandeen -Suggested-by: Lukas Czerner -Signed-off-by: Javier Martinez Canillas ---- - grub-core/fs/ext2.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c -index e7dd78e6635..731d346f886 100644 ---- a/grub-core/fs/ext2.c -+++ b/grub-core/fs/ext2.c -@@ -103,6 +103,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 - #define EXT4_FEATURE_INCOMPAT_MMP 0x0100 - #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 -+#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000 - #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 - - /* The set of back-incompatible features this driver DOES support. Add (OR) -@@ -123,9 +124,16 @@ GRUB_MOD_LICENSE ("GPLv3+"); - * mmp: Not really back-incompatible - was added as such to - * avoid multiple read-write mounts. Safe to ignore for this - * RO driver. -+ * checksum seed: Not really back-incompatible - was added to allow tools -+ * such as tune2fs to change the UUID on a mounted metadata -+ * checksummed filesystem. Safe to ignore for now since the -+ * driver doesn't support checksum verification. But it must -+ * be removed from this list if that support is added later. -+ * - */ - #define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \ -- | EXT4_FEATURE_INCOMPAT_MMP) -+ | EXT4_FEATURE_INCOMPAT_MMP \ -+ | EXT4_FEATURE_INCOMPAT_CSUM_SEED) - - - #define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U diff --git a/0189-Don-t-update-the-cmdline-when-generating-legacy-menu.patch b/0189-Don-t-update-the-cmdline-when-generating-legacy-menu.patch deleted file mode 100644 index 2e13f39..0000000 --- a/0189-Don-t-update-the-cmdline-when-generating-legacy-menu.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Thu, 17 Jun 2021 14:31:42 +0200 -Subject: [PATCH] Don't update the cmdline when generating legacy menuentry - commands - -On OPAL ppc64le machines with an old petitboot version that doesn't have -support to parse BLS snippets, the grub2-mkconfig script is executed to -generate menuentry commands from the BLS snippets. - -In this case, the script is executed with the --no-grubenv-update option -that indicates that no side effects should happen when running the script. - -But the options field in the BLS snippets are updated regardless, only do -the update if --no-grubenv-update was not used. - -Signed-off-by: Javier Martinez Canillas ---- - util/grub.d/10_linux.in | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 6bceabf3dc9..b95a9a8d7ca 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -261,7 +261,9 @@ if [ -z "\${kernelopts}" ]; then - fi - EOF - -- update_bls_cmdline -+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then -+ update_bls_cmdline -+ fi - - if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then - populate_menu diff --git a/0190-Suppress-gettext-error-message.patch b/0190-Suppress-gettext-error-message.patch deleted file mode 100644 index c42dd0d..0000000 --- a/0190-Suppress-gettext-error-message.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Tue, 29 Jun 2021 13:17:42 +0200 -Subject: [PATCH] Suppress gettext error message - -Colin Watson's patch from comment #11 on the upstream bug: -https://savannah.gnu.org/bugs/?35880#comment11 - -Resolves: rhbz#1592124 - -Signed-off-by: Paulo Flabiano Smorigo ---- - grub-core/gettext/gettext.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c -index 4d02e62c109..7ec81ca0b48 100644 ---- a/grub-core/gettext/gettext.c -+++ b/grub-core/gettext/gettext.c -@@ -424,6 +424,13 @@ grub_gettext_init_ext (struct grub_gettext_context *ctx, - grub_free (lang); - } - -+ /* If no translations are available, fall back to untranslated text. */ -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ { -+ grub_errno = GRUB_ERR_NONE; -+ return 0; -+ } -+ - if (locale[0] == 'e' && locale[1] == 'n' - && (locale[2] == '\0' || locale[2] == '_')) - grub_errno = err = GRUB_ERR_NONE; diff --git a/0192-templates-Check-for-EFI-at-runtime-instead-of-config.patch b/0192-templates-Check-for-EFI-at-runtime-instead-of-config.patch deleted file mode 100644 index e36afa1..0000000 --- a/0192-templates-Check-for-EFI-at-runtime-instead-of-config.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 6 Jul 2021 00:38:40 +0200 -Subject: [PATCH] templates: Check for EFI at runtime instead of config - generation time - -The 30_uefi-firmware template checks if an OsIndicationsSupported UEFI var -exists and EFI_OS_INDICATIONS_BOOT_TO_FW_UI bit is set, to decide whether -a "fwsetup" menu entry would be added or not to the GRUB menu. - -But this has the problem that it will only work if the configuration file -was created on an UEFI machine that supports booting to a firmware UI. - -This for example doesn't support creating GRUB config files when executing -on systems that support both UEFI and legacy BIOS booting. Since creating -the config file from legacy BIOS wouldn't allow to access the firmware UI. - -To prevent this, make the template to unconditionally create the grub.cfg -snippet but check at runtime if was booted through UEFI to decide if this -entry should be added. That way it won't be added when booting with BIOS. - -There's no need to check if EFI_OS_INDICATIONS_BOOT_TO_FW_UI bit is set, -since that's already done by the "fwsetup" command when is executed. - -Resolves: rhbz#1823864 - -Signed-off-by: Javier Martinez Canillas ---- - util/grub.d/30_uefi-firmware.in | 21 ++++++++------------- - 1 file changed, 8 insertions(+), 13 deletions(-) - -diff --git a/util/grub.d/30_uefi-firmware.in b/util/grub.d/30_uefi-firmware.in -index d344d3883d7..b6041b55e2a 100644 ---- a/util/grub.d/30_uefi-firmware.in -+++ b/util/grub.d/30_uefi-firmware.in -@@ -26,19 +26,14 @@ export TEXTDOMAINDIR="@localedir@" - - . "$pkgdatadir/grub-mkconfig_lib" - --EFI_VARS_DIR=/sys/firmware/efi/efivars --EFI_GLOBAL_VARIABLE=8be4df61-93ca-11d2-aa0d-00e098032b8c --OS_INDICATIONS="$EFI_VARS_DIR/OsIndicationsSupported-$EFI_GLOBAL_VARIABLE" -+LABEL="UEFI Firmware Settings" - --if [ -e "$OS_INDICATIONS" ] && \ -- [ "$(( $(printf 0x%x \'"$(cat $OS_INDICATIONS | cut -b5)"\') & 1 ))" = 1 ]; then -- LABEL="UEFI Firmware Settings" -+gettext_printf "Adding boot menu entry for UEFI Firmware Settings ...\n" >&2 - -- gettext_printf "Adding boot menu entry for UEFI Firmware Settings ...\n" >&2 -- -- cat << EOF --menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' { -- fwsetup --} --EOF -+cat << EOF -+if [ "\$grub_platform" = "efi" ]; then -+ menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' { -+ fwsetup -+ } - fi -+EOF diff --git a/0193-efi-Print-an-error-if-boot-to-firmware-setup-is-not-.patch b/0193-efi-Print-an-error-if-boot-to-firmware-setup-is-not-.patch deleted file mode 100644 index 65b4aec..0000000 --- a/0193-efi-Print-an-error-if-boot-to-firmware-setup-is-not-.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 6 Jul 2021 01:10:18 +0200 -Subject: [PATCH] efi: Print an error if boot to firmware setup is not - supported - -The "fwsetup" command is only registered if the firmware supports booting -to the firmware setup UI. But it could be possible that the GRUB config -already contains a "fwsetup" entry, because it was generated in a machine -that has support for this feature. - -To prevent users getting a "can't find command `fwsetup`" error if it is -not supported by the firmware, let's just always register the command but -print a more accurate message if the firmware doesn't support this option. - -Resolves: rhbz#1823864 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/commands/efi/efifwsetup.c | 43 ++++++++++++++++++++----------------- - 1 file changed, 23 insertions(+), 20 deletions(-) - -diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c -index eaca0328388..328c45e82e0 100644 ---- a/grub-core/commands/efi/efifwsetup.c -+++ b/grub-core/commands/efi/efifwsetup.c -@@ -27,6 +27,25 @@ - - GRUB_MOD_LICENSE ("GPLv3+"); - -+static grub_efi_boolean_t -+efifwsetup_is_supported (void) -+{ -+ grub_efi_uint64_t *os_indications_supported = NULL; -+ grub_size_t oi_size = 0; -+ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ -+ grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size, -+ (void **) &os_indications_supported); -+ -+ if (!os_indications_supported) -+ return 0; -+ -+ if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) -+ return 1; -+ -+ return 0; -+} -+ - static grub_err_t - grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), -@@ -38,6 +57,10 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), - grub_size_t oi_size; - grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; - -+ if (!efifwsetup_is_supported ()) -+ return grub_error (GRUB_ERR_INVALID_COMMAND, -+ N_("Reboot to firmware setup is not supported")); -+ - grub_efi_get_variable ("OsIndications", &global, &oi_size, - (void **) &old_os_indications); - -@@ -56,28 +79,8 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), - - static grub_command_t cmd = NULL; - --static grub_efi_boolean_t --efifwsetup_is_supported (void) --{ -- grub_efi_uint64_t *os_indications_supported = NULL; -- grub_size_t oi_size = 0; -- grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; -- -- grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size, -- (void **) &os_indications_supported); -- -- if (!os_indications_supported) -- return 0; -- -- if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) -- return 1; -- -- return 0; --} -- - GRUB_MOD_INIT (efifwsetup) - { -- if (efifwsetup_is_supported ()) - cmd = grub_register_command ("fwsetup", grub_cmd_fwsetup, NULL, - N_("Reboot into firmware setup menu.")); - diff --git a/0194-arm64-Fix-EFI-loader-kernel-image-allocation.patch b/0194-arm64-Fix-EFI-loader-kernel-image-allocation.patch deleted file mode 100644 index 0472a42..0000000 --- a/0194-arm64-Fix-EFI-loader-kernel-image-allocation.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Benjamin Herrenschmidt -Date: Mon, 2 Aug 2021 23:10:01 +1000 -Subject: [PATCH] arm64: Fix EFI loader kernel image allocation - -We are currently allocating just enough memory for the file size, -which means that the kernel BSS is in limbo (and not even zeroed). - -We are also not honoring the alignment specified in the image -PE header. - -This makes us use the PE optional header in which the kernel puts the -actual size it needs, including BSS, and make sure we clear it, and -honors the specified alignment for the image. - -Signed-off-by: Benjamin Herrenschmidt -[pjones: arm: check for the PE magic for the compiled arch] -Signed-off-by: Peter Jones -Signed-off-by: Robbie Harwood ---- - grub-core/loader/arm64/linux.c | 100 +++++++++++++++++++++++++++-------------- - include/grub/arm/linux.h | 1 + - include/grub/arm64/linux.h | 1 + - 3 files changed, 68 insertions(+), 34 deletions(-) - -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index 47f8cf0d84b..f18d90bd749 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -41,6 +41,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); - static grub_dl_t my_mod; - static int loaded; - -+static void *kernel_alloc_addr; -+static grub_uint32_t kernel_alloc_pages; - static void *kernel_addr; - static grub_uint64_t kernel_size; - static grub_uint32_t handover_offset; -@@ -204,9 +206,8 @@ grub_linux_unload (void) - GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start)); - initrd_start = initrd_end = 0; - grub_free (linux_args); -- if (kernel_addr) -- grub_efi_free_pages ((grub_addr_t) kernel_addr, -- GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -+ if (kernel_alloc_addr) -+ grub_efi_free_pages ((grub_addr_t) kernel_alloc_addr, kernel_alloc_pages); - grub_fdt_unload (); - return GRUB_ERR_NONE; - } -@@ -311,14 +312,35 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - return grub_errno; - } - -+static grub_err_t -+parse_pe_header (void *kernel, grub_uint64_t *total_size, -+ grub_uint32_t *entry_offset, -+ grub_uint32_t *alignment) -+{ -+ struct linux_arch_kernel_header *lh = kernel; -+ struct grub_armxx_linux_pe_header *pe; -+ -+ pe = (void *)((unsigned long)kernel + lh->hdr_offset); -+ -+ if (pe->opt.magic != GRUB_PE32_PEXX_MAGIC) -+ return grub_error(GRUB_ERR_BAD_OS, "Invalid PE optional header magic"); -+ -+ *total_size = pe->opt.image_size; -+ *entry_offset = pe->opt.entry_addr; -+ *alignment = pe->opt.section_alignment; -+ -+ return GRUB_ERR_NONE; -+} -+ - static grub_err_t - grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) - { - grub_file_t file = 0; -- struct linux_arch_kernel_header lh; -- struct grub_armxx_linux_pe_header *pe; - grub_err_t err; -+ grub_off_t filelen; -+ grub_uint32_t align; -+ void *kernel = NULL; - int rc; - - grub_dl_ref (my_mod); -@@ -333,40 +355,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - if (!file) - goto fail; - -- kernel_size = grub_file_size (file); -- -- if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) -- return grub_errno; -- -- if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE) -- goto fail; -- -- grub_loader_unset(); -- -- grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size); -- kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -- grub_dprintf ("linux", "kernel numpages: %lld\n", -- (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -- if (!kernel_addr) -+ filelen = grub_file_size (file); -+ kernel = grub_malloc(filelen); -+ if (!kernel) - { -- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel load buffer")); - goto fail; - } - -- grub_file_seek (file, 0); -- if (grub_file_read (file, kernel_addr, kernel_size) -- < (grub_int64_t) kernel_size) -+ if (grub_file_read (file, kernel, filelen) < (grub_ssize_t)filelen) - { -- if (!grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), -+ argv[0]); - goto fail; - } - -- grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); -- - if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { -- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size); -+ rc = grub_linuxefi_secure_validate (kernel, filelen); - if (rc <= 0) - { - grub_error (GRUB_ERR_INVALID_COMMAND, -@@ -375,8 +381,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - } - -- pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset); -- handover_offset = pe->opt.entry_addr; -+ if (grub_arch_efi_linux_check_image (kernel) != GRUB_ERR_NONE) -+ goto fail; -+ if (parse_pe_header (kernel, &kernel_size, &handover_offset, &align) != GRUB_ERR_NONE) -+ goto fail; -+ grub_dprintf ("linux", "kernel mem size : %lld\n", (long long) kernel_size); -+ grub_dprintf ("linux", "kernel entry offset : %d\n", handover_offset); -+ grub_dprintf ("linux", "kernel alignment : 0x%x\n", align); -+ -+ grub_loader_unset(); -+ -+ kernel_alloc_pages = GRUB_EFI_BYTES_TO_PAGES (kernel_size + align - 1); -+ kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages); -+ grub_dprintf ("linux", "kernel numpages: %d\n", kernel_alloc_pages); -+ if (!kernel_alloc_addr) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ kernel_addr = (void *)ALIGN_UP((grub_uint64_t)kernel_alloc_addr, align); -+ -+ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); -+ grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)); -+ if (kernel_size > filelen) -+ grub_memset ((char *)kernel_addr + filelen, 0, kernel_size - filelen); -+ grub_free(kernel); -+ kernel = NULL; - - cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); - linux_args = grub_malloc (cmdline_size); -@@ -400,6 +430,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - - fail: -+ if (kernel) -+ grub_free (kernel); -+ - if (file) - grub_file_close (file); - -@@ -412,9 +445,8 @@ fail: - if (linux_args && !loaded) - grub_free (linux_args); - -- if (kernel_addr && !loaded) -- grub_efi_free_pages ((grub_addr_t) kernel_addr, -- GRUB_EFI_BYTES_TO_PAGES (kernel_size)); -+ if (kernel_alloc_addr && !loaded) -+ grub_efi_free_pages ((grub_addr_t) kernel_alloc_addr, kernel_alloc_pages); - - return grub_errno; - } -diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h -index b582f67f661..966a5074f53 100644 ---- a/include/grub/arm/linux.h -+++ b/include/grub/arm/linux.h -@@ -44,6 +44,7 @@ struct grub_arm_linux_pe_header - - #if defined(__arm__) - # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE -+# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE32_MAGIC - # define linux_arch_kernel_header linux_arm_kernel_header - # define grub_armxx_linux_pe_header grub_arm_linux_pe_header - #endif -diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h -index ea030312df3..422bf2bf24b 100644 ---- a/include/grub/arm64/linux.h -+++ b/include/grub/arm64/linux.h -@@ -48,6 +48,7 @@ struct grub_arm64_linux_pe_header - - #if defined(__aarch64__) - # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE -+# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE64_MAGIC - # define linux_arch_kernel_header linux_arm64_kernel_header - # define grub_armxx_linux_pe_header grub_arm64_linux_pe_header - #endif diff --git a/0195-normal-main-Discover-the-device-to-read-the-config-f.patch b/0195-normal-main-Discover-the-device-to-read-the-config-f.patch deleted file mode 100644 index 8009038..0000000 --- a/0195-normal-main-Discover-the-device-to-read-the-config-f.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 30 Aug 2021 12:31:18 +0200 -Subject: [PATCH] normal/main: Discover the device to read the config from as a - fallback - -The GRUB core.img is generated locally, when this is done the grub2-probe -tool figures out the device and partition that needs to be read to parse -the GRUB configuration file. - -But in some cases the core.img can't be generated on the host and instead -has to be done at package build time. For example, if needs to get signed -with a key that's only available on the package building infrastructure. - -If that's the case, the prefix variable won't have a device and partition -but only a directory path. So there's no way for GRUB to know from which -device has to read the configuration file. - -To allow GRUB to continue working on that scenario, fallback to iterating -over all the available devices, if reading the config failed when using -the prefix and fw_path variables. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/normal/main.c | 58 +++++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 51 insertions(+), 7 deletions(-) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 4ebdbd228d4..b72fe3d653c 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -337,18 +337,13 @@ grub_enter_normal_mode (const char *config) - } - - static grub_err_t --grub_try_normal (const char *variable) -+grub_try_normal_prefix (const char *prefix) - { - char *config; -- const char *prefix; - grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; - const char *net_search_cfg; - int disable_net_search = 0; - -- prefix = grub_env_get (variable); -- if (!prefix) -- return GRUB_ERR_FILE_NOT_FOUND; -- - net_search_cfg = grub_env_get ("feature_net_search_cfg"); - if (net_search_cfg && net_search_cfg[0] == 'n') - disable_net_search = 1; -@@ -362,7 +357,7 @@ grub_try_normal (const char *variable) - config = grub_malloc (config_len); - - if (! config) -- return GRUB_ERR_FILE_NOT_FOUND; -+ return err; - - grub_snprintf (config, config_len, "%s/grub.cfg", prefix); - err = grub_net_search_config_file (config); -@@ -391,6 +386,53 @@ grub_try_normal (const char *variable) - return err; - } - -+static int -+grub_try_normal_dev (const char *name, void *data) -+{ -+ grub_err_t err; -+ const char *prefix = grub_xasprintf ("(%s)%s", name, (char *)data); -+ -+ if (!prefix) -+ return 0; -+ -+ err = grub_try_normal_prefix (prefix); -+ if (err == GRUB_ERR_NONE) -+ return 1; -+ -+ return 0; -+} -+ -+static grub_err_t -+grub_try_normal_discover (void) -+{ -+ char *prefix = grub_env_get ("prefix"); -+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; -+ -+ if (!prefix) -+ return err; -+ -+ if (grub_device_iterate (grub_try_normal_dev, (void *)prefix)) -+ return GRUB_ERR_NONE; -+ -+ return err; -+} -+ -+static grub_err_t -+grub_try_normal (const char *variable) -+{ -+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; -+ const char *prefix; -+ -+ if (!variable) -+ return err; -+ -+ prefix = grub_env_get (variable); -+ if (!prefix) -+ return err; -+ -+ return grub_try_normal_prefix (prefix); -+} -+ - /* Enter normal mode from rescue mode. */ - static grub_err_t - grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), -@@ -405,6 +447,8 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - err = grub_try_normal ("fw_path"); - if (err == GRUB_ERR_FILE_NOT_FOUND) - err = grub_try_normal ("prefix"); -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ err = grub_try_normal_discover (); - if (err == GRUB_ERR_FILE_NOT_FOUND) - grub_enter_normal_mode (0); - } diff --git a/0196-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch b/0196-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch deleted file mode 100644 index 7f3161e..0000000 --- a/0196-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 19 Jul 2021 14:35:55 +1000 -Subject: [PATCH] powerpc: adjust setting of prefix for signed binary case - -On RHEL-signed powerpc grub, we sign a grub with -p /grub2 and expect -that there's a boot partition. - -Unfortunately grub_set_prefix_and_root tries to convert this to -($fwdevice)/grub2. This ends up being (ieee1275/disk)/grub2 and that -falls apart pretty quickly - there's no file-system on ieee1275/disk, -and it makes the search routine try things like -(ieee1275/disk,msdos2)(ieee1275/disk)/grub2 which also doesn't work. - -Detect if we would be about to create (ieee1275/disk)/path and don't: -preserve a prefix of /path instead and hope the search later finds us. - -Related: rhbz#1899864 - -Signed-off-by: Daniel Axtens -[rharwood@redhat.com: squash in fixup commit] -Signed-off-by: Robbie Harwood ---- - grub-core/kern/main.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 44 insertions(+), 5 deletions(-) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index b573be6650d..3fc34014726 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -216,13 +216,52 @@ grub_set_prefix_and_root (void) - if (device) - { - char *prefix_set; -- -- prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); -- if (prefix_set) -+ -+#ifdef __powerpc__ -+ /* We have to be careful here on powerpc-ieee1275 + signed grub. We -+ will have signed something with a prefix that doesn't have a device -+ because we cannot know in advance what partition we're on. -+ -+ We will have had !device earlier, so we will have set device=fwdevice -+ However, we want to make sure we do not end up setting prefix to be -+ ($fwdevice)/path, because we will then end up trying to boot or search -+ based on a prefix of (ieee1275/disk)/path, which will not work because -+ it's missing a partition. -+ -+ Also: -+ - You can end up with a device with an FS directly on it, without -+ a partition, e.g. ieee1275/cdrom. -+ -+ - powerpc-ieee1275 + grub-install sets e.g. prefix=(,gpt2)/path, -+ which will have now been extended to device=$fwdisk,partition -+ and path=/path -+ -+ - PowerVM will give us device names like -+ ieee1275//vdevice/v-scsi@3000006c/disk@8100000000000000 -+ and we don't want to try to encode some sort of truth table about -+ what sorts of paths represent disks with partition tables and those -+ without partition tables. -+ -+ So we act unless there is a comma in the device, which would indicate -+ a partition has already been specified. -+ -+ (If we only have a path, the code in normal to discover config files -+ will try both without partitions and then with any partitions so we -+ will cover both CDs and HDs.) -+ */ -+ if (grub_strchr (device, ',') == NULL) -+ grub_env_set ("prefix", path); -+ else -+#endif - { -- grub_env_set ("prefix", prefix_set); -- grub_free (prefix_set); -+ prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); -+ if (prefix_set) -+ { -+ grub_env_set ("prefix", prefix_set); -+ grub_free (prefix_set); -+ } - } -+ - grub_env_set ("root", device); - } - diff --git a/0197-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch b/0197-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch deleted file mode 100644 index 893d8b4..0000000 --- a/0197-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Erwan Velu -Date: Wed, 25 Aug 2021 15:31:52 +0200 -Subject: [PATCH] fs/xfs: Fix unreadable filesystem with v4 superblock - -The commit 8b1e5d193 (fs/xfs: Add bigtime incompat feature support) -introduced the bigtime support by adding some features in v3 inodes. -This change extended grub_xfs_inode struct by 76 bytes but also changed -the computation of XFS_V2_INODE_SIZE and XFS_V3_INODE_SIZE. Prior this -commit, XFS_V2_INODE_SIZE was 100 bytes. After the commit it's 84 bytes -XFS_V2_INODE_SIZE becomes 16 bytes too small. - -As a result, the data structures aren't properly aligned and the GRUB -generates "attempt to read or write outside of partition" errors when -trying to read the XFS filesystem: - - GNU GRUB version 2.11 - .... - grub> set debug=efi,gpt,xfs - grub> insmod part_gpt - grub> ls (hd0,gpt1)/ - partmap/gpt.c:93: Read a valid GPT header - partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125 - fs/xfs.c:931: Reading sb - fs/xfs.c:270: Validating superblock - fs/xfs.c:295: XFS v4 superblock detected - fs/xfs.c:962: Reading root ino 128 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (739521961424144223) - 344365866970255880, 3840 - error: attempt to read or write outside of partition. - -This commit change the XFS_V2_INODE_SIZE computation by subtracting 76 -bytes instead of 92 bytes from the actual size of grub_xfs_inode struct. -This 76 bytes value comes from added members: - 20 grub_uint8_t unused5 - 1 grub_uint64_t flags2 - 48 grub_uint8_t unused6 - -This patch explicitly splits the v2 and v3 parts of the structure. -The unused4 is still ending of the v2 structures and the v3 starts -at unused5. Thanks to this we will avoid future corruptions of v2 -or v3 inodes. - -The XFS_V2_INODE_SIZE is returning to its expected size and the -filesystem is back to a readable state: - - GNU GRUB version 2.11 - .... - grub> set debug=efi,gpt,xfs - grub> insmod part_gpt - grub> ls (hd0,gpt1)/ - partmap/gpt.c:93: Read a valid GPT header - partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125 - fs/xfs.c:931: Reading sb - fs/xfs.c:270: Validating superblock - fs/xfs.c:295: XFS v4 superblock detected - fs/xfs.c:962: Reading root ino 128 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:931: Reading sb - fs/xfs.c:270: Validating superblock - fs/xfs.c:295: XFS v4 superblock detected - fs/xfs.c:962: Reading root ino 128 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (131) - 64, 768 - efi/ fs/xfs.c:515: Reading inode (3145856) - 1464904, 0 - grub2/ fs/xfs.c:515: Reading inode (132) - 64, 1024 - grub/ fs/xfs.c:515: Reading inode (139) - 64, 2816 - grub> - -Fixes: 8b1e5d193 (fs/xfs: Add bigtime incompat feature support) - -Signed-off-by: Erwan Velu -Tested-by: Carlos Maiolino -Reviewed-by: Daniel Kiper -(cherry picked from commit a4b495520e4dc41a896a8b916a64eda9970c50ea) ---- - grub-core/fs/xfs.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c -index 0f524c3a8a6..e3816d1ec4a 100644 ---- a/grub-core/fs/xfs.c -+++ b/grub-core/fs/xfs.c -@@ -192,6 +192,11 @@ struct grub_xfs_time_legacy - grub_uint32_t nanosec; - } GRUB_PACKED; - -+/* -+ * The struct grub_xfs_inode layout was taken from the -+ * struct xfs_dinode_core which is described here: -+ * https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf -+ */ - struct grub_xfs_inode - { - grub_uint8_t magic[2]; -@@ -208,14 +213,15 @@ struct grub_xfs_inode - grub_uint32_t nextents; - grub_uint16_t unused3; - grub_uint8_t fork_offset; -- grub_uint8_t unused4[37]; -+ grub_uint8_t unused4[17]; /* Last member of inode v2. */ -+ grub_uint8_t unused5[20]; /* First member of inode v3. */ - grub_uint64_t flags2; -- grub_uint8_t unused5[48]; -+ grub_uint8_t unused6[48]; /* Last member of inode v3. */ - } GRUB_PACKED; - - #define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode) --/* Size of struct grub_xfs_inode until fork_offset (included). */ --#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 92) -+/* Size of struct grub_xfs_inode v2, up to unused4 member included. */ -+#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76) - - struct grub_xfs_dirblock_tail - { diff --git a/0198-Print-module-name-on-license-check-failure.patch b/0198-Print-module-name-on-license-check-failure.patch deleted file mode 100644 index c4b9a13..0000000 --- a/0198-Print-module-name-on-license-check-failure.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Tue, 12 Oct 2021 12:34:23 -0400 -Subject: [PATCH] Print module name on license check failure - -At the very least, this will make it easier to track down the problem -module - or, if something else has gone wrong, provide more information -for debugging. - -Signed-off-by: Robbie Harwood ---- - grub-core/kern/dl.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 9557254035e..f3044945742 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -528,14 +528,16 @@ grub_dl_find_section_index (Elf_Ehdr *e, const char *name) - Be sure to understand your license obligations. - */ - static grub_err_t --grub_dl_check_license (Elf_Ehdr *e) -+grub_dl_check_license (grub_dl_t mod, Elf_Ehdr *e) - { - Elf_Shdr *s = grub_dl_find_section (e, ".module_license"); - if (s && (grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv3") == 0 - || grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv3+") == 0 - || grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv2+") == 0)) - return GRUB_ERR_NONE; -- return grub_error (GRUB_ERR_BAD_MODULE, "incompatible license"); -+ return grub_error (GRUB_ERR_BAD_MODULE, -+ "incompatible license in module %s: %s", mod->name, -+ (char *) e + s->sh_offset); - } - - static grub_err_t -@@ -743,8 +745,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) - constitutes linking) and GRUB core being licensed under GPLv3+. - Be sure to understand your license obligations. - */ -- if (grub_dl_check_license (e) -- || grub_dl_resolve_name (mod, e) -+ if (grub_dl_resolve_name (mod, e) -+ || grub_dl_check_license (mod, e) - || grub_dl_resolve_dependencies (mod, e) - || grub_dl_load_segments (mod, e) - || grub_dl_resolve_symbols (mod, e) diff --git a/0199-powerpc-ieee1275-load-grub-at-4MB-not-2MB.patch b/0199-powerpc-ieee1275-load-grub-at-4MB-not-2MB.patch deleted file mode 100644 index a80727e..0000000 --- a/0199-powerpc-ieee1275-load-grub-at-4MB-not-2MB.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 22 Oct 2021 09:53:15 +1100 -Subject: [PATCH] powerpc-ieee1275: load grub at 4MB, not 2MB - -This was first reported under PFW but reproduces under SLOF. - - - The core.elf was 2126152 = 0x207148 bytes in size with the following - program headers (per readelf): - -Entry point 0x200000 -There are 4 program headers, starting at offset 52 - -Program Headers: - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - LOAD 0x000160 0x00200000 0x00200000 0x21f98 0x2971c RWE 0x8 - GNU_STACK 0x0220f8 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4 - LOAD 0x0220f8 0x00232000 0x00232000 0x1e4e50 0x1e4e50 RWE 0x4 - NOTE 0x206f48 0x00000000 0x00000000 0x00200 0x00000 R 0x4 - - - SLOF places the ELF file at 0x4000 (after the reserved space for - interrupt handlers etc.) upwards. The image was 2126152 = 0x207148 - bytes in size, so it runs from 0x4000 - 0x20b148. We'll call 0x4000 the - load address. - -0x0 0x4000 0x20b148 - |----------|--------------| - | reserved | ELF contents | - - - SLOF then copies the first LOAD program header (for .text). That runs - for 0x21f98 bytes. It runs from - (load addr + 0x160) to (load addr + 0x160 + 0x21f98) - = 0x4160 to 0x260f8 - and we copy it to 0x200000 to 0x221f98. This overwrites the end of the - image: - -0x0 0x4000 0x200000 0x221f98 - |----------|------------|---------------| - | reserved | ELF cont.. | .text section | - - - SLOF zeros the bss up to PhysAddr + MemSize = 0x22971c - -0x0 0x4000 0x200000 0x221f98 0x22971c - |----------|------------|---------------|--------| - | reserved | ELF cont.. | .text section | bss 0s | - - - SLOF then goes to fulfil the next LOAD header (for mods), which is - for 0x1e4e50 bytes. We copy from - (load addr + 0x220f8) to (load addr + 0x220f8 + 0x1e4e50) - = 0x260f8 to 0x20af48 - and we copy it to 0x232000 to 0x416e50: - -0x0 0x4000 0x200000 0x221f98 0x22971c - |----------|------------|---------------|--------| - | reserved | ELF cont.. | .text section | bss 0s | - |-------------| - | copied area | - 0x260f8 0x20af48 - - This goes poorly: - -0x0 0x4000 0x200000 0x221f98 0x22971c 0x232000 0x40bf08 0x416e50 - |----------|------------|---------------|--------|-----|-----------|-------------| - | reserved | ELF cont.. | .text section | bss 0s | pad | some mods | .text start | - -This matches the observations on the running system - 0x40bf08 was where -the contents of memory no longer matched the contents of the ELF file. - -This was reported as a license verification failure on SLOF as the -last module's .module_license section fell past where the corruption -began. - -Signed-off-by: Daniel Axtens -[rharwood@redhat.com: trim very detailed commit message] -Signed-off-by: Robbie Harwood ---- - grub-core/Makefile.core.def | 2 +- - include/grub/offsets.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 3f3459b2c70..6b00eb55575 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -89,7 +89,7 @@ kernel = { - i386_xen_pvh_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x100000'; - - mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; -- powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; -+ powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x400000'; - sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; - mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)'; - mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000'; -diff --git a/include/grub/offsets.h b/include/grub/offsets.h -index 871e1cd4c38..69211aa798b 100644 ---- a/include/grub/offsets.h -+++ b/include/grub/offsets.h -@@ -63,7 +63,7 @@ - #define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 - - #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 --#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 -+#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x400000 - - #define GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR 0x80200000 - diff --git a/0200-grub-mkconfig-restore-umask-for-grub.cfg.patch b/0200-grub-mkconfig-restore-umask-for-grub.cfg.patch deleted file mode 100644 index 7c7bee0..0000000 --- a/0200-grub-mkconfig-restore-umask-for-grub.cfg.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang via Grub-devel -Date: Fri, 3 Dec 2021 16:13:28 +0800 -Subject: [PATCH] grub-mkconfig: restore umask for grub.cfg - -Since commit: - - ab2e53c8a grub-mkconfig: Honor a symlink when generating configuration -by grub-mkconfig - -has inadvertently discarded umask for creating grub.cfg in the process -of grub-mkconfig. The resulting wrong permission (0644) would allow -unprivileged users to read grub's configuration file content. This -presents a low confidentiality risk as grub.cfg may contain non-secured -plain-text passwords. - -This patch restores the missing umask and set the file mode of creation -to 0600 preventing unprivileged access. - -Fixes: CVE-2021-3981 - -Signed-off-by: Michael Chang ---- - util/grub-mkconfig.in | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index f55339a3f64..520a672cd2c 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -311,7 +311,9 @@ and /etc/grub.d/* files or please file a bug report with - exit 1 - else - # none of the children aborted with error, install the new grub.cfg -+ oldumask=$(umask); umask 077 - cat ${grub_cfg}.new > ${grub_cfg} -+ umask $oldumask - rm -f ${grub_cfg}.new - fi - fi diff --git a/0201-fs-btrfs-Use-full-btrfs-bootloader-area.patch b/0201-fs-btrfs-Use-full-btrfs-bootloader-area.patch deleted file mode 100644 index ecfc58c..0000000 --- a/0201-fs-btrfs-Use-full-btrfs-bootloader-area.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Mon, 13 Dec 2021 14:25:49 +0800 -Subject: [PATCH] fs/btrfs: Use full btrfs bootloader area - -Up to now GRUB can only embed to the first 64 KiB before primary -superblock of btrfs, effectively limiting the GRUB core size. That -could consequently pose restrictions to feature enablement like -advanced zstd compression. - -This patch attempts to utilize full unused area reserved by btrfs for -the bootloader outlined in the document [1]: - - The first 1MiB on each device is unused with the exception of primary - superblock that is on the offset 64KiB and spans 4KiB. - -Apart from that, adjacent sectors to superblock and first block group -are not used for embedding in case of overflow and logged access to -adjacent sectors could be useful for tracing it up. - -This patch has been tested to provide out of the box support for btrfs -zstd compression with which GRUB has been installed to the partition. - -[1] https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)#BOOTLOADER_SUPPORT - -Signed-off-by: Michael Chang -Reviewed-by: Daniel Kiper -(cherry picked from commit b0f06a81c6f31b6fa20be67a96b6683bba8210c9) ---- - grub-core/fs/btrfs.c | 90 ++++++++++++++++++++++++++++++++++++++++++++-------- - include/grub/disk.h | 2 ++ - 2 files changed, 79 insertions(+), 13 deletions(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 4cc86e9b79e..07c0ff874b8 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -2476,6 +2476,33 @@ grub_btrfs_label (grub_device_t device, char **label) - } - - #ifdef GRUB_UTIL -+ -+struct embed_region { -+ unsigned int start; -+ unsigned int secs; -+}; -+ -+/* -+ * https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)#BOOTLOADER_SUPPORT -+ * The first 1 MiB on each device is unused with the exception of primary -+ * superblock that is on the offset 64 KiB and spans 4 KiB. -+ */ -+ -+static const struct { -+ struct embed_region available; -+ struct embed_region used[6]; -+} btrfs_head = { -+ .available = {0, GRUB_DISK_KiB_TO_SECTORS (1024)}, /* The first 1 MiB. */ -+ .used = { -+ {0, 1}, /* boot.S. */ -+ {GRUB_DISK_KiB_TO_SECTORS (64) - 1, 1}, /* Overflow guard. */ -+ {GRUB_DISK_KiB_TO_SECTORS (64), GRUB_DISK_KiB_TO_SECTORS (4)}, /* 4 KiB superblock. */ -+ {GRUB_DISK_KiB_TO_SECTORS (68), 1}, /* Overflow guard. */ -+ {GRUB_DISK_KiB_TO_SECTORS (1024) - 1, 1}, /* Overflow guard. */ -+ {0, 0} /* Array terminator. */ -+ } -+}; -+ - static grub_err_t - grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), - unsigned int *nsectors, -@@ -2483,25 +2510,62 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors) - { -- unsigned i; -+ unsigned int i, j, n = 0; -+ const struct embed_region *u; -+ grub_disk_addr_t *map; - - if (embed_type != GRUB_EMBED_PCBIOS) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "BtrFS currently supports only PC-BIOS embedding"); - -- if (64 * 2 - 1 < *nsectors) -- return grub_error (GRUB_ERR_OUT_OF_RANGE, -- N_("your core.img is unusually large. " -- "It won't fit in the embedding area")); -- -- *nsectors = 64 * 2 - 1; -- if (*nsectors > max_nsectors) -- *nsectors = max_nsectors; -- *sectors = grub_calloc (*nsectors, sizeof (**sectors)); -- if (!*sectors) -+ map = grub_calloc (btrfs_head.available.secs, sizeof (*map)); -+ if (map == NULL) - return grub_errno; -- for (i = 0; i < *nsectors; i++) -- (*sectors)[i] = i + 1; -+ -+ /* -+ * Populating the map array so that it can be used to index if a disk -+ * address is available to embed: -+ * - 0: available, -+ * - 1: unavailable. -+ */ -+ for (u = btrfs_head.used; u->secs; ++u) -+ { -+ unsigned int end = u->start + u->secs; -+ -+ if (end > btrfs_head.available.secs) -+ end = btrfs_head.available.secs; -+ for (i = u->start; i < end; ++i) -+ map[i] = 1; -+ } -+ -+ /* Adding up n until it matches total size of available embedding area. */ -+ for (i = 0; i < btrfs_head.available.secs; ++i) -+ if (map[i] == 0) -+ n++; -+ -+ if (n < *nsectors) -+ { -+ grub_free (map); -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("your core.img is unusually large. " -+ "It won't fit in the embedding area")); -+ } -+ -+ if (n > max_nsectors) -+ n = max_nsectors; -+ -+ /* -+ * Populating the array so that it can used to index disk block address for -+ * an image file's offset to be embedded on disk (the unit is in sectors): -+ * - i: The disk block address relative to btrfs_head.available.start, -+ * - j: The offset in image file. -+ */ -+ for (i = 0, j = 0; i < btrfs_head.available.secs && j < n; ++i) -+ if (map[i] == 0) -+ map[j++] = btrfs_head.available.start + i; -+ -+ *nsectors = n; -+ *sectors = map; - - return GRUB_ERR_NONE; - } -diff --git a/include/grub/disk.h b/include/grub/disk.h -index f95aca929a6..06210a70492 100644 ---- a/include/grub/disk.h -+++ b/include/grub/disk.h -@@ -182,6 +182,8 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; - /* Return value of grub_disk_native_sectors() in case disk size is unknown. */ - #define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL - -+#define GRUB_DISK_KiB_TO_SECTORS(x) ((x) << (10 - GRUB_DISK_SECTOR_BITS)) -+ - /* Convert sector number from one sector size to another. */ - static inline grub_disk_addr_t - grub_convert_sector (grub_disk_addr_t sector, diff --git a/0202-rpm-sort-add-prereqs-for-declaration-of-strchrnul.patch b/0202-rpm-sort-add-prereqs-for-declaration-of-strchrnul.patch deleted file mode 100644 index 9847347..0000000 --- a/0202-rpm-sort-add-prereqs-for-declaration-of-strchrnul.patch +++ /dev/null @@ -1,42 +0,0 @@ -From da43f9b55b5084a1c9f72785fa29ec62e70658c2 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Thu, 5 May 2022 18:01:05 -0400 -Subject: [PATCH] rpm-sort: add prereqs for declaration of strchrnul() - -Reference:https://src.fedoraproject.org/rpms/grub2/c/ea7cfdf72690c5d6e15af02a3e395a40dd24f7c7 -Conflict:NA - -Signed-off-by: Robbie Harwood ---- - util/grub-rpm-sort.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/util/grub-rpm-sort.c b/util/grub-rpm-sort.c -index 8345944..71d038b 100644 ---- a/util/grub-rpm-sort.c -+++ b/util/grub-rpm-sort.c -@@ -1,13 +1,17 @@ -+#define _GNU_SOURCE 1 -+ - #include -+ -+#include -+#include -+#include - #include - #include -+#include - #include - #include -+#include - #include --#include --#include --#include --#include - - static size_t - read_file (const char *input, char **ret) --- -2.27.0 - diff --git a/1000-port-Add-LoongArch-support.patch b/1000-port-Add-LoongArch-support.patch deleted file mode 100644 index 4d19b96..0000000 --- a/1000-port-Add-LoongArch-support.patch +++ /dev/null @@ -1,3574 +0,0 @@ -From 781cdb1573ffb77ed6d507d8daa7c6ff92256c57 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Thu, 12 Jan 2023 14:44:13 +0800 -Subject: [PATCH] port: Add LoongArch support - -This patch adds support for LoongArch. From now on, we can boot up -grub as a UEFI application on LoongArch platform. - -Signed-off-by: yangqiming -Signed-off-by: mengyingkun ---- - Makefile.util.def | 1 + - bootstrap.conf | 4 + - configure.ac | 24 + - gentpl.py | 9 +- - grub-core/Makefile.am | 6 + - grub-core/Makefile.core.def | 23 + - grub-core/kern/dl.c | 9 +- - grub-core/kern/efi/mm.c | 3 +- - grub-core/kern/loongarch64/cache.S | 26 + - grub-core/kern/loongarch64/dl.c | 150 +++++ - grub-core/kern/loongarch64/dl_helper.c | 264 +++++++++ - grub-core/kern/loongarch64/efi/init.c | 73 +++ - grub-core/kern/loongarch64/efi/startup.S | 45 ++ - grub-core/kern/loongarch64/init.c | 47 ++ - .../lib/gnulib-patches/fix-loongarch.patch | 26 + - grub-core/lib/loongarch64/relocator.c | 163 ++++++ - grub-core/lib/loongarch64/relocator_asm.S | 51 ++ - grub-core/lib/loongarch64/setjmp.S | 68 +++ - grub-core/lib/setjmp.S | 2 + - grub-core/loader/efi/chainloader.c | 2 + - grub-core/loader/loongarch64/linux-efi.c | 144 +++++ - grub-core/loader/loongarch64/linux-elf.c | 529 ++++++++++++++++++ - grub-core/loader/loongarch64/linux.c | 398 +++++++++++++ - include/grub/efi/api.h | 2 +- - include/grub/efi/efi.h | 6 +- - include/grub/efi/pe32.h | 4 + - include/grub/elf.h | 30 + - include/grub/fdt.h | 4 +- - include/grub/loongarch64/efi/loader.h | 25 + - include/grub/loongarch64/efi/memory.h | 15 + - include/grub/loongarch64/efi/time.h | 0 - include/grub/loongarch64/io.h | 62 ++ - include/grub/loongarch64/linux.h | 144 +++++ - include/grub/loongarch64/loongarch64.h | 30 + - include/grub/loongarch64/memory.h | 59 ++ - include/grub/loongarch64/reloc.h | 113 ++++ - include/grub/loongarch64/relocator.h | 38 ++ - include/grub/loongarch64/setjmp.h | 27 + - include/grub/loongarch64/time.h | 39 ++ - include/grub/loongarch64/types.h | 34 ++ - include/grub/util/install.h | 1 + - util/grub-install-common.c | 1 + - util/grub-install.c | 16 + - util/grub-mkimagexx.c | 99 +++- - util/grub-module-verifier.c | 15 + - util/mkimage.c | 16 + - 46 files changed, 2833 insertions(+), 14 deletions(-) - create mode 100644 grub-core/kern/loongarch64/cache.S - create mode 100644 grub-core/kern/loongarch64/dl.c - create mode 100644 grub-core/kern/loongarch64/dl_helper.c - create mode 100644 grub-core/kern/loongarch64/efi/init.c - create mode 100644 grub-core/kern/loongarch64/efi/startup.S - create mode 100644 grub-core/kern/loongarch64/init.c - create mode 100644 grub-core/lib/gnulib-patches/fix-loongarch.patch - create mode 100644 grub-core/lib/loongarch64/relocator.c - create mode 100644 grub-core/lib/loongarch64/relocator_asm.S - create mode 100644 grub-core/lib/loongarch64/setjmp.S - create mode 100644 grub-core/loader/loongarch64/linux-efi.c - create mode 100644 grub-core/loader/loongarch64/linux-elf.c - create mode 100644 grub-core/loader/loongarch64/linux.c - create mode 100644 include/grub/loongarch64/efi/loader.h - create mode 100644 include/grub/loongarch64/efi/memory.h - create mode 100644 include/grub/loongarch64/efi/time.h - create mode 100644 include/grub/loongarch64/io.h - create mode 100644 include/grub/loongarch64/linux.h - create mode 100644 include/grub/loongarch64/loongarch64.h - create mode 100644 include/grub/loongarch64/memory.h - create mode 100644 include/grub/loongarch64/reloc.h - create mode 100644 include/grub/loongarch64/relocator.h - create mode 100644 include/grub/loongarch64/setjmp.h - create mode 100644 include/grub/loongarch64/time.h - create mode 100644 include/grub/loongarch64/types.h - -diff --git a/Makefile.util.def b/Makefile.util.def -index b7a6311..932a8c2 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -169,6 +169,7 @@ library = { - common = grub-core/kern/ia64/dl_helper.c; - common = grub-core/kern/arm/dl_helper.c; - common = grub-core/kern/arm64/dl_helper.c; -+ common = grub-core/kern/loongarch64/dl_helper.c; - common = grub-core/lib/minilzo/minilzo.c; - common = grub-core/lib/xzembed/xz_dec_bcj.c; - common = grub-core/lib/xzembed/xz_dec_lzma2.c; -diff --git a/bootstrap.conf b/bootstrap.conf -index 03f1093..854d3c0 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -85,6 +85,10 @@ cp -a INSTALL INSTALL.grub - - bootstrap_post_import_hook () { - set -e -+ for patchname in fix-loongarch; do -+ patch -d gnulib -p1 \ -+ < "grub-core/lib/gnulib-patches/$patchname.patch" -+ done - for patchname in \ - 0001-Support-POTFILES-shell \ - 0002-Handle-gettext_printf-shell-function \ -diff --git a/configure.ac b/configure.ac -index 0a9522a..d03e089 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -149,6 +149,10 @@ case "$target_cpu" in - riscv64*) - target_cpu=riscv64 - ;; -+ loongarch64) -+ target_cpu=loongarch64 -+ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_LOONGARCH64=1" -+ ;; - esac - - # Specify the platform (such as firmware). -@@ -167,6 +171,7 @@ if test "x$with_platform" = x; then - powerpc64-*) platform=ieee1275 ;; - powerpc64le-*) platform=ieee1275 ;; - sparc64-*) platform=ieee1275 ;; -+ loongarch64-*) platform=efi ;; - mipsel-*) platform=loongson ;; - mips-*) platform=arc ;; - ia64-*) platform=efi ;; -@@ -218,6 +223,7 @@ case "$target_cpu"-"$platform" in - mipsel-yeeloong) platform=loongson ;; - mipsel-fuloong) platform=loongson ;; - mipsel-loongson) ;; -+ loongarch64-efi) ;; - arm-uboot) ;; - arm-coreboot) ;; - arm-efi) ;; -@@ -276,6 +282,7 @@ case "$platform" in - pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;; - emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; - loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1" ;; -+ loongson64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_LOONARCH64=1" ;; - qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;; - arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; - esac -@@ -890,6 +897,21 @@ if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$p - TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow" - fi - -+if test "x$target_cpu" = xloongarch64; then -+ AC_CACHE_CHECK([whether _mno_explicit_relocs works], [grub_cv_cc_mno_explicit_relocs], [ -+ CFLAGS="$TARGET_CFLAGS -mno-explicit-relocs -Werror" -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], -+ [grub_cv_cc_mno_explicit_relocs=yes], -+ [grub_cv_cc_mno_explicit_relocs=no]) -+ ]) -+ if test "x$grub_cv_cc_mno_explicit_relocs" = xyes; then -+ TARGET_CFLAGS="$TARGET_CFLAGS -mno-explicit-relocs -fno-plt" -+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-explicit-relocs -fno-plt" -+ fi -+ TARGET_CFLAGS="$TARGET_CFLAGS -Wa,-mla-global-with-abs" -+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -Wa,-mla-global-with-abs" -+fi -+ - # Should grub utils get the host CFLAGS, or the target CFLAGS? - AC_ARG_WITH([utils], - AS_HELP_STRING([--with-utils=host|target|build], -@@ -2166,6 +2188,8 @@ AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = - AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) - AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu]) - AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) -+AM_CONDITIONAL([COND_loongarch64_efi], [test x$target_cpu = xloongarch64 -a x$platform = xefi]) -+AM_CONDITIONAL([COND_loongarch64], [test x$target_cpu = xloongarch64]) - AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) - AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) - AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) -diff --git a/gentpl.py b/gentpl.py -index 59f62ef..f03aff8 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -32,7 +32,8 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", - "mips_loongson", "sparc64_ieee1275", - "powerpc_ieee1275", "mips_arc", "ia64_efi", - "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi", -- "arm_coreboot", "riscv32_efi", "riscv64_efi" ] -+ "arm_coreboot", "riscv32_efi", "riscv64_efi", -+ "loongarch64_efi" ] - - GROUPS = {} - -@@ -49,11 +50,12 @@ GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ] - GROUPS["arm64"] = [ "arm64_efi" ] - GROUPS["riscv32"] = [ "riscv32_efi" ] - GROUPS["riscv64"] = [ "riscv64_efi" ] -+GROUPS["loongarch64"] = [ "loongarch64_efi" ] - - # Groups based on firmware - GROUPS["pc"] = [ "i386_pc" ] - GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", -- "riscv32_efi", "riscv64_efi" ] -+ "riscv32_efi", "riscv64_efi", "loongarch64_efi" ] - GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] - GROUPS["uboot"] = [ "arm_uboot" ] - GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] -@@ -80,7 +82,8 @@ GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; - for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) - - # Flattened Device Trees (FDT) --GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", "riscv64_efi" ] -+GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", -+ "riscv64_efi", "loongarch64_efi" ] - - # Needs software helpers for division - # Must match GRUB_DIVISION_IN_SOFTWARE in misc.h -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index dd49939..6582f16 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -240,6 +240,12 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h - KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h - endif - -+if COND_loongarch64_efi -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -+endif -+ - if COND_powerpc_ieee1275 - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 6b00eb5..016d345 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -103,6 +103,9 @@ kernel = { - arm_coreboot_ldflags = '-Wl,-r,-d'; - arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - -+ loongarch64_efi_ldflags = '-Wl,-r,-d'; -+ loongarch64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; -+ - i386_pc_startup = kern/i386/pc/startup.S; - i386_efi_startup = kern/i386/efi/startup.S; - x86_64_efi_startup = kern/x86_64/efi/startup.S; -@@ -122,6 +125,7 @@ kernel = { - arm64_efi_startup = kern/arm64/efi/startup.S; - riscv32_efi_startup = kern/riscv/efi/startup.S; - riscv64_efi_startup = kern/riscv/efi/startup.S; -+ loongarch64_efi_startup = kern/loongarch64/efi/startup.S; - - common = kern/buffer.c; - common = kern/command.c; -@@ -270,6 +274,9 @@ kernel = { - riscv64_efi = kern/riscv/efi/init.c; - riscv64_efi = kern/efi/fdt.c; - -+ loongarch64_efi = kern/loongarch64/efi/init.c; -+ loongarch64_efi = kern/efi/fdt.c; -+ - i386_pc = kern/i386/pc/init.c; - i386_pc = kern/i386/pc/mmap.c; - i386_pc = term/i386/pc/console.c; -@@ -351,6 +358,12 @@ kernel = { - riscv64 = kern/riscv/cache_flush.S; - riscv64 = kern/riscv/dl.c; - -+ loongarch64 = kern/loongarch64/init.c; -+ loongarch64 = kern/loongarch64/dl.c; -+ loongarch64 = kern/loongarch64/dl_helper.c; -+ loongarch64 = kern/loongarch64/cache.S; -+ loongarch64 = kern/generic/rtc_get_time_ms.c; -+ - fdt = lib/fdt.c; - - emu = disk/host.c; -@@ -864,6 +877,7 @@ module = { - enable = arm_coreboot; - enable = riscv32_efi; - enable = riscv64_efi; -+ enable = loongarch64_efi; - }; - - module = { -@@ -941,6 +955,7 @@ module = { - i386_multiboot = commands/acpihalt.c; - i386_efi = commands/acpihalt.c; - x86_64_efi = commands/acpihalt.c; -+ loongarch64_efi = commands/acpihalt.c; - i386_multiboot = lib/i386/halt.c; - i386_coreboot = lib/i386/halt.c; - i386_qemu = lib/i386/halt.c; -@@ -1715,6 +1730,8 @@ module = { - x86_64_xen = lib/x86_64/xen/relocator.S; - xen = lib/i386/relocator_common_c.c; - x86_64_efi = lib/x86_64/efi/relocator.c; -+ loongarch64 = lib/loongarch64/relocator_asm.S; -+ loongarch64 = lib/loongarch64/relocator.c; - - extra_dist = lib/i386/relocator_common.S; - extra_dist = kern/powerpc/cache_flush.S; -@@ -1724,6 +1741,7 @@ module = { - enable = x86; - enable = i386_xen_pvh; - enable = xen; -+ enable = loongarch64; - }; - - module = { -@@ -1756,6 +1774,7 @@ module = { - extra_dist = lib/arm/setjmp.S; - extra_dist = lib/arm64/setjmp.S; - extra_dist = lib/riscv/setjmp.S; -+ extra_dist = lib/loongarch64/setjmp.S; - }; - - module = { -@@ -1854,6 +1873,9 @@ module = { - arm64 = loader/arm64/linux.c; - riscv32 = loader/riscv/linux.c; - riscv64 = loader/riscv/linux.c; -+ loongarch64 = loader/loongarch64/linux.c; -+ loongarch64 = loader/loongarch64/linux-elf.c; -+ loongarch64 = loader/loongarch64/linux-efi.c; - emu = loader/emu/linux.c; - - common = loader/linux.c; -@@ -1953,6 +1975,7 @@ module = { - enable = riscv32_efi; - enable = riscv64_efi; - enable = mips; -+ enable = loongarch64_efi; - }; - - module = { -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index f304494..8c82ea1 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -278,7 +278,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - unsigned i; - const Elf_Shdr *s; - grub_size_t tsize = 0, talign = 1; --#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ -+ !defined(__loongarch__) - grub_size_t tramp; - grub_size_t got; - grub_err_t err; -@@ -294,7 +295,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - talign = s->sh_addralign; - } - --#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ -+ !defined(__loongarch__) - err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got); - if (err) - return err; -@@ -357,7 +359,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - mod->segment = seg; - } - } --#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ -+ !defined(__loongarch__) - ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); - mod->tramp = ptr; - mod->trampptr = ptr; -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 8553fcd..9d723a9 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -699,7 +699,8 @@ grub_efi_mm_init (void) - 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); - } - --#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) -+#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) \ -+ || defined (__loongarch__) - grub_err_t - grub_efi_get_ram_base(grub_addr_t *base_addr) - { -diff --git a/grub-core/kern/loongarch64/cache.S b/grub-core/kern/loongarch64/cache.S -new file mode 100644 -index 0000000..d291c67 ---- /dev/null -+++ b/grub-core/kern/loongarch64/cache.S -@@ -0,0 +1,26 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+ -+FUNCTION (grub_arch_sync_caches) -+ jr $ra -+ -+FUNCTION (grub_arch_sync_dma_caches) -+ jr $ra -+ -diff --git a/grub-core/kern/loongarch64/dl.c b/grub-core/kern/loongarch64/dl.c -new file mode 100644 -index 0000000..47196a2 ---- /dev/null -+++ b/grub-core/kern/loongarch64/dl.c -@@ -0,0 +1,150 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Check if EHDR is a valid ELF header. */ -+grub_err_t -+grub_arch_dl_check_header (void *ehdr) -+{ -+ Elf_Ehdr *e = ehdr; -+ -+ /* Check the magic numbers. */ -+ if (e->e_ident[EI_CLASS] != ELFCLASS64 -+ || e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_LOONGARCH) -+ return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); -+ -+ return GRUB_ERR_NONE; -+} -+ -+#pragma GCC diagnostic ignored "-Wcast-align" -+ -+/* -+ * Unified function for both REL and RELA. -+ */ -+grub_err_t -+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, -+ Elf_Shdr *s, grub_dl_segment_t seg) -+{ -+ Elf_Rel *rel, *max; -+ struct grub_loongarch64_stack stack; -+ grub_loongarch64_stack_init (&stack); -+ -+ for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), -+ max = (Elf_Rel *) ((char *) rel + s->sh_size); -+ rel < max; -+ rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) -+ { -+ Elf_Sym *sym; -+ void *place; -+ grub_uint64_t sym_addr; -+ -+ if (rel->r_offset >= seg->size) -+ return grub_error (GRUB_ERR_BAD_MODULE, -+ "reloc offset is outside the segment"); -+ -+ sym = (Elf_Sym *) ((char*)mod->symtab -+ + mod->symsize * ELF_R_SYM (rel->r_info)); -+ -+ sym_addr = sym->st_value; -+ if (s->sh_type == SHT_RELA) -+ sym_addr += ((Elf_Rela *) rel)->r_addend; -+ -+ place = (void *) ((grub_addr_t)seg->addr + rel->r_offset); -+ -+ switch (ELF_R_TYPE (rel->r_info)) -+ { -+ case R_LARCH_64: -+ { -+ grub_uint64_t *abs_place = place; -+ -+ grub_dprintf ("dl", "reloc_abs64 %p => 0x%016llx, %p\n", -+ place, (unsigned long long) sym_addr, abs_place); -+ -+ *abs_place += (grub_uint64_t) sym_addr; -+ } -+ break; -+ case R_LARCH_MARK_LA: -+ break; -+ case R_LARCH_SOP_PUSH_PCREL: -+ case R_LARCH_SOP_PUSH_PLT_PCREL: -+ grub_loongarch64_sop_push (&stack, sym_addr - (grub_uint64_t)place); -+ break; -+ case R_LARCH_B26: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_ssize_t off = sym_addr - (grub_addr_t) place; -+ -+ grub_loongarch64_b26 (abs_place, off); -+ } -+ break; -+ case R_LARCH_ABS_HI20: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_loongarch64_xxx_hi20 (abs_place, sym_addr); -+ } -+ break; -+ case R_LARCH_ABS64_LO20: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_loongarch64_xxx64_lo20 (abs_place, sym_addr); -+ } -+ break; -+ case R_LARCH_ABS64_HI12: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_loongarch64_xxx64_hi12 (abs_place, sym_addr); -+ } -+ break; -+ case R_LARCH_PCALA_HI20: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_int32_t off = (((sym_addr + 0x800) & ~0xfffULL) - ((grub_addr_t)place & ~0xfffULL)); -+ -+ grub_loongarch64_xxx_hi20 (abs_place, off); -+ } -+ break; -+ case R_LARCH_ABS_LO12: -+ case R_LARCH_PCALA_LO12: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_loongarch64_xxx_lo12 (abs_place, sym_addr); -+ } -+ break; -+ GRUB_LOONGARCH64_RELOCATION (&stack, place, sym_addr) -+ default: -+ { -+ char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ -+ -+ grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, -+ (grub_uint64_t) ELF_R_TYPE (rel->r_info)); -+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ N_("relocation 0x%s is not implemented yet"), rel_info); -+ } -+ break; -+ } -+ } -+ return GRUB_ERR_NONE; -+} -diff --git a/grub-core/kern/loongarch64/dl_helper.c b/grub-core/kern/loongarch64/dl_helper.c -new file mode 100644 -index 0000000..68275fe ---- /dev/null -+++ b/grub-core/kern/loongarch64/dl_helper.c -@@ -0,0 +1,264 @@ -+/* dl_helper.c - relocation helper functions for modules and grub-mkimage */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static void grub_loongarch64_stack_push (grub_loongarch64_stack_t stack, grub_uint64_t x); -+static grub_uint64_t grub_loongarch64_stack_pop (grub_loongarch64_stack_t stack); -+ -+void -+grub_loongarch64_stack_init (grub_loongarch64_stack_t stack) -+{ -+ stack->top = -1; -+ stack->count = LOONGARCH64_STACK_MAX; -+} -+ -+static void -+grub_loongarch64_stack_push (grub_loongarch64_stack_t stack, grub_uint64_t x) -+{ -+ if (stack->top == stack->count) -+ return; -+ stack->data[++stack->top] = x; -+} -+ -+static grub_uint64_t -+grub_loongarch64_stack_pop (grub_loongarch64_stack_t stack) -+{ -+ if (stack->top == -1) -+ return -1; -+ return stack->data[stack->top--]; -+} -+ -+void -+grub_loongarch64_sop_push (grub_loongarch64_stack_t stack, grub_int64_t offset) -+{ -+ grub_loongarch64_stack_push (stack, offset); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 - opr2) */ -+void -+grub_loongarch64_sop_sub (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a - b); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 << opr2) */ -+void -+grub_loongarch64_sop_sl (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a << b); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 >> opr2) */ -+void -+grub_loongarch64_sop_sr (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a >> b); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 + opr2) */ -+void -+grub_loongarch64_sop_add (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a + b); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 & opr2) */ -+void -+grub_loongarch64_sop_and (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a & b); -+} -+ -+/* opr3 = pop (), opr2 = pop (), opr1 = pop (), push (opr1 ? opr2 : opr3) */ -+void -+grub_loongarch64_sop_if_else (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b, c; -+ c = grub_loongarch64_stack_pop (stack); -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ -+ if (a) { -+ grub_loongarch64_stack_push (stack, b); -+ } else { -+ grub_loongarch64_stack_push (stack, c); -+ } -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [14 ... 10] = opr1 [4 ... 0] */ -+void -+grub_loongarch64_sop_32_s_10_5 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place |= ((a & 0x1f) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [21 ... 10] = opr1 [11 ... 0] */ -+void -+grub_loongarch64_sop_32_u_10_12 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = *place | ((a & 0xfff) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [21 ... 10] = opr1 [11 ... 0] */ -+void -+grub_loongarch64_sop_32_s_10_12 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = (*place) | ((a & 0xfff) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [25 ... 10] = opr1 [15 ... 0] */ -+void -+grub_loongarch64_sop_32_s_10_16 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = (*place) | ((a & 0xffff) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [25 ... 10] = opr1 [17 ... 2] */ -+void -+grub_loongarch64_sop_32_s_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = (*place) | (((a >> 2) & 0xffff) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [24 ... 5] = opr1 [19 ... 0] */ -+void -+grub_loongarch64_sop_32_s_5_20 (grub_loongarch64_stack_t stack, grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = (*place) | ((a & 0xfffff)<<5); -+} -+ -+/* opr1 = pop (), -+ (*(uint32_t *) PC) [4 ... 0] = opr1 [22 ... 18] -+ (*(uint32_t *) PC) [25 ...10] = opr1 [17 ... 2] -+ */ -+void -+grub_loongarch64_sop_32_s_0_5_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ -+ *place =(*place) | (((a >> 2) & 0xffff) << 10); -+ *place =(*place) | ((a >> 18) & 0x1f); -+} -+ -+/* -+ opr1 = pop () -+ (*(uint32_t *) PC) [9 ... 0] = opr1 [27 ... 18], -+ (*(uint32_t *) PC) [25 ... 10] = opr1 [17 ... 2] -+*/ -+void -+grub_loongarch64_sop_32_s_0_10_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place =(*place) | (((a >> 2) & 0xffff) << 10); -+ *place =(*place) | ((a >> 18) & 0x3ff); -+} -+ -+void grub_loongarch64_b26 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ grub_uint32_t val; -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfc000000); -+ -+ grub_dprintf ("dl", " reloc_xxxx64 %p %c= 0x%llx\n", -+ place, offset > 0 ? '+' : '-', -+ offset < 0 ? (long long) -(unsigned long long) offset : offset); -+ -+ val = ((offset >> 18) & 0x3ff) | (((offset >> 2) & 0xffff) << 10); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (val) & ~insmask; -+} -+ -+void grub_loongarch64_xxx_hi20 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfe00001f); -+ grub_uint32_t val; -+ -+ offset >>= 12; -+ val = ((offset & 0xfffff) << 5); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (val) & ~insmask; -+} -+ -+void grub_loongarch64_xxx_lo12 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (offset << 10) & ~insmask; -+} -+ -+void grub_loongarch64_xxx64_hi12 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff); -+ grub_uint32_t val; -+ -+ offset >>= 52; -+ val = ((offset & 0xfff) << 10); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (val) & ~insmask; -+} -+ -+void grub_loongarch64_xxx64_lo20 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfe00001f); -+ grub_uint32_t val; -+ -+ offset >>= 32; -+ val = ((offset & 0xfffff) << 5); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (val) & ~insmask; -+} -diff --git a/grub-core/kern/loongarch64/efi/init.c b/grub-core/kern/loongarch64/efi/init.c -new file mode 100644 -index 0000000..7f7c866 ---- /dev/null -+++ b/grub-core/kern/loongarch64/efi/init.c -@@ -0,0 +1,73 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2013 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static grub_uint64_t tmr; -+static grub_efi_event_t tmr_evt; -+ -+static grub_uint64_t -+grub_efi_get_time_ms (void) -+{ -+ return tmr; -+} -+ -+static void -+grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)), -+ void *context __attribute__ ((unused))) -+{ -+ tmr += 10; -+} -+ -+void -+grub_machine_init (void) -+{ -+ grub_efi_boot_services_t *b; -+ -+ grub_efi_init (); -+ -+ b = grub_efi_system_table->boot_services; -+ efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, -+ GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); -+ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000); -+ -+ grub_install_get_time_ms (grub_efi_get_time_ms); -+} -+ -+void -+grub_machine_fini (int flags) -+{ -+ grub_efi_boot_services_t *b; -+ -+ if (!(flags & GRUB_LOADER_FLAG_NORETURN)) -+ return; -+ -+ b = grub_efi_system_table->boot_services; -+ -+ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); -+ efi_call_1 (b->close_event, tmr_evt); -+ -+ grub_efi_fini (); -+} -diff --git a/grub-core/kern/loongarch64/efi/startup.S b/grub-core/kern/loongarch64/efi/startup.S -new file mode 100644 -index 0000000..1ffff08 ---- /dev/null -+++ b/grub-core/kern/loongarch64/efi/startup.S -@@ -0,0 +1,45 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2013 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+ -+ .file "startup.S" -+ .text -+ .globl start, _start -+ .align 4 -+ -+FUNCTION(start) -+FUNCTION(_start) -+ /* -+ * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. -+ */ -+ addi.d $sp, $sp, -16 -+ st.d $ra, $sp, 0 -+ -+ la $a2, grub_efi_image_handle -+ st.d $a0, $a2, 0 -+ la $a2, grub_efi_system_table -+ st.d $a1, $a2, 0 -+ -+ bl grub_main -+ -+1: -+ ld.d $ra, $sp, 0 -+ addi.d $sp, $sp, 16 -+ jr $ra -+ -diff --git a/grub-core/kern/loongarch64/init.c b/grub-core/kern/loongarch64/init.c -new file mode 100644 -index 0000000..b2de930 ---- /dev/null -+++ b/grub-core/kern/loongarch64/init.c -@@ -0,0 +1,47 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+grub_uint32_t grub_arch_cpuclock; -+ -+/* FIXME: use interrupt to count high. */ -+grub_uint64_t -+grub_get_rtc (void) -+{ -+ static grub_uint32_t high = 0; -+ static grub_uint32_t last = 0; -+ grub_uint32_t low; -+ -+ asm volatile ("csrrd %0, " GRUB_CPU_LOONGARCH_COP0_TIMER_COUNT : "=r" (low)); -+ if (low < last) -+ high++; -+ last = low; -+ -+ return (((grub_uint64_t) high) << 32) | low; -+} -+ -+void -+grub_timer_init (grub_uint32_t cpuclock) -+{ -+ grub_arch_cpuclock = cpuclock; -+ grub_install_get_time_ms (grub_rtc_get_time_ms); -+} -diff --git a/grub-core/lib/gnulib-patches/fix-loongarch.patch b/grub-core/lib/gnulib-patches/fix-loongarch.patch -new file mode 100644 -index 0000000..fa0b09a ---- /dev/null -+++ b/grub-core/lib/gnulib-patches/fix-loongarch.patch -@@ -0,0 +1,26 @@ -+diff --git a/build-aux/config.guess b/build-aux/config.guess -+index 8e2a58b..927581d 100755 -+--- a/build-aux/config.guess -++++ b/build-aux/config.guess -+@@ -990,6 +990,9 @@ EOF -+ k1om:Linux:*:*) -+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" -+ exit ;; -++ loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) -++ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" -++ exit ;; -+ m32r*:Linux:*:*) -+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" -+ exit ;; -+diff --git a/build-aux/config.sub b/build-aux/config.sub -+index 1fc4cde..6303428 100755 -+--- a/build-aux/config.sub -++++ b/build-aux/config.sub -+@@ -1184,6 +1184,7 @@ case $cpu-$vendor in -+ | k1om \ -+ | le32 | le64 \ -+ | lm32 \ -++ | loongarch32 | loongarch64 | loongarchx32 \ -+ | m32c | m32r | m32rle \ -+ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k | v70 | w65 \ -+ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip \ -diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c -new file mode 100644 -index 0000000..faa4553 ---- /dev/null -+++ b/grub-core/lib/loongarch64/relocator.c -@@ -0,0 +1,163 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+extern grub_uint8_t grub_relocator_forward_start; -+extern grub_uint8_t grub_relocator_forward_end; -+extern grub_uint8_t grub_relocator_backward_start; -+extern grub_uint8_t grub_relocator_backward_end; -+ -+#define REGW_SIZEOF (4 * sizeof (grub_uint32_t)) -+#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) -+ -+#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ -+ - &grub_relocator_##x##_start) -+#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ -+ + REGW_SIZEOF * 3) -+grub_size_t grub_relocator_align = sizeof (grub_uint64_t); -+grub_size_t grub_relocator_forward_size; -+grub_size_t grub_relocator_backward_size; -+grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; -+ -+void -+grub_cpu_relocator_init (void) -+{ -+ grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); -+ grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); -+} -+ -+static void -+write_reg (int regn, grub_uint64_t val, void **target) -+{ -+ grub_uint32_t lu12iw=0x14000000; -+ grub_uint32_t ori=0x03800000; -+ grub_uint32_t lu32id=0x16000000; -+ grub_uint32_t lu52id=0x03000000; -+ -+ *(grub_uint32_t *) *target = (lu12iw | (grub_uint32_t)((val & 0xfffff000)>>12<<5) | (grub_uint32_t)regn);; -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (ori | (grub_uint32_t)((val & 0xfff)<<10) | (grub_uint32_t)(regn | regn<<5)); -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (lu32id | (grub_uint32_t)((val & 0xfffff00000000)>>32<<5) | (grub_uint32_t)regn);; -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (lu52id | (grub_uint32_t)((val & 0xfff0000000000000)>>52<<10) | (grub_uint32_t)(regn | regn<<5));; -+ *target = ((grub_uint32_t *) *target) + 1; -+} -+ -+static void -+write_jump (int regn, void **target) -+{ -+ grub_uint32_t jirl=0x4c000000; -+ -+ *(grub_uint32_t *) *target = (jirl | (grub_uint32_t)(regn<<5)); -+ *target = ((grub_uint32_t *) *target) + 1; -+} -+ -+void -+grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) -+{ -+ write_reg (1, addr, &rels); -+ write_jump (1, &rels); -+} -+ -+void -+grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, -+ grub_size_t size) -+{ -+ void *ptr = ptr0; -+ write_reg (8, (grub_uint64_t) src, &ptr); -+ write_reg (9, (grub_uint64_t) dest, &ptr); -+ write_reg (10, (grub_uint64_t) size, &ptr); -+ grub_memcpy (ptr, &grub_relocator_backward_start, -+ RELOCATOR_SRC_SIZEOF (backward)); -+} -+ -+void -+grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, -+ grub_size_t size) -+{ -+ void *ptr = ptr0; -+ write_reg (8, (grub_uint64_t) src, &ptr); -+ write_reg (9, (grub_uint64_t) dest, &ptr); -+ write_reg (10, (grub_uint64_t) size, &ptr); -+ grub_memcpy (ptr, &grub_relocator_forward_start, -+ RELOCATOR_SRC_SIZEOF (forward)); -+} -+ -+grub_err_t -+grub_relocator64_boot (struct grub_relocator *rel, -+ struct grub_relocator64_state state) -+{ -+ grub_relocator_chunk_t ch; -+ void *ptr; -+ grub_err_t err; -+ void *relst; -+ grub_size_t relsize; -+ grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF; -+ unsigned i; -+ grub_addr_t vtarget; -+ -+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, -+ (0xffffffff - stateset_size) -+ + 1, stateset_size, -+ grub_relocator_align, -+ GRUB_RELOCATOR_PREFERENCE_NONE, 0); -+ if (err) -+ return err; -+ -+ ptr = get_virtual_current_address (ch); -+ for (i = 1; i < 32; i++) -+ write_reg (i, state.gpr[i], &ptr); -+ write_jump (state.jumpreg, &ptr); -+ -+ vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch), -+ stateset_size); -+ -+ err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize); -+ if (err) -+ return err; -+ -+ grub_arch_sync_caches ((void *) relst, relsize); -+ -+ asm volatile ( -+ "ibar 0 \n"); -+ -+ grub_uint64_t val; -+ __asm__ __volatile__( -+ "li.w %0, 0x4\n\t" -+ "csrxchg $r0, %0, 0x0\n\t" -+ : "=r"(val) -+ : -+ : -+ ); -+ -+ ((void (*) (void)) relst) (); -+ -+ /* Not reached. */ -+ return GRUB_ERR_NONE; -+} -diff --git a/grub-core/lib/loongarch64/relocator_asm.S b/grub-core/lib/loongarch64/relocator_asm.S -new file mode 100644 -index 0000000..ffdccc9 ---- /dev/null -+++ b/grub-core/lib/loongarch64/relocator_asm.S -@@ -0,0 +1,51 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+ -+ .p2align 4 /* force 16-byte alignment */ -+ -+VARIABLE (grub_relocator_forward_start) -+ -+copycont1: -+ ld.d $r11,$r8,0 -+ st.d $r11,$r9,0 -+ addi.d $r8, $r8, 8 -+ addi.d $r10, $r10, -8 -+ addi.d $r9, $r9, 8 -+ bne $r10, $r0, copycont1 -+ -+VARIABLE (grub_relocator_forward_end) -+ -+VARIABLE (grub_relocator_backward_start) -+ -+ add.d $r9, $r9, $r10 -+ add.d $r8, $r8, $r10 -+ /* Backward movsl is implicitly off-by-one. compensate that. */ -+ addi.d $r9, $r9, -8 -+ addi.d $r8, $r8, -8 -+copycont2: -+ ld.w $r11,$r8,0 -+ st.w $r11,$r9,0 -+ addi.d $r8, $r8, -8 -+ addi.d $r10, $r10, -8 -+ addi.d $r9, $r9, -8 -+ bne $r10, $r0, copycont2 -+ -+VARIABLE (grub_relocator_backward_end) -+ -diff --git a/grub-core/lib/loongarch64/setjmp.S b/grub-core/lib/loongarch64/setjmp.S -new file mode 100644 -index 0000000..bb09959 ---- /dev/null -+++ b/grub-core/lib/loongarch64/setjmp.S -@@ -0,0 +1,68 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+ -+ .file "setjmp.S" -+ -+GRUB_MOD_LICENSE "GPLv3+" -+ -+ .text -+ -+/* -+ * int grub_setjmp (jmp_buf env) -+ */ -+FUNCTION(grub_setjmp) -+ st.d $s0, $a0, 0x0 -+ st.d $s1, $a0, 0x8 -+ st.d $s2, $a0, 0x10 -+ st.d $s3, $a0, 0x18 -+ st.d $s4, $a0, 0x20 -+ st.d $s5, $a0, 0x28 -+ st.d $s6, $a0, 0x30 -+ st.d $s7, $a0, 0x38 -+ st.d $s8, $a0, 0x40 -+ st.d $fp, $a0, 0x48 -+ st.d $sp, $a0, 0x50 -+ st.d $ra, $a0, 0x58 -+ -+ move $a0, $zero -+ jr $ra -+ -+/* -+ * void grub_longjmp (jmp_buf env, int val) -+ */ -+FUNCTION(grub_longjmp) -+ ld.d $s0, $a0, 0x0 -+ ld.d $s1, $a0, 0x8 -+ ld.d $s2, $a0, 0x10 -+ ld.d $s3, $a0, 0x18 -+ ld.d $s4, $a0, 0x20 -+ ld.d $s5, $a0, 0x28 -+ ld.d $s6, $a0, 0x30 -+ ld.d $s7, $a0, 0x38 -+ ld.d $s8, $a0, 0x40 -+ ld.d $fp, $a0, 0x48 -+ ld.d $sp, $a0, 0x50 -+ ld.d $ra, $a0, 0x58 -+ -+ li.w $a0, 1 -+ beqz $a1, .L0 -+ move $a0, $a1 -+.L0: -+ jr $ra -diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S -index aa297ab..da71fc7 100644 ---- a/grub-core/lib/setjmp.S -+++ b/grub-core/lib/setjmp.S -@@ -15,6 +15,8 @@ - #include "./arm/setjmp.S" - #elif defined(__aarch64__) - #include "./arm64/setjmp.S" -+#elif defined(__loongarch64) -+#include "./loongarch64/setjmp.S" - #elif defined(__riscv) - #include "./riscv/setjmp.S" - #else -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index fb874f1..faf60ef 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -345,6 +345,8 @@ static const grub_uint16_t machine_type __attribute__((__unused__)) = - GRUB_PE32_MACHINE_I386; - #elif defined(__ia64__) - GRUB_PE32_MACHINE_IA64; -+#elif defined(__loongarch64) -+ GRUB_PE32_MACHINE_LOONGARCH64; - #elif defined(__riscv) && (__riscv_xlen == 32) - GRUB_PE32_MACHINE_RISCV32; - #elif defined(__riscv) && (__riscv_xlen == 64) -diff --git a/grub-core/loader/loongarch64/linux-efi.c b/grub-core/loader/loongarch64/linux-efi.c -new file mode 100644 -index 0000000..4dcefd9 ---- /dev/null -+++ b/grub-core/loader/loongarch64/linux-efi.c -@@ -0,0 +1,144 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define GRUB_EFI_PE_MAGIC 0x5A4D -+ -+grub_err_t -+finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params) -+{ -+ int node, retval; -+ -+ void *fdt; -+ -+ fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE); -+ -+ if (!fdt) -+ goto failure; -+ -+ node = grub_fdt_find_subnode (fdt, 0, "chosen"); -+ if (node < 0) -+ node = grub_fdt_add_subnode (fdt, 0, "chosen"); -+ -+ if (node < 1) -+ goto failure; -+ -+ /* Set initrd info */ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ grub_dprintf ("linux", "Initrd @ %p-%p\n", -+ (void *) kernel_params->ramdisk_addr, -+ (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -+ -+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", -+ kernel_params->ramdisk_addr); -+ if (retval) -+ goto failure; -+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", -+ kernel_params->ramdisk_addr + kernel_params->ramdisk_size); -+ if (retval) -+ goto failure; -+ } -+ -+ if (grub_fdt_install() != GRUB_ERR_NONE) -+ goto failure; -+ -+ return GRUB_ERR_NONE; -+ -+failure: -+ grub_fdt_unload(); -+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+} -+ -+grub_err_t -+grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) -+{ -+ if ((lh->code0 & 0xffff) == GRUB_EFI_PE_MAGIC) -+ return GRUB_ERR_NONE; -+ else -+ return 1; -+ -+ grub_dprintf ("linux", "UEFI stub kernel:\n"); -+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset); -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_err_t -+grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) -+{ -+ grub_efi_memory_mapped_device_path_t *mempath; -+ grub_efi_handle_t image_handle; -+ grub_efi_boot_services_t *b; -+ grub_efi_status_t status; -+ grub_efi_loaded_image_t *loaded_image; -+ int len; -+ -+ mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); -+ if (!mempath) -+ return grub_errno; -+ -+ mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; -+ mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; -+ mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); -+ mempath[0].memory_type = GRUB_EFI_LOADER_DATA; -+ mempath[0].start_address = addr; -+ mempath[0].end_address = addr + size; -+ -+ mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ mempath[1].header.length = sizeof (grub_efi_device_path_t); -+ -+ b = grub_efi_system_table->boot_services; -+ status = b->load_image (0, grub_efi_image_handle, -+ (grub_efi_device_path_t *) mempath, -+ (void *) addr, size, &image_handle); -+ if (status != GRUB_EFI_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); -+ -+ grub_dprintf ("linux", "linux command line: '%s'\n", args); -+ -+ /* Convert command line to UCS-2 */ -+ loaded_image = grub_efi_get_loaded_image (image_handle); -+ loaded_image->load_options_size = len = -+ (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); -+ loaded_image->load_options = -+ grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); -+ if (!loaded_image->load_options) -+ return grub_errno; -+ -+ loaded_image->load_options_size = -+ 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, -+ (grub_uint8_t *) args, len, NULL); -+ -+ grub_dprintf ("linux", "starting image %p\n", image_handle); -+ status = b->start_image (image_handle, 0, NULL); -+ -+ /* When successful, not reached */ -+ b->unload_image (image_handle); -+ grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, -+ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); -+ -+ return grub_errno; -+} -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -new file mode 100644 -index 0000000..85585b4 ---- /dev/null -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -0,0 +1,529 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define GRUB_ADDRESS_TYPE_SYSRAM 1 -+#define GRUB_ADDRESS_TYPE_RESERVED 2 -+#define GRUB_ADDRESS_TYPE_ACPI 3 -+#define GRUB_ADDRESS_TYPE_NVS 4 -+#define GRUB_ADDRESS_TYPE_PMEM 5 -+#define GRUB_EFI_LOONGSON_BPI_TABLE_GUID \ -+ { 0x4660f721, 0x2ec5, 0x416a, \ -+ { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ -+ } -+ -+static struct grub_relocator *relocator; -+ -+void grub_linux_loongarch_elf_relocator_unload (void) -+{ -+ grub_relocator_unload (relocator); -+} -+ -+static grub_err_t -+allocate_fdt_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) -+{ -+ int node, retval; -+ grub_err_t err; -+ unsigned int size; -+ grub_efi_uintn_t mmap_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_uint32_t desc_version; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ -+ size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA + GRUB_EFI_LINUX_FDT_EXTRA_SPACE; -+ -+ kernel_params->fdt = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (size)); -+ if (!kernel_params->fdt) -+ return GRUB_ERR_OUT_OF_MEMORY; -+ -+ grub_fdt_create_empty_tree (kernel_params->fdt, size); -+ grub_fdt_set_prop32 (kernel_params->fdt, 0, FDT_ADDR_CELLS_STRING, 2); -+ grub_fdt_set_prop32 (kernel_params->fdt, 0, FDT_SIZE_CELLS_STRING, 2); -+ -+ node = grub_fdt_find_subnode (kernel_params->fdt, 0, "chosen"); -+ if (node < 0) -+ node = grub_fdt_add_subnode (kernel_params->fdt, 0, "chosen"); -+ if (node < 1) -+ goto failure; -+ -+ grub_dprintf ("loongson", "command_line %s, len %ld\n", -+ (char *)kernel_params->linux_args, -+ grub_strlen(kernel_params->linux_args) + 1); -+ if ((kernel_params->linux_args != NULL) && (grub_strlen(kernel_params->linux_args) > 0)) { -+ retval = grub_fdt_set_prop (kernel_params->fdt, node, "bootargs", kernel_params->linux_args, -+ grub_strlen(kernel_params->linux_args) + 1); -+ if (retval) -+ goto failure; -+ } -+ -+ /* Set initrd info */ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ grub_dprintf ("linux", "Initrd @ %p-%p\n", -+ (void *) kernel_params->ramdisk_addr, -+ (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -+ -+ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,initrd-start", -+ kernel_params->ramdisk_addr); -+ if (retval) -+ goto failure; -+ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,initrd-end", -+ (grub_uint64_t) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -+ if (retval) -+ goto failure; -+ } -+ -+ node = grub_fdt_find_subnode (kernel_params->fdt, 0, "chosen"); -+ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,uefi-system-table", -+ (grub_uint64_t)grub_efi_system_table); -+ if (retval) -+ goto failure; -+ -+ mmap_size = grub_efi_find_mmap_size (); -+ if (! mmap_size) -+ return grub_errno; -+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ if (! mmap_buf) -+ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, &desc_version); -+ if (err) -+ return err; -+ -+ if (!mmap_buf || !mmap_size || !desc_size) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,uefi-mmap-start", -+ (grub_uint64_t)mmap_buf); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-size", -+ mmap_size); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-desc-size", -+ desc_size); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-desc-ver", -+ desc_version); -+ if (retval) -+ goto failure; -+ -+ return GRUB_ERR_NONE; -+ -+failure: -+ if (!kernel_params->fdt) { -+ return GRUB_ERR_BAD_OS; -+ } -+ grub_efi_free_pages ((grub_addr_t) kernel_params->fdt, -+ GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (kernel_params->fdt))); -+ kernel_params->fdt = NULL; -+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+} -+ -+static void -+grub_linux_loongarch_elf_make_argv (struct linux_loongarch64_kernel_params *kernel_params) -+{ -+ static void* linux_args_addr; -+ int size; -+ grub_uint64_t *linux_argv; -+ char *args, *p, *linux_args; -+ int i, argc; -+ grub_err_t err; -+ -+ argc = kernel_params->linux_argc; -+ args = kernel_params->linux_args; -+ -+ /* new size */ -+ p = args; -+ size = (argc + 3 + 1) * sizeof (grub_uint64_t); /* orig arguments */ -+ for (i = 0; i < argc; i++) -+ { -+ size += ALIGN_UP (grub_strlen (p) + 1, 4); -+ p += grub_strlen (p) + 1; -+ } -+ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4) \ -+ + ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4) \ -+ + ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -+ 4); -+ } -+ size = ALIGN_UP (size, 8); -+ -+ /* alloc memory */ -+ linux_args_addr = grub_linux_loongarch_alloc_virtual_mem_align (size, 8, &err); -+ -+ linux_argv = linux_args_addr; -+ linux_args = (char *)(linux_argv + (argc + 1 + 3)); -+ p = args; -+ for (i = 0; i < argc; i++) -+ { -+ grub_memcpy (linux_args, p, grub_strlen (p) + 1); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (grub_strlen (p) + 1, 4); -+ p += grub_strlen (p) + 1; -+ } -+ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ /* rd_start */ -+ grub_snprintf (linux_args, -+ sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), -+ "rd_start=0x%lx", -+ (grub_uint64_t) kernel_params->ramdisk_addr); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); -+ kernel_params->linux_argc++; -+ -+ /* rd_size */ -+ grub_snprintf (linux_args, -+ sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), -+ "rd_size=0x%lx", -+ (grub_uint64_t) kernel_params->ramdisk_size); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); -+ kernel_params->linux_argc++; -+ -+ /* initrd */ -+ grub_snprintf (linux_args, -+ sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -+ "initrd=0x%lx,0x%lx", -+ ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), -+ (grub_uint64_t) kernel_params->ramdisk_size); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); -+ kernel_params->linux_argc++; -+ } -+ -+ /* Reserve space for initrd arguments. */ -+ *linux_argv = 0; -+ -+ grub_free (kernel_params->linux_args); -+ kernel_params->linux_argv = (grub_addr_t) linux_args_addr; -+} -+ -+grub_err_t -+grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_params -+ *kernel_params) -+{ -+ struct boot_params_interface *boot_params = NULL; -+ struct grub_relocator64_state state; -+ grub_err_t err; -+ -+ /* linux kernel type is ELF */ -+ grub_memset (&state, 0, sizeof (state)); -+ -+ state.jumpreg = 1; -+ state.gpr[1] = kernel_params->kernel_addr; /* ra */ -+ if (grub_linux_loongarch_elf_get_boot_params (&boot_params) == 0) -+ { -+ grub_printf("not find param, is fdt boot\n"); -+ if (allocate_fdt_and_exit_boot (kernel_params) != GRUB_ERR_NONE) -+ return grub_errno; -+ state.gpr[4] = 1 << FLAGS_EFI_SUPPORT_BIT; /* a0 = flag */ -+ state.gpr[5] = (grub_uint64_t)kernel_params->fdt; /* a1 = fdt */ -+ state.gpr[6] = 0; /* a2 = flag */ -+ } else { -+ grub_printf("find param, is bpi boot\n"); -+ grub_linux_loongarch_elf_make_argv (kernel_params); -+ state.gpr[4] = kernel_params->linux_argc; /* a0 = argc */ -+ state.gpr[5] = kernel_params->linux_argv; /* a1 = args */ -+ state.gpr[6] = (grub_uint64_t) boot_params; /* a2 = envp */ -+ err = grub_linux_loongarch_elf_boot_params (boot_params); -+ if (err) -+ return err; -+ } -+ -+ /* Boot the ELF kernel */ -+ grub_relocator64_boot (relocator, state); -+ -+ return GRUB_ERR_NONE; -+} -+ -+void* -+grub_linux_loongarch_alloc_virtual_mem_addr (grub_addr_t addr, -+ grub_size_t size, -+ grub_err_t *err) -+{ -+ relocator = grub_relocator_new (); -+ if (!relocator) -+ return NULL; -+ -+ grub_relocator_chunk_t ch; -+ *err = grub_relocator_alloc_chunk_addr (relocator, &ch, -+ grub_vtop ((void *) addr), -+ size); -+ if (*err) -+ return NULL; -+ return get_virtual_current_address (ch); -+} -+ -+void* -+grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, -+ grub_size_t align, -+ grub_err_t *err) -+{ -+ grub_relocator_chunk_t ch; -+ -+ *err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0, (0xffffffff - size) + 1, -+ size, align, -+ GRUB_RELOCATOR_PREFERENCE_LOW, 0); -+ return get_virtual_current_address (ch); -+} -+ -+int -+grub_linux_loongarch_elf_get_boot_params (struct boot_params_interface **boot_params) -+{ -+ grub_efi_configuration_table_t *tables; -+ grub_efi_guid_t bpi_guid = GRUB_EFI_LOONGSON_BPI_TABLE_GUID; -+ unsigned int i; -+ int found = 0; -+ -+ /* Look for Loongson BPI in UEFI config tables. */ -+ tables = grub_efi_system_table->configuration_table; -+ -+ for (i = 0; i < grub_efi_system_table->num_table_entries; i++) -+ if (grub_memcmp (&tables[i].vendor_guid, &bpi_guid, sizeof (bpi_guid)) == 0) -+ { -+ *boot_params = tables[i].vendor_table; -+ char *p = (char*) &((*boot_params)->signature); -+ if (grub_strncmp (p, "BPI", 3) == 0) -+ { -+ found = 1; -+ break; -+ } -+ } -+ return found; -+} -+ -+static grub_uint8_t -+grub_kernel_update_checksum (const grub_uint8_t *buffer, grub_efi_uintn_t length) -+{ -+ grub_uint8_t sum; -+ grub_efi_uintn_t count; -+ -+ for (sum = 0, count = 0; count < length; count++) -+ { -+ sum = (grub_uint8_t) (sum + *(buffer + count)); -+ } -+ -+ return (grub_uint8_t) (0x100 - sum); -+} -+ -+static grub_uint32_t -+grub_efi_loongarch64_memmap_sort (struct memmap array[], -+ grub_uint32_t length, -+ struct loongsonlist_mem_map* bpmem, -+ grub_uint32_t index, -+ grub_uint32_t memtype) -+{ -+ grub_uint64_t tempmemsize = 0; -+ grub_uint32_t j = 0; -+ grub_uint32_t t = 0; -+ -+ for(j = 0; j < length;) -+ { -+ tempmemsize = array[j].mem_size; -+ for(t = j + 1; t < length; t++) -+ { -+ if(array[j].mem_start + tempmemsize == array[t].mem_start) -+ { -+ tempmemsize += array[t].mem_size; -+ } -+ else -+ { -+ break; -+ } -+ } -+ bpmem->map[index].mem_type = memtype; -+ bpmem->map[index].mem_start = array[j].mem_start; -+ bpmem->map[index].mem_size = tempmemsize; -+ grub_printf("map[%d]:type %"PRIuGRUB_UINT32_T", start 0x%" -+ PRIxGRUB_UINT64_T", end 0x%"PRIxGRUB_UINT64_T"\n", -+ index, -+ bpmem->map[index].mem_type, -+ bpmem->map[index].mem_start, -+ bpmem->map[index].mem_start+ bpmem->map[index].mem_size -+ ); -+ j = t; -+ index++; -+ } -+ return index; -+} -+ -+grub_err_t -+grub_linux_loongarch_elf_boot_params (struct boot_params_interface *boot_params) -+{ -+ grub_int8_t checksum = 0; -+ grub_err_t err; -+ -+ struct loongsonlist_mem_map *loongson_mem_map = NULL; -+ struct _extention_list_hdr * listpointer = NULL; -+ grub_uint32_t tmp_index = 0; -+ grub_efi_memory_descriptor_t * lsdesc = NULL; -+ -+ grub_uint32_t free_index = 0; -+ grub_uint32_t reserve_index = 0; -+ grub_uint32_t acpi_table_index = 0; -+ grub_uint32_t acpi_nvs_index = 0; -+ -+ grub_efi_uintn_t mmap_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ -+ struct memmap reserve_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+ struct memmap free_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+ struct memmap acpi_table_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+ struct memmap acpi_nvs_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+ -+ grub_memset (reserve_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); -+ grub_memset (free_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); -+ grub_memset (acpi_table_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); -+ grub_memset (acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); -+ -+ /* Check extlist headers */ -+ listpointer = boot_params->extlist; -+ for( ;listpointer != NULL; listpointer = listpointer->next) -+ { -+ char *pl= (char *)&(listpointer->signature); -+ if(grub_strncmp(pl, "MEM", 3) == 0) -+ { -+ loongson_mem_map = (struct loongsonlist_mem_map *)listpointer; -+ break; -+ } -+ } -+ -+ mmap_size = grub_efi_find_mmap_size (); -+ if (! mmap_size) -+ return grub_errno; -+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ if (! mmap_buf) -+ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); -+ -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, NULL); -+ if (err) -+ return err; -+ -+ if (!mmap_buf || !mmap_size || !desc_size) -+ return -1; -+ -+ /* -+ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ -+ now we can fill platform specific memory structure. -+ */ -+ for (lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); -+ lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) -+ { -+ /* System RAM */ -+ if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ -+ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ -+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ -+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ -+ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ -+ (lsdesc->type != GRUB_EFI_PAL_CODE)) -+ { -+ free_mem[free_index].mem_type = GRUB_ADDRESS_TYPE_SYSRAM; -+ free_mem[free_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ free_mem[free_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ free_index++; -+ -+ /*ACPI*/ -+ }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ -+ acpi_table_mem[acpi_table_index].mem_type = GRUB_ADDRESS_TYPE_ACPI; -+ acpi_table_mem[acpi_table_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ acpi_table_mem[acpi_table_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ acpi_table_index++; -+ }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ -+ acpi_nvs_mem[acpi_nvs_index].mem_type = GRUB_ADDRESS_TYPE_NVS; -+ acpi_nvs_mem[acpi_nvs_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ acpi_nvs_mem[acpi_nvs_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ acpi_nvs_index++; -+ -+ /* Reserve */ -+ }else{ -+ reserve_mem[reserve_index].mem_type = GRUB_ADDRESS_TYPE_RESERVED; -+ reserve_mem[reserve_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ reserve_mem[reserve_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ reserve_index++; -+ } -+ } -+ -+ tmp_index = loongson_mem_map->map_count; -+ /*System RAM Sort*/ -+ tmp_index = grub_efi_loongarch64_memmap_sort(free_mem, -+ free_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_SYSRAM); -+ /*ACPI Sort*/ -+ tmp_index = grub_efi_loongarch64_memmap_sort(acpi_table_mem, -+ acpi_table_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_ACPI); -+ tmp_index = grub_efi_loongarch64_memmap_sort(acpi_nvs_mem, -+ acpi_nvs_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_NVS); -+ -+ /*Reserve Sort*/ -+ { -+ grub_uint64_t loongarch_addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); -+ if ((loongarch_addr & 0xff00000000000000) == 0x9000000000000000) -+ tmp_index = grub_efi_loongarch64_memmap_sort(reserve_mem, -+ reserve_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_RESERVED); -+ else -+ tmp_index = grub_efi_loongarch64_memmap_sort(reserve_mem, -+ reserve_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_RESERVED + 1); -+ } -+ loongson_mem_map->map_count = tmp_index; -+ loongson_mem_map->header.checksum = 0; -+ -+ checksum = grub_kernel_update_checksum ((grub_uint8_t *) loongson_mem_map, -+ loongson_mem_map->header.length); -+ loongson_mem_map->header.checksum = checksum; -+ -+ return grub_errno; -+} -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -new file mode 100644 -index 0000000..783054b ---- /dev/null -+++ b/grub-core/loader/loongarch64/linux.c -@@ -0,0 +1,398 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) -+ -+static struct linux_loongarch64_kernel_params kernel_params; -+ -+static grub_addr_t phys_addr; -+static grub_dl_t my_mod; -+static int loaded; -+static int is_bpi_boot; -+static int grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_BAD; -+ -+static grub_err_t -+grub_linux_boot (void) -+{ -+ -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { -+ if (finalize_efi_params_linux (&kernel_params) != GRUB_ERR_NONE) -+ return grub_errno; -+ return (grub_arch_efi_linux_boot_image((grub_addr_t) kernel_params.kernel_addr, -+ kernel_params.kernel_size, -+ kernel_params.linux_args)); -+ } -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_ELF) { -+ return grub_linux_loongarch_elf_linux_boot_image (&kernel_params); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_linux_unload (void) -+{ -+ -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { -+ if (kernel_params.ramdisk_addr) -+ grub_efi_free_pages ((grub_efi_physical_address_t) kernel_params.ramdisk_addr, -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.ramdisk_size)); -+ kernel_params.ramdisk_size = 0; -+ -+ if (kernel_params.kernel_addr) -+ grub_efi_free_pages ((grub_addr_t) kernel_params.kernel_addr, -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); -+ kernel_params.kernel_addr = 0; -+ } -+ -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_ELF) { -+ grub_free (kernel_params.linux_args); -+ kernel_params.linux_args = 0; -+ grub_linux_loongarch_elf_relocator_unload (); -+ } -+ -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_BAD; -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_err_t -+grub_linux_loongarch_elf_load_kernel (grub_elf_t elf, const char *filename) -+{ -+ Elf64_Addr base; -+ grub_err_t err; -+ grub_uint8_t *playground; -+ grub_uint64_t addr; -+ int flag; -+ -+ /* Linux's entry point incorrectly contains a virtual address. */ -+ kernel_params.kernel_addr = elf->ehdr.ehdr64.e_entry; -+ kernel_params.kernel_size = grub_elf64_size (elf, &base, 0); -+ -+ if (kernel_params.kernel_size == 0) -+ return grub_errno; -+ -+ phys_addr = base; -+ kernel_params.kernel_size = ALIGN_UP (base + kernel_params.kernel_size - base, 8); -+ -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ if (addr & 0x1) { -+ flag = GRUB_ELF_LOAD_FLAGS_NONE; -+ } else { -+ flag = GRUB_ELF_LOAD_FLAGS_30BITS; -+ base &= ~ELF64_LOADMASK; -+ kernel_params.kernel_addr &= ~ELF64_LOADMASK; -+ } -+ -+ playground = grub_linux_loongarch_alloc_virtual_mem_addr (phys_addr, -+ kernel_params.kernel_size, -+ &err); -+ if (playground == NULL) -+ return err; -+ -+ /* Now load the segments into the area we claimed. */ -+ return grub_elf64_load (elf, filename, playground - base, -+ flag, 0, 0); -+} -+ -+static grub_err_t -+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ grub_file_t file = 0; -+ struct linux_arch_kernel_header lh; -+ struct boot_params_interface *boot_params = NULL; -+ grub_elf_t elf = NULL; -+ grub_err_t err; -+ grub_size_t cmdline_size; -+ int i; -+ -+ grub_dl_ref (my_mod); -+ -+ /* Release the previously used memory. */ -+ grub_loader_unset (); -+ -+ if (argc == 0) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ goto fail; -+ } -+ -+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); -+ if (!file) -+ goto fail; -+ -+ kernel_params.kernel_size = grub_file_size (file); -+ grub_dprintf ("linux", "kernel file size: %" PRIuGRUB_SIZE "\n", -+ kernel_params.kernel_size); -+ -+ if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) -+ return grub_errno; -+ -+ if (grub_arch_efi_linux_check_image (&lh) == GRUB_ERR_NONE) { -+ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_EFI; -+ } -+ -+ if (grub_loongarch_linux_type != GRUB_LOONGARCH_LINUX_EFI) { -+ elf = grub_elf_file (file, argv[0]); -+ if (elf != NULL) -+ { -+ /* linux kernel type is ELF */ -+ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_ELF; -+ if (elf->ehdr.ehdr64.e_type != ET_EXEC) -+ { -+ grub_error (GRUB_ERR_UNKNOWN_OS, -+ N_("this ELF file is not of the right type")); -+ goto fail; -+ } -+ if (elf->ehdr.ehdr64.e_machine != EM_LOONGARCH) -+ { -+ grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); -+ goto fail; -+ } -+ -+ if (grub_elf_is_elf64 (elf)) -+ { -+ err = grub_linux_loongarch_elf_load_kernel (elf, argv[0]); -+ if (err) -+ goto fail; -+ } else { -+ grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); -+ goto fail; -+ } -+ grub_dprintf ("linux", "kernel @ %p\n", (void*) elf->ehdr.ehdr64.e_entry); -+ } -+ } else { -+ if (grub_file_seek (file, 0) == (grub_off_t) -1) -+ goto fail; -+ -+ if (grub_file_read (file, &lh, sizeof (lh)) < (grub_ssize_t) sizeof (lh)) -+ { -+ if (!grub_errno) -+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -+ argv[0]); -+ goto fail; -+ } -+ -+ if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE) -+ { -+ goto fail; -+ } -+ /* linux kernel type is EFI */ -+ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_EFI; -+ kernel_params.kernel_addr = (grub_addr_t) grub_efi_allocate_any_pages ( -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); -+ grub_dprintf ("linux", "kernel numpages: %" PRIuGRUB_SIZE "\n", -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); -+ if (!kernel_params.kernel_addr) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ -+ grub_file_seek (file, 0); -+ if (grub_file_read (file, (void*) kernel_params.kernel_addr, kernel_params.kernel_size) -+ < (grub_int64_t) kernel_params.kernel_size) -+ { -+ if (!grub_errno) -+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); -+ goto fail; -+ } -+ -+ grub_dprintf ("linux", "kernel @ %p\n", (void*) kernel_params.kernel_addr); -+ } -+ -+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); -+ kernel_params.linux_argc = argc; -+ kernel_params.linux_args = grub_malloc (cmdline_size); -+ if (!kernel_params.linux_args) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ -+ grub_memcpy (kernel_params.linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); -+ -+ if (grub_linux_loongarch_elf_get_boot_params (&boot_params) == 1) -+ is_bpi_boot = 1; -+ else -+ is_bpi_boot = 0; -+ -+ if (is_bpi_boot == 0) -+ { -+ err = grub_create_loader_cmdline (argc, argv, -+ (char*) ((grub_addr_t) kernel_params.linux_args + sizeof (LINUX_IMAGE) - 1), -+ cmdline_size, -+ GRUB_VERIFY_KERNEL_CMDLINE); -+ if (err) -+ goto fail; -+ } else { -+ /* save args from linux cmdline */ -+ char *p = kernel_params.linux_args; -+ -+ p += sizeof (LINUX_IMAGE) - 1; -+ for (i=0; i < argc; i++) -+ { -+ grub_memcpy (p, argv[i], grub_strlen(argv[i]) + 1); -+ p += grub_strlen(argv[i]) + 1; -+ } -+ } -+ -+ if (grub_errno == GRUB_ERR_NONE) -+ { -+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); -+ loaded = 1; -+ } -+ -+fail: -+ if (elf != NULL) { -+ /* grub_elf_close will call grub_file_close() */ -+ grub_elf_close (elf); -+ } else { -+ if (file) -+ grub_file_close (file); -+ } -+ -+ if (grub_errno != GRUB_ERR_NONE) -+ { -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ } -+ -+ if (kernel_params.linux_args && !loaded) -+ grub_free (kernel_params.linux_args); -+ -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { -+ if (kernel_params.kernel_addr && !loaded) -+ grub_efi_free_pages ((grub_addr_t) kernel_params.kernel_addr, -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); -+ } -+ -+ return grub_errno; -+} -+ -+/* -+ * This function returns a pointer to a legally allocated initrd buffer, -+ * or NULL if unsuccessful -+ */ -+static void * -+allocate_initrd_mem (int initrd_pages) -+{ -+ grub_addr_t max_addr; -+ -+ if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) -+ return NULL; -+ -+ max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; -+ -+ return grub_efi_allocate_pages_real (max_addr, initrd_pages, -+ GRUB_EFI_ALLOCATE_MAX_ADDRESS, -+ GRUB_EFI_LOADER_DATA); -+} -+ -+ -+static grub_err_t -+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; -+ grub_size_t initrd_size; -+ void *initrd_mem = NULL; -+ -+ if (argc == 0) -+ { -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ goto fail; -+ } -+ -+ if (!loaded) -+ { -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); -+ goto fail; -+ } -+ -+ if (grub_initrd_init (argc, argv, &initrd_ctx)) -+ goto fail; -+ -+ initrd_size = grub_get_initrd_size (&initrd_ctx); -+ grub_dprintf ("linux", "Loading initrd\n"); -+ -+ if (is_bpi_boot == 0) { -+ grub_size_t initrd_pages; -+ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); -+ initrd_mem = allocate_initrd_mem (initrd_pages); -+ } else { -+ grub_err_t err; -+ initrd_mem = grub_linux_loongarch_alloc_virtual_mem_align (initrd_size, 0x10000, &err); -+ if (err) -+ goto fail; -+ } -+ -+ if (!initrd_mem) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ -+ if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) -+ goto fail; -+ -+ /* save ramdisk addr and size */ -+ kernel_params.ramdisk_addr = (grub_addr_t) initrd_mem; -+ kernel_params.ramdisk_size = initrd_size; -+ grub_dprintf ("linux", "ramdisk [addr=%p, size=0x%lx]\n", -+ (void *) initrd_mem, initrd_size); -+fail: -+ grub_initrd_close (&initrd_ctx); -+ if (is_bpi_boot == 0) { -+ if (initrd_mem && !kernel_params.ramdisk_addr) -+ grub_efi_free_pages ((grub_addr_t) initrd_mem, -+ GRUB_EFI_BYTES_TO_PAGES (initrd_size)); -+ } -+ return grub_errno; -+} -+ -+static grub_command_t cmd_linux, cmd_initrd; -+ -+GRUB_MOD_INIT(linux) -+{ -+ cmd_linux = grub_register_command ("linux", grub_cmd_linux, -+ N_("FILE [ARGS...]"), N_("Load Linux.")); -+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, -+ N_("FILE"), N_("Load initrd.")); -+ my_mod = mod; -+} -+ -+GRUB_MOD_FINI(linux) -+{ -+ grub_unregister_command (cmd_linux); -+ grub_unregister_command (cmd_initrd); -+} -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index f431f49..a74ce39 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -2104,7 +2104,7 @@ typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_add - - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ -- || defined(__riscv) -+ || defined(__riscv) || defined (__loongarch64) - - #define efi_call_0(func) func() - #define efi_call_1(func, a) func(a) -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 8dfc89a..c816359 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -135,13 +135,17 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, - char **device, - char **path); - --#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) -+#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__) - void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); - grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); - #include - grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); -+#if defined(__loongarch__) -+grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, char *args); -+#else - grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args); - #endif -+#endif - - grub_addr_t grub_efi_section_addr (const char *section); - -diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h -index a43adf2..f8f2402 100644 ---- a/include/grub/efi/pe32.h -+++ b/include/grub/efi/pe32.h -@@ -79,6 +79,8 @@ struct grub_pe32_coff_header - #define GRUB_PE32_MACHINE_ARM64 0xAA64 - #define GRUB_PE32_MACHINE_RISCV32 0x5032 - #define GRUB_PE32_MACHINE_RISCV64 0x5064 -+#define GRUB_PE32_MACHINE_LOONGARCH32 0x6232 -+#define GRUB_PE32_MACHINE_LOONGARCH64 0x6264 - - #define GRUB_PE32_RELOCS_STRIPPED 0x0001 - #define GRUB_PE32_EXECUTABLE_IMAGE 0x0002 -@@ -338,6 +340,8 @@ struct grub_pe32_fixup_block - #define GRUB_PE32_REL_BASED_ARM_MOV32T 7 - #define GRUB_PE32_REL_BASED_RISCV_LOW12I 7 - #define GRUB_PE32_REL_BASED_RISCV_LOW12S 8 -+#define GRUB_PE32_REL_BASED_LOONGARCH32_MARK_LA 8 -+#define GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA 8 - #define GRUB_PE32_REL_BASED_IA64_IMM64 9 - #define GRUB_PE32_REL_BASED_DIR64 10 - #define GRUB_PE32_REL_BASED_HIGH3ADJ 11 -diff --git a/include/grub/elf.h b/include/grub/elf.h -index c478933..73175bd 100644 ---- a/include/grub/elf.h -+++ b/include/grub/elf.h -@@ -248,6 +248,7 @@ typedef struct - #define EM_NUM 95 - #define EM_AARCH64 183 /* ARM 64-bit architecture */ - #define EM_RISCV 243 /* RISC-V */ -+#define EM_LOONGARCH 258 /* LoongArch */ - - /* If it is necessary to assign new unofficial EM_* values, please - pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -@@ -2531,6 +2532,35 @@ typedef Elf32_Addr Elf32_Conflict; - #define R_RISCV_SET32 56 - #define R_RISCV_32_PCREL 57 - -+/* LoongArch relocations */ -+#define R_LARCH_NONE 0 -+#define R_LARCH_64 2 -+#define R_LARCH_MARK_LA 20 -+#define R_LARCH_SOP_PUSH_PCREL 22 -+#define R_LARCH_SOP_PUSH_ABSOLUTE 23 -+#define R_LARCH_SOP_PUSH_PLT_PCREL 29 -+#define R_LARCH_SOP_SUB 32 -+#define R_LARCH_SOP_SL 33 -+#define R_LARCH_SOP_SR 34 -+#define R_LARCH_SOP_ADD 35 -+#define R_LARCH_SOP_AND 36 -+#define R_LARCH_SOP_IF_ELSE 37 -+#define R_LARCH_SOP_POP_32_S_10_5 38 -+#define R_LARCH_SOP_POP_32_U_10_12 39 -+#define R_LARCH_SOP_POP_32_S_10_12 40 -+#define R_LARCH_SOP_POP_32_S_10_16 41 -+#define R_LARCH_SOP_POP_32_S_10_16_S2 42 -+#define R_LARCH_SOP_POP_32_S_5_20 43 -+#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 -+#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 -+#define R_LARCH_B26 66 -+#define R_LARCH_ABS_HI20 67 -+#define R_LARCH_ABS_LO12 68 -+#define R_LARCH_ABS64_LO20 69 -+#define R_LARCH_ABS64_HI12 70 -+#define R_LARCH_PCALA_HI20 71 -+#define R_LARCH_PCALA_LO12 72 -+ - #ifdef GRUB_TARGET_WORDSIZE - #if GRUB_TARGET_WORDSIZE == 32 - -diff --git a/include/grub/fdt.h b/include/grub/fdt.h -index 3514aa4..ba2f9a9 100644 ---- a/include/grub/fdt.h -+++ b/include/grub/fdt.h -@@ -20,7 +20,7 @@ - #define GRUB_FDT_HEADER 1 - - #if !defined(GRUB_MACHINE_EMU) && \ -- (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) -+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__)) - - #include - #include -@@ -148,6 +148,6 @@ int EXPORT_FUNC(grub_fdt_set_prop) (void *fdt, unsigned int nodeoffset, const ch - }) - - #endif /* !defined(GRUB_MACHINE_EMU) && \ -- (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) */ -+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__)) */ - - #endif /* ! GRUB_FDT_HEADER */ -diff --git a/include/grub/loongarch64/efi/loader.h b/include/grub/loongarch64/efi/loader.h -new file mode 100644 -index 0000000..71a0159 ---- /dev/null -+++ b/include/grub/loongarch64/efi/loader.h -@@ -0,0 +1,25 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2003,2004,2006,2007,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOADER_MACHINE_HEADER -+#define GRUB_LOADER_MACHINE_HEADER 1 -+ -+#include -+#include -+ -+#endif /* ! GRUB_LOADER_MACHINE_HEADER */ -diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h -new file mode 100644 -index 0000000..2d3f36e ---- /dev/null -+++ b/include/grub/loongarch64/efi/memory.h -@@ -0,0 +1,15 @@ -+#ifndef GRUB_MEMORY_CPU_HEADER -+#include -+ -+ -+static inline grub_uint64_t grub_efi_max_usable_address(void) -+{ -+ grub_uint64_t addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ return addr |= 0xffffffffffUL; -+} -+ -+#define GRUB_EFI_MAX_USABLE_ADDRESS (grub_efi_max_usable_address()) -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS -+ -+#endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/loongarch64/efi/time.h b/include/grub/loongarch64/efi/time.h -new file mode 100644 -index 0000000..e69de29 -diff --git a/include/grub/loongarch64/io.h b/include/grub/loongarch64/io.h -new file mode 100644 -index 0000000..5f34103 ---- /dev/null -+++ b/include/grub/loongarch64/io.h -@@ -0,0 +1,62 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_IO_H -+#define GRUB_IO_H 1 -+ -+#include -+ -+typedef grub_addr_t grub_port_t; -+ -+static __inline unsigned char -+grub_inb (grub_port_t port) -+{ -+ return *(volatile grub_uint8_t *) port; -+} -+ -+static __inline unsigned short int -+grub_inw (grub_port_t port) -+{ -+ return *(volatile grub_uint16_t *) port; -+} -+ -+static __inline unsigned int -+grub_inl (grub_port_t port) -+{ -+ return *(volatile grub_uint32_t *) port; -+} -+ -+static __inline void -+grub_outb (unsigned char value, grub_port_t port) -+{ -+ *(volatile grub_uint8_t *) port = value; -+} -+ -+static __inline void -+grub_outw (unsigned short int value, grub_port_t port) -+{ -+ *(volatile grub_uint16_t *) port = value; -+} -+ -+static __inline void -+grub_outl (unsigned int value, grub_port_t port) -+{ -+ *(volatile grub_uint32_t *) port = value; -+} -+ -+#endif /* _SYS_IO_H */ -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -new file mode 100644 -index 0000000..af1f51d ---- /dev/null -+++ b/include/grub/loongarch64/linux.h -@@ -0,0 +1,144 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOONGARCH64_LINUX_HEADER -+#define GRUB_LOONGARCH64_LINUX_HEADER 1 -+ -+#include -+ -+/* LoongArch linux kernel type */ -+#define GRUB_LOONGARCH_LINUX_BAD 0 -+#define GRUB_LOONGARCH_LINUX_ELF 1 -+#define GRUB_LOONGARCH_LINUX_EFI 2 -+ -+#define GRUB_LOONGSON3_BOOT_MEM_MAP_MAX 128 -+ -+#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE 0x6E6F73676E6F6F4C /* 'Loongson' */ -+#define linux_arch_kernel_header linux_loongarch64_kernel_header -+ -+/* From linux/Documentation/loongarch/booting.txt -+ * -+ * 0-1: MZ -+ * 0x28: LoongArch\0 -+ * 0x3c: PE/COFF头偏移 -+ * 0x20e:内核版本号偏移-512 -+ * riscv的version字段在0x20偏移处,现在LoongArch没有使用,是0 -+ */ -+struct linux_loongarch64_kernel_header -+{ -+ grub_uint32_t code0; /* Executable code */ -+ grub_uint32_t code1; /* Executable code */ -+ grub_uint64_t text_offset; /* Image load offset */ -+ grub_uint64_t res0; /* reserved */ -+ grub_uint64_t res1; /* reserved */ -+ grub_uint64_t res2; /* reserved */ -+ grub_uint64_t magic; /* Magic number, little endian, "Loongson" */ -+ grub_uint64_t res3; /* reserved */ -+ grub_uint32_t res4; /* reserved */ -+ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ -+}; -+ -+struct linux_loongarch64_kernel_params -+{ -+ grub_addr_t kernel_addr; /* kernel entry address */ -+ grub_size_t kernel_size; /* kernel size */ -+ grub_addr_t ramdisk_addr; /* initrd load address */ -+ grub_size_t ramdisk_size; /* initrd size */ -+ int linux_argc; /* cmdline parameters number*/ -+ grub_addr_t linux_argv; /* cmdline parameters address*/ -+ void* linux_args; -+ void* fdt; -+}; -+ -+#include -+#include -+ -+#define GRUB_EFI_MAX_PHY_ADDRESS 0xffffffffffffULL -+#define ELF32_LOADMASK (0xf0000000UL) -+#define ELF64_LOADMASK (0xf000000000000000ULL) -+#define FLAGS_EFI_SUPPORT_BIT 0 -+ -+#define FDT_ADDR_CELLS_STRING "#address-cells" -+#define FDT_SIZE_CELLS_STRING "#size-cells" -+#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ -+ sizeof (FDT_ADDR_CELLS_STRING) + \ -+ sizeof (FDT_SIZE_CELLS_STRING)) -+ -+/* From arch/loongarch/include/asm/mach-loongson64/boot_param.h */ -+struct _extention_list_hdr { -+ grub_uint64_t signature; -+ grub_uint32_t length; -+ grub_uint8_t revision; -+ grub_uint8_t checksum; -+ union { -+ struct _extention_list_hdr *next; -+ grub_uint64_t next_offset; -+ }; -+ -+} GRUB_PACKED; -+ -+struct boot_params_interface { -+ grub_uint64_t signature; /* {"B", "P", "I", "0", "1", ... } */ -+ grub_efi_system_table_t *systemtable; -+ union { -+ struct _extention_list_hdr *extlist; -+ grub_uint64_t extlist_offset; -+ }; -+ grub_uint64_t flags; -+}GRUB_PACKED; -+ -+struct loongsonlist_mem_map { -+ struct _extention_list_hdr header; /* {"M", "E", "M"} */ -+ grub_uint8_t map_count; -+ struct memmap { -+ grub_uint32_t mem_type; -+ grub_uint64_t mem_start; -+ grub_uint64_t mem_size; -+ } GRUB_PACKED map[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+}GRUB_PACKED; -+ -+grub_err_t -+finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params); -+ -+grub_err_t -+grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_params -+ *kernel_params); -+ -+void* -+grub_linux_loongarch_alloc_virtual_mem_addr (grub_addr_t addr, -+ grub_size_t size, -+ grub_err_t *err); -+ -+void* -+grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, -+ grub_size_t align, -+ grub_err_t *err); -+ -+void -+grub_linux_loongarch_elf_relocator_unload (void); -+ -+int -+grub_linux_loongarch_elf_get_boot_params (struct boot_params_interface **boot_params); -+ -+grub_err_t -+grub_linux_loongarch_elf_boot_params (struct boot_params_interface *boot_params); -+ -+grub_err_t -+grub_linux_loongarch_elf_load_kernel (grub_elf_t elf, const char *filename); -+ -+#endif /* ! GRUB_LOONGARCH64_LINUX_HEADER */ -diff --git a/include/grub/loongarch64/loongarch64.h b/include/grub/loongarch64/loongarch64.h -new file mode 100644 -index 0000000..ea3be3d ---- /dev/null -+++ b/include/grub/loongarch64/loongarch64.h -@@ -0,0 +1,30 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2010,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_REGISTERS_CPU_HEADER -+#define GRUB_REGISTERS_CPU_HEADER 1 -+ -+#ifdef ASM_FILE -+#define GRUB_CPU_REGISTER_WRAP(x) x -+#else -+#define GRUB_CPU_REGISTER_WRAP(x) #x -+#endif -+ -+#define GRUB_CPU_LOONGARCH_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP(9) -+ -+#endif -diff --git a/include/grub/loongarch64/memory.h b/include/grub/loongarch64/memory.h -new file mode 100644 -index 0000000..cc9faef ---- /dev/null -+++ b/include/grub/loongarch64/memory.h -@@ -0,0 +1,59 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_MEMORY_CPU_HEADER -+#define GRUB_MEMORY_CPU_HEADER 1 -+ -+#ifndef ASM_FILE -+#include -+#include -+#include -+#endif -+ -+#ifndef ASM_FILE -+ -+typedef grub_addr_t grub_phys_addr_t; -+ -+static inline grub_phys_addr_t -+grub_vtop (void *a) -+{ -+ if (-1 == ((grub_int64_t) a >> 32)) -+ return ((grub_phys_addr_t) a) & 0x1fffffffUL; -+ return ((grub_phys_addr_t) a) & 0xffffffffffffUL; -+} -+ -+static inline void * -+grub_map_memory (grub_phys_addr_t a, grub_size_t size) -+{ -+ grub_uint64_t addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ if (addr & 0x1) -+ return (void *) (a | (addr & 0xffffffffffffff00UL)); -+ else -+ return (void *) a; -+} -+ -+static inline void -+grub_unmap_memory (void *a __attribute__ ((unused)), -+ grub_size_t size __attribute__ ((unused))) -+{ -+} -+ -+#endif -+ -+#endif -diff --git a/include/grub/loongarch64/reloc.h b/include/grub/loongarch64/reloc.h -new file mode 100644 -index 0000000..2106ba2 ---- /dev/null -+++ b/include/grub/loongarch64/reloc.h -@@ -0,0 +1,113 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOONGARCH64_RELOC_H -+#define GRUB_LOONGARCH64_RELOC_H 1 -+#include -+ -+#define LOONGARCH64_STACK_MAX 16 -+ -+struct grub_loongarch64_stack -+{ -+ grub_uint64_t data[LOONGARCH64_STACK_MAX]; -+ int count; -+ int top; -+}; -+ -+typedef struct grub_loongarch64_stack* grub_loongarch64_stack_t; -+ -+void grub_loongarch64_stack_init (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_push (grub_loongarch64_stack_t stack, -+ grub_int64_t offset); -+void grub_loongarch64_sop_sub (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_sl (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_sr (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_add (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_and (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_if_else (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_32_s_10_5 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_u_10_12 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_10_12 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_10_16 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_5_20 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_0_5_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_0_10_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+ -+void grub_loongarch64_b26 (grub_uint32_t *place, grub_int64_t offset); -+void grub_loongarch64_xxx_hi20 (grub_uint32_t *place, grub_int64_t offset); -+void grub_loongarch64_xxx_lo12 (grub_uint32_t *place, grub_int64_t offset); -+void grub_loongarch64_xxx64_hi12 (grub_uint32_t *place, grub_int64_t offset); -+void grub_loongarch64_xxx64_lo20 (grub_uint32_t *place, grub_int64_t offset); -+ -+#define GRUB_LOONGARCH64_RELOCATION(STACK, PLACE, OFFSET) \ -+ case R_LARCH_SOP_PUSH_ABSOLUTE: \ -+ grub_loongarch64_sop_push (STACK, OFFSET); \ -+ break; \ -+ case R_LARCH_SOP_SUB: \ -+ grub_loongarch64_sop_sub (STACK); \ -+ break; \ -+ case R_LARCH_SOP_SL: \ -+ grub_loongarch64_sop_sl (STACK); \ -+ break; \ -+ case R_LARCH_SOP_SR: \ -+ grub_loongarch64_sop_sr (STACK); \ -+ break; \ -+ case R_LARCH_SOP_ADD: \ -+ grub_loongarch64_sop_add (STACK); \ -+ break; \ -+ case R_LARCH_SOP_AND: \ -+ grub_loongarch64_sop_and (STACK); \ -+ break; \ -+ case R_LARCH_SOP_IF_ELSE: \ -+ grub_loongarch64_sop_if_else (STACK); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_10_5: \ -+ grub_loongarch64_sop_32_s_10_5 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_U_10_12: \ -+ grub_loongarch64_sop_32_u_10_12 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_10_12: \ -+ grub_loongarch64_sop_32_s_10_12 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_10_16: \ -+ grub_loongarch64_sop_32_s_10_16 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_10_16_S2: \ -+ grub_loongarch64_sop_32_s_10_16_s2 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_5_20: \ -+ grub_loongarch64_sop_32_s_5_20 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: \ -+ grub_loongarch64_sop_32_s_0_5_10_16_s2 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: \ -+ grub_loongarch64_sop_32_s_0_10_10_16_s2 (STACK, PLACE); \ -+ break; -+ -+#endif /* GRUB_LOONGARCH64_RELOC_H */ -diff --git a/include/grub/loongarch64/relocator.h b/include/grub/loongarch64/relocator.h -new file mode 100644 -index 0000000..cef3aaa ---- /dev/null -+++ b/include/grub/loongarch64/relocator.h -@@ -0,0 +1,38 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_RELOCATOR_CPU_HEADER -+#define GRUB_RELOCATOR_CPU_HEADER 1 -+ -+#include -+#include -+#include -+ -+struct grub_relocator64_state -+{ -+ /* gpr[0] is ignored since it's hardwired to 0. */ -+ grub_uint64_t gpr[32]; -+ /* Register holding target $pc. */ -+ int jumpreg; -+}; -+ -+grub_err_t -+grub_relocator64_boot (struct grub_relocator *rel, -+ struct grub_relocator64_state state); -+ -+#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ -diff --git a/include/grub/loongarch64/setjmp.h b/include/grub/loongarch64/setjmp.h -new file mode 100644 -index 0000000..d9a0776 ---- /dev/null -+++ b/include/grub/loongarch64/setjmp.h -@@ -0,0 +1,27 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2004,2006,2007,2009,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_SETJMP_CPU_HEADER -+#define GRUB_SETJMP_CPU_HEADER 1 -+ -+typedef grub_uint64_t grub_jmp_buf[12]; -+ -+int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; -+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); -+ -+#endif /* ! GRUB_SETJMP_CPU_HEADER */ -diff --git a/include/grub/loongarch64/time.h b/include/grub/loongarch64/time.h -new file mode 100644 -index 0000000..c9a7334 ---- /dev/null -+++ b/include/grub/loongarch64/time.h -@@ -0,0 +1,39 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2003,2004,2005,2007,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef KERNEL_CPU_TIME_HEADER -+#define KERNEL_CPU_TIME_HEADER 1 -+ -+#ifndef GRUB_UTIL -+ -+#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) -+ -+void grub_timer_init (grub_uint32_t cpuclock); -+ -+/* Return the real time in ticks. */ -+grub_uint64_t grub_get_rtc (void); -+ -+extern grub_uint32_t grub_arch_cpuclock; -+#endif -+ -+static inline void -+grub_cpu_idle(void) -+{ -+} -+ -+#endif -diff --git a/include/grub/loongarch64/types.h b/include/grub/loongarch64/types.h -new file mode 100644 -index 0000000..2dbefbf ---- /dev/null -+++ b/include/grub/loongarch64/types.h -@@ -0,0 +1,34 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2006,2007,2009,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_TYPES_CPU_HEADER -+#define GRUB_TYPES_CPU_HEADER 1 -+ -+/* The size of void *. */ -+#define GRUB_TARGET_SIZEOF_VOID_P 8 -+ -+/* The size of long. */ -+#define GRUB_TARGET_SIZEOF_LONG 8 -+ -+#ifdef GRUB_CPU_LOONGARCH -+/* loongarch is little-endian. */ -+#undef GRUB_TARGET_WORDS_BIGENDIAN -+ -+#endif /* ! GRUB_TYPES_CPU_HEADER */ -+ -+#endif -diff --git a/include/grub/util/install.h b/include/grub/util/install.h -index 51f3b13..a728afc 100644 ---- a/include/grub/util/install.h -+++ b/include/grub/util/install.h -@@ -114,6 +114,7 @@ enum grub_install_plat - GRUB_INSTALL_PLATFORM_ARM_COREBOOT, - GRUB_INSTALL_PLATFORM_RISCV32_EFI, - GRUB_INSTALL_PLATFORM_RISCV64_EFI, -+ GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI, - GRUB_INSTALL_PLATFORM_MAX - }; - -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index 4833407..60d2c00 100644 ---- a/util/grub-install-common.c -+++ b/util/grub-install-common.c -@@ -939,6 +939,7 @@ static struct - [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, - [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32", "efi" }, - [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64", "efi" }, -+ [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64", "efi" }, - }; - - char * -diff --git a/util/grub-install.c b/util/grub-install.c -index 5babc7a..c8f15df 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -332,6 +332,8 @@ get_default_platform (void) - #else - return NULL; - #endif -+#elif defined (__loongarch64) -+ return "loongarch64-efi"; - #else - return NULL; - #endif -@@ -487,6 +489,7 @@ have_bootdev (enum grub_install_plat pl) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: - case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: -@@ -906,6 +909,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_I386_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_X86_64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - is_efi = 1; - grub_util_error (_("this utility cannot be used for EFI platforms" - " because it does not support UEFI Secure Boot")); -@@ -933,6 +937,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: -@@ -980,6 +985,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_ARM_UBOOT: -@@ -1133,6 +1139,9 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: - efi_file = "BOOTRISCV64.EFI"; - break; -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: -+ efi_file = "BOOTLOONGARCH64.EFI"; -+ break; - default: - grub_util_error ("%s", _("You've found a bug")); - break; -@@ -1166,6 +1175,9 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: - efi_file = "grubriscv64.efi"; - break; -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: -+ efi_file = "grubloongarch64.efi"; -+ break; - default: - efi_file = "grub.efi"; - break; -@@ -1470,6 +1482,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - g = grub_util_guess_efi_drive (*curdev); - break; -@@ -1614,6 +1627,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - core_name = "core.efi"; - snprintf (mkimage_target, sizeof (mkimage_target), -@@ -1719,6 +1733,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: - case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: -@@ -1973,6 +1988,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - { - char *dst = grub_util_path_concat (2, efidir, efi_file); -diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c -index 3931194..cf582a9 100644 ---- a/util/grub-mkimagexx.c -+++ b/util/grub-mkimagexx.c -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1160,7 +1161,60 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, - } - break; - } --#endif -+ case EM_LOONGARCH: -+ { -+ grub_int64_t pc; -+ grub_uint32_t *t32 = (grub_uint32_t *) target; -+ -+ sym_addr += addend; -+ pc = offset + target_section_addr + image_target->vaddr_offset; -+ -+ switch (ELF_R_TYPE (info)) -+ { -+ case R_LARCH_64: -+ { -+ grub_uint64_t *t64 = (grub_uint64_t *) target; -+ *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) + sym_addr); -+ } -+ break; -+ case R_LARCH_MARK_LA: -+ break; -+ case R_LARCH_B26: -+ { -+ grub_int64_t off; -+ off = sym_addr - target_section_addr - offset -+ - image_target->vaddr_offset; -+ grub_loongarch64_b26 (t32, off); -+ } -+ break; -+ case R_LARCH_ABS_HI20: -+ grub_loongarch64_xxx_hi20 (t32, sym_addr); -+ break; -+ case R_LARCH_ABS64_LO20: -+ grub_loongarch64_xxx64_lo20 (t32, sym_addr); -+ break; -+ case R_LARCH_ABS64_HI12: -+ grub_loongarch64_xxx64_hi12 (t32, sym_addr); -+ break; -+ case R_LARCH_PCALA_HI20: -+ { -+ grub_int32_t hi20; -+ hi20 = (((sym_addr + 0x800) & ~0xfffULL) - (pc & ~0xfffULL)); -+ grub_loongarch64_xxx_hi20 (t32, hi20); -+ } -+ break; -+ case R_LARCH_ABS_LO12: -+ case R_LARCH_PCALA_LO12: -+ grub_loongarch64_xxx_lo12 (t32, sym_addr); -+ break; -+ default: -+ grub_util_error (_("relocation 0x%x is not implemented yet"), -+ (unsigned int) ELF_R_TYPE (info)); -+ break; -+ } -+ break; -+ } -+#endif /* defined(MKIMAGE_ELF64) */ - #if defined(MKIMAGE_ELF32) - case EM_ARM: - { -@@ -1538,7 +1592,10 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - - /* The spec does not mention the requirement of a Page RVA. - Here, align the address with a 4K boundary for safety. */ -- b->page_rva = (addr & ~(0x1000 - 1)); -+#ifdef GRUB_CPU_LOONGARCH64 -+ if (type) -+#endif -+ b->page_rva = (addr & ~(0x1000 - 1)); - b->block_size = sizeof (*b); - } - -@@ -1548,7 +1605,11 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - - /* Add a new entry. */ - cur_index = ((b->block_size - sizeof (*b)) >> 1); -+#ifdef GRUB_CPU_LOONGARCH64 -+ entry = GRUB_PE32_FIXUP_ENTRY (type, type ? (addr - b->page_rva) : addr); -+#else - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); -+#endif - b->entries[cur_index] = grub_host_to_target16 (entry); - b->block_size += 2; - } -@@ -1704,7 +1765,39 @@ translate_relocation_pe (struct translate_context *ctx, - break; - } - break; -- break; -+#if defined(MKIMAGE_ELF64) -+ case EM_LOONGARCH: -+ switch (ELF_R_TYPE (info)) -+ { -+ case R_LARCH_64: -+ ctx->current_address = add_fixup_entry (&ctx->lst, -+ GRUB_PE32_REL_BASED_DIR64, addr, 0, -+ ctx->current_address, image_target); -+ break; -+ case R_LARCH_MARK_LA: -+ ctx->current_address = add_fixup_entry (&ctx->lst, -+ GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA, -+ addr, 0, ctx->current_address, image_target); -+ break; -+ /* Relative relocations do not require fixup entries. */ -+ case R_LARCH_B26: -+ case R_LARCH_ABS_HI20: -+ case R_LARCH_ABS_LO12: -+ case R_LARCH_ABS64_LO20: -+ case R_LARCH_ABS64_HI12: -+ case R_LARCH_PCALA_HI20: -+ case R_LARCH_PCALA_LO12: -+ grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", -+ __FUNCTION__, (unsigned int) addr, -+ (unsigned int) ctx->current_address); -+ break; -+ default: -+ grub_util_error (_("relocation 0x%x is not implemented yet"), -+ (unsigned int) ELF_R_TYPE (info)); -+ break; -+ } -+ break; -+#endif /* defined(MKIMAGE_ELF64) */ - #if defined(MKIMAGE_ELF32) - case EM_ARM: - switch (ELF_R_TYPE (info)) -diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c -index 163529c..071d1c3 100644 ---- a/util/grub-module-verifier.c -+++ b/util/grub-module-verifier.c -@@ -176,6 +176,21 @@ struct grub_module_verifier_arch archs[] = { - -1 - } - }, -+ { "loongarch64", 8, 0, EM_LOONGARCH, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ -+ R_LARCH_NONE, -+ R_LARCH_64, -+ R_LARCH_MARK_LA, -+ R_LARCH_B26, -+ R_LARCH_ABS_HI20, -+ R_LARCH_ABS_LO12, -+ R_LARCH_ABS64_LO20, -+ R_LARCH_ABS64_HI12, -+ R_LARCH_PCALA_HI20, -+ R_LARCH_PCALA_LO12, -+ -1 -+ }, (int[]){ -+ -1 -+ } }, - }; - - struct platform_whitelist { -diff --git a/util/mkimage.c b/util/mkimage.c -index 8319e8d..4e09dfc 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -654,6 +654,22 @@ static const struct grub_install_image_target_desc image_targets[] = - .pe_target = GRUB_PE32_MACHINE_RISCV64, - .elf_target = EM_RISCV, - }, -+ { -+ .dirname = "loongarch64-efi", -+ .names = { "loongarch64-efi", NULL }, -+ .voidp_sizeof = 8, -+ .bigendian = 0, -+ .id = IMAGE_EFI, -+ .flags = PLATFORM_FLAGS_NONE, -+ .total_module_size = TARGET_NO_FIELD, -+ .decompressor_compressed_size = TARGET_NO_FIELD, -+ .decompressor_uncompressed_size = TARGET_NO_FIELD, -+ .decompressor_uncompressed_addr = TARGET_NO_FIELD, -+ .section_align = GRUB_PE32_SECTION_ALIGNMENT, -+ .vaddr_offset = EFI64_HEADER_SIZE, -+ .pe_target = GRUB_PE32_MACHINE_LOONGARCH64, -+ .elf_target = EM_LOONGARCH, -+ }, - }; - - #include --- -2.33.0 - diff --git a/1001-loongarch-Modify-the-location-where-initrd-is-loaded.patch b/1001-loongarch-Modify-the-location-where-initrd-is-loaded.patch deleted file mode 100644 index abbf1b5..0000000 --- a/1001-loongarch-Modify-the-location-where-initrd-is-loaded.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 062741f3d9878bcbd4556f3bfe73d1bead458255 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Thu, 2 Feb 2023 20:32:17 +0800 -Subject: [PATCH] loongarch: Modify the location where initrd is loaded into - memory - -Try to allocate memory from higher than 256MB to -avoid kernel relocation overlaying initrd. If failed, -allocate memory in range 0~256MB, and high address -takes precedence. - -Signed-off-by: mengyingkun ---- - grub-core/loader/loongarch64/linux-elf.c | 21 +++++++++++++++++++++ - grub-core/loader/loongarch64/linux.c | 2 +- - include/grub/loongarch64/linux.h | 5 +++++ - 3 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 85585b4..8260e4c 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -304,6 +304,27 @@ grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, - return get_virtual_current_address (ch); - } - -+void* -+grub_linux_loongarch_alloc_initrd_mem_align (grub_size_t size, -+ grub_size_t align, -+ grub_err_t *err) -+{ -+ grub_relocator_chunk_t ch; -+ -+ /* Firstly try to allocate from memory higher than 256MB */ -+ *err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0x10000000, (0xffffffff - size) + 1, size, align, -+ GRUB_RELOCATOR_PREFERENCE_LOW, 0); -+ if (*err != GRUB_ERR_NONE) -+ { -+ /* Failed, try to allocate in range 0 ~ 256MB */ -+ *err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0, (0xfffffff - size) + 1, size, align, -+ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); -+ } -+ return get_virtual_current_address (ch); -+} -+ - int - grub_linux_loongarch_elf_get_boot_params (struct boot_params_interface **boot_params) - { -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -index 783054b..4c02194 100644 ---- a/grub-core/loader/loongarch64/linux.c -+++ b/grub-core/loader/loongarch64/linux.c -@@ -351,7 +351,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - initrd_mem = allocate_initrd_mem (initrd_pages); - } else { - grub_err_t err; -- initrd_mem = grub_linux_loongarch_alloc_virtual_mem_align (initrd_size, 0x10000, &err); -+ initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x10000, &err); - if (err) - goto fail; - } -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -index af1f51d..f4b198a 100644 ---- a/include/grub/loongarch64/linux.h -+++ b/include/grub/loongarch64/linux.h -@@ -129,6 +129,11 @@ grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, - grub_size_t align, - grub_err_t *err); - -+void* -+grub_linux_loongarch_alloc_initrd_mem_align (grub_size_t size, -+ grub_size_t align, -+ grub_err_t *err); -+ - void - grub_linux_loongarch_elf_relocator_unload (void); - --- -2.33.0 - diff --git a/1002-loongarch-Add-EFI-frame-buffer-support.patch b/1002-loongarch-Add-EFI-frame-buffer-support.patch deleted file mode 100644 index ca432af..0000000 --- a/1002-loongarch-Add-EFI-frame-buffer-support.patch +++ /dev/null @@ -1,337 +0,0 @@ -From 1ebd229556ba767f76c829b6d00d8a7b5bf28e65 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Wed, 8 Feb 2023 09:24:05 +0800 -Subject: [PATCH] loongarch: Add EFI frame buffer support - -Signed-off-by: yangqiming -Signed-off-by: mengyingkun ---- - grub-core/loader/loongarch64/linux-elf.c | 232 +++++++++++++++++++++++ - include/grub/loongarch64/linux.h | 47 +++++ - 2 files changed, 279 insertions(+) - -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 8260e4c..852e8f4 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #define GRUB_ADDRESS_TYPE_SYSRAM 1 - #define GRUB_ADDRESS_TYPE_RESERVED 2 -@@ -34,13 +35,242 @@ - { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ - } - -+#define GRUB_EFI_LARCH_SCREEN_INFO_GUID \ -+ { 0x07fd51a6, 0x9532, 0x926f, \ -+ { 0x51, 0xdc, 0x6a, 0x63, 0x60, 0x2f, 0x84, 0xb4 } \ -+ } -+ -+#define GRUB_EFI_LARCH_CONSOLE_OUT_DEVICE_GUID \ -+ { 0xd3b36f2c, 0xd551, 0x11d4, \ -+ { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ -+ } -+ - static struct grub_relocator *relocator; -+static grub_efi_guid_t screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; - - void grub_linux_loongarch_elf_relocator_unload (void) - { - grub_relocator_unload (relocator); - } - -+static void -+find_bits (unsigned long mask, grub_efi_uint8_t *pos, grub_efi_uint8_t *size) -+{ -+ grub_efi_uint8_t first, len; -+ -+ first = 0; -+ len = 0; -+ -+ if (mask) -+ { -+ while (!(mask & 0x1)) -+ { -+ mask = mask >> 1; -+ first++; -+ } -+ -+ while (mask & 0x1) -+ { -+ mask = mask >> 1; -+ len++; -+ } -+ } -+ -+ *pos = first; -+ *size = len; -+} -+ -+static void -+setup_pixel_info (struct screen_info *si, grub_efi_uint32_t pixels_per_scan_line, -+ struct grub_efi_gop_pixel_bitmask pixel_info, int pixel_format) -+{ -+ if (pixel_format == GRUB_EFI_GOT_RGBA8) -+ { -+ si->lfb_depth = 32; -+ si->lfb_linelength = pixels_per_scan_line * 4; -+ si->red_size = 8; -+ si->red_pos = 0; -+ si->green_size = 8; -+ si->green_pos = 8; -+ si->blue_size = 8; -+ si->blue_pos = 16; -+ si->rsvd_size = 8; -+ si->rsvd_pos = 24; -+ } -+ else if (pixel_format == GRUB_EFI_GOT_BGRA8) -+ { -+ si->lfb_depth = 32; -+ si->lfb_linelength = pixels_per_scan_line * 4; -+ si->red_size = 8; -+ si->red_pos = 16; -+ si->green_size = 8; -+ si->green_pos = 8; -+ si->blue_size = 8; -+ si->blue_pos = 0; -+ si->rsvd_size = 8; -+ si->rsvd_pos = 24; -+ } -+ else if (pixel_format == GRUB_EFI_GOT_BITMASK) -+ { -+ find_bits(pixel_info.r, &si->red_pos, &si->red_size); -+ find_bits(pixel_info.g, &si->green_pos, &si->green_size); -+ find_bits(pixel_info.b, &si->blue_pos, &si->blue_size); -+ find_bits(pixel_info.a, &si->rsvd_pos, &si->rsvd_size); -+ si->lfb_depth = si->red_size + si->green_size + -+ si->blue_size + si->rsvd_size; -+ si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8; -+ } -+ else -+ { -+ si->lfb_depth = 4; -+ si->lfb_linelength = si->lfb_width / 2; -+ si->red_size = 0; -+ si->red_pos = 0; -+ si->green_size = 0; -+ si->green_pos = 0; -+ si->blue_size = 0; -+ si->blue_pos = 0; -+ si->rsvd_size = 0; -+ si->rsvd_pos = 0; -+ } -+} -+ -+static struct screen_info * -+alloc_screen_info (void) -+{ -+ grub_efi_status_t status; -+ grub_efi_boot_services_t *b; -+ struct screen_info *si; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_3 (b->allocate_pool, GRUB_EFI_RUNTIME_SERVICES_DATA, -+ sizeof(*si), (void**)&si); -+ if (status != GRUB_EFI_SUCCESS) -+ return NULL; -+ -+ status = b->install_configuration_table (&screen_info_guid, si); -+ if (status == GRUB_EFI_SUCCESS) -+ return si; -+ -+ efi_call_1 (b->free_pool, si); -+ -+ return NULL; -+} -+ -+static struct screen_info * -+setup_screen_info (void) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_handle_t gop_handle; -+ struct screen_info *si = NULL; -+ struct grub_efi_gop *gop, *first_gop; -+ grub_efi_handle_t *handles; -+ grub_efi_uintn_t num_handles, i; -+ grub_efi_guid_t graphics_output_guid = GRUB_EFI_GOP_GUID; -+ grub_efi_uint16_t width, height; -+ grub_efi_uint32_t ext_lfb_base, pixels_per_scan_line; -+ grub_efi_uint64_t fb_base; -+ struct grub_efi_gop_pixel_bitmask pixel_info; -+ grub_efi_gop_pixel_format_t pixel_format; -+ -+ si = alloc_screen_info(); -+ if (!si) -+ return NULL; -+ -+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, -+ &graphics_output_guid, NULL, &num_handles); -+ if (!handles || num_handles == 0) -+ goto free_screen_info; -+ -+ gop = NULL; -+ first_gop = NULL; -+ -+ for (i = 0; i < num_handles; i++) -+ { -+ struct grub_efi_gop_mode *mode; -+ struct grub_efi_gop_mode_info *info = NULL; -+ grub_efi_guid_t conout_proto = GRUB_EFI_LARCH_CONSOLE_OUT_DEVICE_GUID; -+ void *dummy = NULL; -+ grub_efi_uint8_t conout_found = 0; -+ grub_efi_uint64_t current_fb_base; -+ -+ gop_handle = handles[i]; -+ gop = grub_efi_open_protocol (gop_handle, &graphics_output_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ -+ dummy = grub_efi_open_protocol (gop_handle, &conout_proto, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ if (dummy != NULL) -+ conout_found = 1; -+ -+ mode = gop->mode; -+ info = mode->info; -+ current_fb_base = mode->fb_base; -+ -+ if ((!first_gop || conout_found) && -+ info->pixel_format != GRUB_EFI_GOT_BLT_ONLY) -+ { -+ /* -+ * Systems that use the UEFI Console Splitter may -+ * provide multiple GOP devices, not all of which are -+ * backed by real hardware. The workaround is to search -+ * for a GOP implementing the ConOut protocol, and if -+ * one isn't found, to just fall back to the first GOP. -+ */ -+ width = info->width; -+ height = info->height; -+ pixel_format = info->pixel_format; -+ pixel_info = info->pixel_bitmask; -+ pixels_per_scan_line = info->pixels_per_scanline; -+ fb_base = current_fb_base; -+ -+ /* -+ * Once we've found a GOP supporting ConOut, -+ * don't bother looking any further. -+ */ -+ first_gop = gop; -+ if (conout_found) -+ break; -+ } -+ } -+ -+ /* Did we find any GOPs? */ -+ if (!first_gop) -+ goto free_screen_info; -+ -+ /* EFI framebuffer */ -+ si->orig_video_isVGA = GRUB_VIDEO_TYPE_EFI; -+ -+ si->lfb_width = width; -+ si->lfb_height = height; -+ si->lfb_base = fb_base; -+ grub_dprintf ("loongson", "Screen info fb base: 0x%"PRIxGRUB_UINT32_T"\n", -+ si->lfb_base); -+ -+ ext_lfb_base = (grub_uint64_t)fb_base >> 32; -+ if (ext_lfb_base) { -+ si->capabilities |= GRUB_VIDEO_CAPABILITY_64BIT_BASE; -+ si->ext_lfb_base = ext_lfb_base; -+ } -+ si->pages = 1; -+ -+ setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format); -+ -+ si->lfb_size = si->lfb_linelength * si->lfb_height; -+ si->capabilities |= GRUB_VIDEO_CAPABILITY_SKIP_QUIRKS; -+ -+ return si; -+ -+free_screen_info: -+ b = grub_efi_system_table->boot_services; -+ b->install_configuration_table (&screen_info_guid, NULL); -+ if (si) -+ efi_call_1 (b->free_pool, si); -+ -+ grub_dprintf ("loongson", "No screen info\n"); -+ return NULL; -+} -+ - static grub_err_t - allocate_fdt_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) - { -@@ -242,6 +472,8 @@ grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_param - struct grub_relocator64_state state; - grub_err_t err; - -+ setup_screen_info (); -+ - /* linux kernel type is ELF */ - grub_memset (&state, 0, sizeof (state)); - -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -index f4b198a..c010982 100644 ---- a/include/grub/loongarch64/linux.h -+++ b/include/grub/loongarch64/linux.h -@@ -79,6 +79,53 @@ struct linux_loongarch64_kernel_params - sizeof (FDT_ADDR_CELLS_STRING) + \ - sizeof (FDT_SIZE_CELLS_STRING)) - -+/* -+ * These are set up by the setup-routine at boot-time: -+ */ -+struct screen_info { -+ grub_efi_uint8_t orig_x; /* 0x00 */ -+ grub_efi_uint8_t orig_y; /* 0x01 */ -+ grub_efi_uint16_t ext_mem_k; /* 0x02 */ -+ grub_efi_uint16_t orig_video_page; /* 0x04 */ -+ grub_efi_uint8_t orig_video_mode; /* 0x06 */ -+ grub_efi_uint8_t orig_video_cols; /* 0x07 */ -+ grub_efi_uint8_t flags; /* 0x08 */ -+ grub_efi_uint8_t unused2; /* 0x09 */ -+ grub_efi_uint16_t orig_video_ega_bx;/* 0x0a */ -+ grub_efi_uint16_t unused3; /* 0x0c */ -+ grub_efi_uint8_t orig_video_lines; /* 0x0e */ -+ grub_efi_uint8_t orig_video_isVGA; /* 0x0f */ -+ grub_efi_uint16_t orig_video_points;/* 0x10 */ -+ -+ /* VESA graphic mode -- linear frame buffer */ -+ grub_efi_uint16_t lfb_width; /* 0x12 */ -+ grub_efi_uint16_t lfb_height; /* 0x14 */ -+ grub_efi_uint16_t lfb_depth; /* 0x16 */ -+ grub_efi_uint32_t lfb_base; /* 0x18 */ -+ grub_efi_uint32_t lfb_size; /* 0x1c */ -+ grub_efi_uint16_t cl_magic, cl_offset; /* 0x20 */ -+ grub_efi_uint16_t lfb_linelength; /* 0x24 */ -+ grub_efi_uint8_t red_size; /* 0x26 */ -+ grub_efi_uint8_t red_pos; /* 0x27 */ -+ grub_efi_uint8_t green_size; /* 0x28 */ -+ grub_efi_uint8_t green_pos; /* 0x29 */ -+ grub_efi_uint8_t blue_size; /* 0x2a */ -+ grub_efi_uint8_t blue_pos; /* 0x2b */ -+ grub_efi_uint8_t rsvd_size; /* 0x2c */ -+ grub_efi_uint8_t rsvd_pos; /* 0x2d */ -+ grub_efi_uint16_t vesapm_seg; /* 0x2e */ -+ grub_efi_uint16_t vesapm_off; /* 0x30 */ -+ grub_efi_uint16_t pages; /* 0x32 */ -+ grub_efi_uint16_t vesa_attributes; /* 0x34 */ -+ grub_efi_uint32_t capabilities; /* 0x36 */ -+ grub_efi_uint32_t ext_lfb_base; /* 0x3a */ -+ grub_efi_uint8_t _reserved[2]; /* 0x3e */ -+} __attribute__((packed)); -+ -+#define GRUB_VIDEO_TYPE_EFI 0x70 -+#define GRUB_VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0) -+#define GRUB_VIDEO_CAPABILITY_64BIT_BASE (1 << 1) /* Frame buffer base is 64-bit */ -+ - /* From arch/loongarch/include/asm/mach-loongson64/boot_param.h */ - struct _extention_list_hdr { - grub_uint64_t signature; --- -2.33.0 - diff --git a/1003-loongarch-Add-support-for-v4.0-interface.patch b/1003-loongarch-Add-support-for-v4.0-interface.patch deleted file mode 100644 index 8629604..0000000 --- a/1003-loongarch-Add-support-for-v4.0-interface.patch +++ /dev/null @@ -1,434 +0,0 @@ -From d984a64ff93443630fde3211e1a8ec42d92a6b56 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Mon, 13 Feb 2023 14:40:16 +0800 -Subject: [PATCH] loongarch: Add support for v4.0 interface - -This patch adds support for parameter passing converntion -between bootloader and kernel, defined in the document -"loongson devsys firmware kernel interface specification v4.0" - -Signed-off-by: yangqiming -Signed-off-by: mengyingkun ---- - grub-core/lib/loongarch64/relocator.c | 2 +- - grub-core/loader/loongarch64/linux-elf.c | 177 ++++++++++++++++++++--- - grub-core/loader/loongarch64/linux.c | 49 ++----- - include/grub/loongarch64/linux.h | 20 +++ - 4 files changed, 190 insertions(+), 58 deletions(-) - -diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c -index faa4553..587fc58 100644 ---- a/grub-core/lib/loongarch64/relocator.c -+++ b/grub-core/lib/loongarch64/relocator.c -@@ -122,7 +122,7 @@ grub_relocator64_boot (struct grub_relocator *rel, - unsigned i; - grub_addr_t vtarget; - -- err = grub_relocator_alloc_chunk_align (rel, &ch, 0, -+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0x3000000, - (0xffffffff - stateset_size) - + 1, stateset_size, - grub_relocator_align, -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 852e8f4..15f9984 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -25,11 +25,14 @@ - #include - #include - -+#define GRUB_EFI_MMAP_NR_SLACK_SLOTS 8 -+ - #define GRUB_ADDRESS_TYPE_SYSRAM 1 - #define GRUB_ADDRESS_TYPE_RESERVED 2 - #define GRUB_ADDRESS_TYPE_ACPI 3 - #define GRUB_ADDRESS_TYPE_NVS 4 - #define GRUB_ADDRESS_TYPE_PMEM 5 -+ - #define GRUB_EFI_LOONGSON_BPI_TABLE_GUID \ - { 0x4660f721, 0x2ec5, 0x416a, \ - { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ -@@ -45,6 +48,16 @@ - { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -+#define GRUB_EFI_LARCH_BOOT_MEMMAP_GUID \ -+ { 0x800f683f, 0xd08b, 0x423a, \ -+ { 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4 } \ -+ } -+ -+#define GRUB_EFI_LARCH_INITRD_MEDIA_GUID \ -+ { 0x5568e427, 0x68fc, 0x4f3d, \ -+ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ -+ } -+ - static struct grub_relocator *relocator; - static grub_efi_guid_t screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; - -@@ -271,6 +284,135 @@ free_screen_info: - return NULL; - } - -+static grub_err_t -+allocate_memmap_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) -+{ -+ grub_err_t err; -+ grub_efi_status_t status; -+ grub_efi_uintn_t mmap_size, desc_size, size; -+ grub_efi_uint32_t desc_version; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ grub_efi_boot_services_t *b; -+ struct efi_boot_memmap *m, tmp; -+ struct efi_initrd *tbl = NULL; -+ grub_efi_guid_t boot_memmap_guid = GRUB_EFI_LARCH_BOOT_MEMMAP_GUID; -+ grub_efi_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; -+ -+ setup_screen_info(); -+ -+ b = grub_efi_system_table->boot_services; -+ -+ grub_dprintf ("loongson", "ramdisk_addr:0x%"PRIxGRUB_UINT64_T", \ -+ size:0x%"PRIxGRUB_UINT64_T"\n", -+ kernel_params->ramdisk_addr, -+ kernel_params->ramdisk_size); -+#if 0 -+ char string[64]; -+ -+ /* Set initrd info to cmdline*/ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ grub_printf ( "Initrd @ %p-%p\n", -+ (void *) kernel_params->ramdisk_addr, -+ (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -+ /* initrd */ -+ grub_snprintf (string, -+ sizeof (GRUB_INITRD_STRING), -+ "initrd=0x%lx,0x%lx", -+ ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), -+ (grub_uint64_t) kernel_params->ramdisk_size); -+ *(char*) ((grub_addr_t) kernel_params->linux_args + kernel_params->ramdisk_args_len - 2) = ' '; -+ grub_memcpy ((char*) ((grub_addr_t) kernel_params->linux_args + kernel_params->ramdisk_args_len - 1), -+ string, sizeof (GRUB_INITRD_STRING)); -+ } -+#else -+ /* Set initrd info to system table*/ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ tbl = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ if (!tbl) -+ return grub_error (GRUB_ERR_IO, "cannot allocate tbl memory"); -+ tbl->base = kernel_params->ramdisk_addr; -+ tbl->size = kernel_params->ramdisk_size; -+ -+ status = b->install_configuration_table (&initrd_media_guid, tbl); -+ if (status != GRUB_EFI_SUCCESS) { -+ grub_error (GRUB_ERR_IO, "failed to install initrd media"); -+ goto free_tbl; -+ } -+ } -+#endif -+ -+ tmp.map_size = 0; -+ status = grub_efi_get_memory_map (&tmp.map_size, NULL, &tmp.map_key, -+ &tmp.desc_size, &tmp.desc_ver); -+ if (status != 0) { -+ grub_error (GRUB_ERR_IO, "cannot get memory map"); -+ goto uninstall_initrd_table; -+ } -+ size = tmp.map_size + tmp.desc_size * GRUB_EFI_MMAP_NR_SLACK_SLOTS; -+ m = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(*m) + size)); -+ if (!m) { -+ grub_error (GRUB_ERR_IO, "cannot allocate m memory"); -+ goto uninstall_initrd_table; -+ } -+ -+ status = b->install_configuration_table (&boot_memmap_guid, m); -+ if (status != GRUB_EFI_SUCCESS) { -+ grub_error (GRUB_ERR_IO, "failed to install boot memmap"); -+ goto free_m; -+ } -+ -+ m->buff_size = m->map_size = size; -+ if (grub_efi_get_memory_map (&m->map_size, m->map, -+ &m->map_key, &m->desc_size, -+ &m->desc_ver) <= 0) -+ { -+ grub_error (GRUB_ERR_IO, "cannot get EFI memory map"); -+ goto uninstall_mem_table; -+ } -+ -+ mmap_size = grub_efi_find_mmap_size (); -+ if (! mmap_size) -+ goto uninstall_mem_table; -+ -+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, &desc_version); -+ if (err) { -+ grub_error (GRUB_ERR_IO, "failed to finish boot services"); -+ goto free_map; -+ } -+ -+ return 0; -+ -+free_map: -+ if (mmap_buf) -+ grub_efi_free_pages ((grub_addr_t) mmap_buf, -+ GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ -+uninstall_mem_table: -+ b->install_configuration_table (&boot_memmap_guid, NULL); -+ -+free_m: -+ if (m) -+ grub_efi_free_pages ((grub_addr_t) m, -+ GRUB_EFI_BYTES_TO_PAGES (sizeof(*m) + size)); -+ -+uninstall_initrd_table: -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ b->install_configuration_table (&initrd_media_guid, NULL); -+ -+free_tbl: -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) { -+ if (tbl) -+ grub_efi_free_pages ((grub_addr_t) tbl, -+ GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ } -+ -+ return grub_error(GRUB_ERR_BAD_OS, "failed to V40 boot"); -+} -+ - static grub_err_t - allocate_fdt_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) - { -@@ -400,12 +542,11 @@ grub_linux_loongarch_elf_make_argv (struct linux_loongarch64_kernel_params *kern - } - - if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- { -- size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4) \ -- + ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4) \ -- + ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -- 4); -- } -+ { -+ size += ALIGN_UP (sizeof (GRUB_RD_START_STRING), 4) -+ + ALIGN_UP (sizeof (GRUB_RD_SIZE_STRING), 4) -+ + ALIGN_UP (sizeof (GRUB_INITRD_STRING), 4); -+ } - size = ALIGN_UP (size, 8); - - /* alloc memory */ -@@ -427,33 +568,33 @@ grub_linux_loongarch_elf_make_argv (struct linux_loongarch64_kernel_params *kern - { - /* rd_start */ - grub_snprintf (linux_args, -- sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), -+ sizeof (GRUB_RD_START_STRING), - "rd_start=0x%lx", - (grub_uint64_t) kernel_params->ramdisk_addr); - *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; - linux_argv++; -- linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); -+ linux_args += ALIGN_UP (sizeof (GRUB_RD_START_STRING), 4); - kernel_params->linux_argc++; - - /* rd_size */ - grub_snprintf (linux_args, -- sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), -+ sizeof (GRUB_RD_SIZE_STRING), - "rd_size=0x%lx", - (grub_uint64_t) kernel_params->ramdisk_size); - *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; - linux_argv++; -- linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); -+ linux_args += ALIGN_UP (sizeof (GRUB_RD_SIZE_STRING), 4); - kernel_params->linux_argc++; - - /* initrd */ - grub_snprintf (linux_args, -- sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -+ sizeof (GRUB_INITRD_STRING), - "initrd=0x%lx,0x%lx", - ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), - (grub_uint64_t) kernel_params->ramdisk_size); - *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; - linux_argv++; -- linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); -+ linux_args += ALIGN_UP (sizeof (GRUB_INITRD_STRING), 4); - kernel_params->linux_argc++; - } - -@@ -472,8 +613,6 @@ grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_param - struct grub_relocator64_state state; - grub_err_t err; - -- setup_screen_info (); -- - /* linux kernel type is ELF */ - grub_memset (&state, 0, sizeof (state)); - -@@ -481,14 +620,14 @@ grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_param - state.gpr[1] = kernel_params->kernel_addr; /* ra */ - if (grub_linux_loongarch_elf_get_boot_params (&boot_params) == 0) - { -- grub_printf("not find param, is fdt boot\n"); -- if (allocate_fdt_and_exit_boot (kernel_params) != GRUB_ERR_NONE) -+ grub_dprintf("loongson", "V4.0 boot\n"); -+ if (allocate_memmap_and_exit_boot (kernel_params) != GRUB_ERR_NONE) - return grub_errno; - state.gpr[4] = 1 << FLAGS_EFI_SUPPORT_BIT; /* a0 = flag */ -- state.gpr[5] = (grub_uint64_t)kernel_params->fdt; /* a1 = fdt */ -- state.gpr[6] = 0; /* a2 = flag */ -+ state.gpr[5] = (grub_uint64_t)kernel_params->linux_args; /* a1 = cmdline */ -+ state.gpr[6] = (grub_uint64_t)grub_efi_system_table; /* a2 = system_table */ - } else { -- grub_printf("find param, is bpi boot\n"); -+ grub_dprintf("loongson", "BPI boot\n"); - grub_linux_loongarch_elf_make_argv (kernel_params); - state.gpr[4] = kernel_params->linux_argc; /* a0 = argc */ - state.gpr[5] = kernel_params->linux_argv; /* a1 = args */ -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -index 4c02194..03b7940 100644 ---- a/grub-core/loader/loongarch64/linux.c -+++ b/grub-core/loader/loongarch64/linux.c -@@ -230,7 +230,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_dprintf ("linux", "kernel @ %p\n", (void*) kernel_params.kernel_addr); - } - -- cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); -+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE) -+ + sizeof (GRUB_INITRD_STRING); -+ kernel_params.ramdisk_args_len = grub_loader_cmdline_size (argc, argv) -+ + sizeof (LINUX_IMAGE); - kernel_params.linux_argc = argc; - kernel_params.linux_args = grub_malloc (cmdline_size); - if (!kernel_params.linux_args) -@@ -250,7 +253,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - { - err = grub_create_loader_cmdline (argc, argv, - (char*) ((grub_addr_t) kernel_params.linux_args + sizeof (LINUX_IMAGE) - 1), -- cmdline_size, -+ kernel_params.ramdisk_args_len, - GRUB_VERIFY_KERNEL_CMDLINE); - if (err) - goto fail; -@@ -299,26 +302,6 @@ fail: - return grub_errno; - } - --/* -- * This function returns a pointer to a legally allocated initrd buffer, -- * or NULL if unsuccessful -- */ --static void * --allocate_initrd_mem (int initrd_pages) --{ -- grub_addr_t max_addr; -- -- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) -- return NULL; -- -- max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; -- -- return grub_efi_allocate_pages_real (max_addr, initrd_pages, -- GRUB_EFI_ALLOCATE_MAX_ADDRESS, -- GRUB_EFI_LOADER_DATA); --} -- -- - static grub_err_t - grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) -@@ -326,6 +309,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - grub_size_t initrd_size; - void *initrd_mem = NULL; -+ grub_err_t err; - - if (argc == 0) - { -@@ -345,16 +329,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - initrd_size = grub_get_initrd_size (&initrd_ctx); - grub_dprintf ("linux", "Loading initrd\n"); - -- if (is_bpi_boot == 0) { -- grub_size_t initrd_pages; -- initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); -- initrd_mem = allocate_initrd_mem (initrd_pages); -- } else { -- grub_err_t err; -- initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x10000, &err); -- if (err) -- goto fail; -- } -+ initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x1000, &err); -+ if (err) -+ goto fail; - - if (!initrd_mem) - { -@@ -369,14 +346,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - kernel_params.ramdisk_addr = (grub_addr_t) initrd_mem; - kernel_params.ramdisk_size = initrd_size; - grub_dprintf ("linux", "ramdisk [addr=%p, size=0x%lx]\n", -- (void *) initrd_mem, initrd_size); -+ (void *) initrd_mem, initrd_size); - fail: - grub_initrd_close (&initrd_ctx); -- if (is_bpi_boot == 0) { -- if (initrd_mem && !kernel_params.ramdisk_addr) -- grub_efi_free_pages ((grub_addr_t) initrd_mem, -- GRUB_EFI_BYTES_TO_PAGES (initrd_size)); -- } -+ - return grub_errno; - } - -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -index c010982..f20a719 100644 ---- a/include/grub/loongarch64/linux.h -+++ b/include/grub/loongarch64/linux.h -@@ -59,6 +59,7 @@ struct linux_loongarch64_kernel_params - grub_size_t kernel_size; /* kernel size */ - grub_addr_t ramdisk_addr; /* initrd load address */ - grub_size_t ramdisk_size; /* initrd size */ -+ int ramdisk_args_len; /* position of initrd in linux_args */ - int linux_argc; /* cmdline parameters number*/ - grub_addr_t linux_argv; /* cmdline parameters address*/ - void* linux_args; -@@ -73,12 +74,31 @@ struct linux_loongarch64_kernel_params - #define ELF64_LOADMASK (0xf000000000000000ULL) - #define FLAGS_EFI_SUPPORT_BIT 0 - -+/*initrd info*/ -+#define GRUB_RD_START_STRING "rd_start=0xXXXXXXXXXXXXXXXX" -+#define GRUB_RD_SIZE_STRING "rd_size=0xXXXXXXXXXXXXXXXX" -+#define GRUB_INITRD_STRING "initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX" -+ - #define FDT_ADDR_CELLS_STRING "#address-cells" - #define FDT_SIZE_CELLS_STRING "#size-cells" - #define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ - sizeof (FDT_ADDR_CELLS_STRING) + \ - sizeof (FDT_SIZE_CELLS_STRING)) - -+struct efi_boot_memmap { -+ grub_efi_uintn_t map_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_uint32_t desc_ver; -+ grub_efi_uintn_t map_key; -+ grub_efi_uintn_t buff_size; -+ grub_efi_memory_descriptor_t map[]; -+}; -+ -+struct efi_initrd { -+ grub_efi_uintn_t base; -+ grub_efi_uintn_t size; -+}; -+ - /* - * These are set up by the setup-routine at boot-time: - */ --- -2.33.0 - diff --git a/1004-loongarch-Add-support-for-new-EFI-screen-info-GUID.patch b/1004-loongarch-Add-support-for-new-EFI-screen-info-GUID.patch deleted file mode 100644 index de359aa..0000000 --- a/1004-loongarch-Add-support-for-new-EFI-screen-info-GUID.patch +++ /dev/null @@ -1,62 +0,0 @@ -From dc3d6e1b080e61a02a8e02e090e3910ca168e616 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Fri, 10 Mar 2023 11:00:51 +0800 -Subject: [PATCH] loongarch: Add support for new EFI screen info GUID - -Support new screen info GUID defined by upstream kernel, and -keep compatible with old GUID defined by loongson. - -Signed-off-by: mengyingkun ---- - grub-core/loader/loongarch64/linux-elf.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 15f9984..86a90e7 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -58,8 +58,14 @@ - { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ - } - -+#define GRUB_EFI_SCREEN_INFO_GUID \ -+ { 0xe03fc20a, 0x85dc, 0x406e, \ -+ { 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95 } \ -+ } -+ - static struct grub_relocator *relocator; --static grub_efi_guid_t screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; -+static grub_efi_guid_t compat_screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; -+static grub_efi_guid_t screen_info_guid = GRUB_EFI_SCREEN_INFO_GUID; - - void grub_linux_loongarch_elf_relocator_unload (void) - { -@@ -161,10 +167,17 @@ alloc_screen_info (void) - if (status != GRUB_EFI_SUCCESS) - return NULL; - -+ status = b->install_configuration_table (&compat_screen_info_guid, si); -+ if (status != GRUB_EFI_SUCCESS) -+ goto free_mem; -+ - status = b->install_configuration_table (&screen_info_guid, si); - if (status == GRUB_EFI_SUCCESS) - return si; - -+free_table: -+ b->install_configuration_table (&compat_screen_info_guid, NULL); -+free_mem: - efi_call_1 (b->free_pool, si); - - return NULL; -@@ -276,6 +289,7 @@ setup_screen_info (void) - - free_screen_info: - b = grub_efi_system_table->boot_services; -+ b->install_configuration_table (&compat_screen_info_guid, NULL); - b->install_configuration_table (&screen_info_guid, NULL); - if (si) - efi_call_1 (b->free_pool, si); --- -2.33.0 - diff --git a/1005-loongarch-Force-initrd-load-address-64KiB-alignment.patch b/1005-loongarch-Force-initrd-load-address-64KiB-alignment.patch deleted file mode 100644 index 1d460b5..0000000 --- a/1005-loongarch-Force-initrd-load-address-64KiB-alignment.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 1107e231094bf2e6cde9daea3bb22b1fccb92bc5 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Sat, 18 Mar 2023 09:33:41 +0800 -Subject: [PATCH] loongarch: Force initrd load address 64KiB alignment - -Signed-off-by: mengyingkun ---- - grub-core/loader/loongarch64/linux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -index 03b7940..5f1d845 100644 ---- a/grub-core/loader/loongarch64/linux.c -+++ b/grub-core/loader/loongarch64/linux.c -@@ -329,7 +329,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - initrd_size = grub_get_initrd_size (&initrd_ctx); - grub_dprintf ("linux", "Loading initrd\n"); - -- initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x1000, &err); -+ initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x10000, &err); - if (err) - goto fail; - --- -2.33.0 - diff --git a/1006-loongarch-Implement-cache-synchronization-operation.patch b/1006-loongarch-Implement-cache-synchronization-operation.patch deleted file mode 100644 index bbe927b..0000000 --- a/1006-loongarch-Implement-cache-synchronization-operation.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7dccf456ce7fe693c6e488a812dc8f14ea592eeb Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Wed, 22 Mar 2023 09:29:42 +0800 -Subject: [PATCH] loongarch: Implement cache synchronization operation - -When the module is loaded, ICACHE and DCACHE need to flush -before calling init function. If the caches are not flushed, -loader will crash unexpectedly. - -Signed-off-by: mengyingkun ---- - grub-core/kern/loongarch64/cache.S | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/kern/loongarch64/cache.S b/grub-core/kern/loongarch64/cache.S -index d291c67..6e32d37 100644 ---- a/grub-core/kern/loongarch64/cache.S -+++ b/grub-core/kern/loongarch64/cache.S -@@ -19,6 +19,8 @@ - #include - - FUNCTION (grub_arch_sync_caches) -+ ibar 0 -+ dbar 0 - jr $ra - - FUNCTION (grub_arch_sync_dma_caches) --- -2.33.0 - diff --git a/1007-loongarch-Fix-the-initrd-parameter-passing.patch b/1007-loongarch-Fix-the-initrd-parameter-passing.patch deleted file mode 100644 index 93a0747..0000000 --- a/1007-loongarch-Fix-the-initrd-parameter-passing.patch +++ /dev/null @@ -1,276 +0,0 @@ -From 3881d41c2fcd1eece2faca8b08577e8e8b30257c Mon Sep 17 00:00:00 2001 -From: Yingkun Meng -Date: Mon, 7 Aug 2023 11:47:54 +0800 -Subject: [PATCH] loongarch: Fix the initrd parameter passing - -When booting with EFI kernel, the kernel can't get -initrd parameter, resulting in the inability to -find the initrd. - -Change-Id: I61c6cee35853cd3ee5ce98a0bce949f6833d85b1 -Signed-off-by: Yingkun Meng ---- - grub-core/loader/loongarch64/linux-efi.c | 44 +--------------- - grub-core/loader/loongarch64/linux-elf.c | 53 +++---------------- - grub-core/loader/loongarch64/linux.c | 66 ++++++++++++++++++++++++ - include/grub/loongarch64/linux.h | 6 +++ - 4 files changed, 80 insertions(+), 89 deletions(-) - -diff --git a/grub-core/loader/loongarch64/linux-efi.c b/grub-core/loader/loongarch64/linux-efi.c -index 4dcefd9d9e27..8e2726163725 100644 ---- a/grub-core/loader/loongarch64/linux-efi.c -+++ b/grub-core/loader/loongarch64/linux-efi.c -@@ -16,11 +16,9 @@ - * along with GRUB. If not, see . - */ - #include --#include - #include - #include - #include --#include - #include - - #define GRUB_EFI_PE_MAGIC 0x5A4D -@@ -28,47 +26,7 @@ - grub_err_t - finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params) - { -- int node, retval; -- -- void *fdt; -- -- fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE); -- -- if (!fdt) -- goto failure; -- -- node = grub_fdt_find_subnode (fdt, 0, "chosen"); -- if (node < 0) -- node = grub_fdt_add_subnode (fdt, 0, "chosen"); -- -- if (node < 1) -- goto failure; -- -- /* Set initrd info */ -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- { -- grub_dprintf ("linux", "Initrd @ %p-%p\n", -- (void *) kernel_params->ramdisk_addr, -- (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -- -- retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", -- kernel_params->ramdisk_addr); -- if (retval) -- goto failure; -- retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", -- kernel_params->ramdisk_addr + kernel_params->ramdisk_size); -- if (retval) -- goto failure; -- } -- -- if (grub_fdt_install() != GRUB_ERR_NONE) -- goto failure; -- -- return GRUB_ERR_NONE; -- --failure: -- grub_fdt_unload(); -- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+ return grub_loongarch_setup_initrd_params(); - } - - grub_err_t -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 86a90e76b4c3..28d3c90ad6e6 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -308,54 +308,22 @@ allocate_memmap_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_pa - grub_efi_memory_descriptor_t *mmap_buf; - grub_efi_boot_services_t *b; - struct efi_boot_memmap *m, tmp; -- struct efi_initrd *tbl = NULL; - grub_efi_guid_t boot_memmap_guid = GRUB_EFI_LARCH_BOOT_MEMMAP_GUID; -- grub_efi_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; - - setup_screen_info(); - -- b = grub_efi_system_table->boot_services; -- - grub_dprintf ("loongson", "ramdisk_addr:0x%"PRIxGRUB_UINT64_T", \ - size:0x%"PRIxGRUB_UINT64_T"\n", - kernel_params->ramdisk_addr, - kernel_params->ramdisk_size); --#if 0 -- char string[64]; - -- /* Set initrd info to cmdline*/ -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- { -- grub_printf ( "Initrd @ %p-%p\n", -- (void *) kernel_params->ramdisk_addr, -- (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -- /* initrd */ -- grub_snprintf (string, -- sizeof (GRUB_INITRD_STRING), -- "initrd=0x%lx,0x%lx", -- ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), -- (grub_uint64_t) kernel_params->ramdisk_size); -- *(char*) ((grub_addr_t) kernel_params->linux_args + kernel_params->ramdisk_args_len - 2) = ' '; -- grub_memcpy ((char*) ((grub_addr_t) kernel_params->linux_args + kernel_params->ramdisk_args_len - 1), -- string, sizeof (GRUB_INITRD_STRING)); -- } --#else - /* Set initrd info to system table*/ -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- { -- tbl = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -- if (!tbl) -- return grub_error (GRUB_ERR_IO, "cannot allocate tbl memory"); -- tbl->base = kernel_params->ramdisk_addr; -- tbl->size = kernel_params->ramdisk_size; -- -- status = b->install_configuration_table (&initrd_media_guid, tbl); -- if (status != GRUB_EFI_SUCCESS) { -- grub_error (GRUB_ERR_IO, "failed to install initrd media"); -- goto free_tbl; -+ err = grub_loongarch_setup_initrd_params(); -+ if (err != GRUB_ERR_NONE) -+ { -+ grub_error(GRUB_ERR_IO, "failed to install initrd media"); -+ return err; - } -- } --#endif - - tmp.map_size = 0; - status = grub_efi_get_memory_map (&tmp.map_size, NULL, &tmp.map_key, -@@ -371,6 +339,7 @@ allocate_memmap_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_pa - goto uninstall_initrd_table; - } - -+ b = grub_efi_system_table->boot_services; - status = b->install_configuration_table (&boot_memmap_guid, m); - if (status != GRUB_EFI_SUCCESS) { - grub_error (GRUB_ERR_IO, "failed to install boot memmap"); -@@ -414,15 +383,7 @@ free_m: - GRUB_EFI_BYTES_TO_PAGES (sizeof(*m) + size)); - - uninstall_initrd_table: -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- b->install_configuration_table (&initrd_media_guid, NULL); -- --free_tbl: -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) { -- if (tbl) -- grub_efi_free_pages ((grub_addr_t) tbl, -- GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -- } -+ grub_loongarch_remove_initrd_params(); - - return grub_error(GRUB_ERR_BAD_OS, "failed to V40 boot"); - } -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -index 5f1d8453b090..0b65249e64d9 100644 ---- a/grub-core/loader/loongarch64/linux.c -+++ b/grub-core/loader/loongarch64/linux.c -@@ -29,6 +29,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); - - #define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) - -+#define GRUB_EFI_LARCH_INITRD_MEDIA_GUID \ -+ { 0x5568e427, 0x68fc, 0x4f3d, \ -+ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ -+ } -+ - static struct linux_loongarch64_kernel_params kernel_params; - - static grub_addr_t phys_addr; -@@ -36,6 +41,67 @@ static grub_dl_t my_mod; - static int loaded; - static int is_bpi_boot; - static int grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_BAD; -+struct efi_initrd *initrd_tbl; -+ -+grub_err_t -+grub_loongarch_setup_initrd_params (void) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; -+ grub_efi_status_t status; -+ -+ if (!kernel_params.ramdisk_addr || !kernel_params.ramdisk_size) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("you need to load the initrd first")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ /* Set initrd info to system table*/ -+ b = grub_efi_system_table->boot_services; -+ initrd_tbl = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ if (!initrd_tbl) -+ return grub_error (GRUB_ERR_IO, "cannot allocate tbl memory"); -+ -+ initrd_tbl->base = kernel_params.ramdisk_addr; -+ initrd_tbl->size = kernel_params.ramdisk_size; -+ status = b->install_configuration_table (&initrd_media_guid, initrd_tbl); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_IO, "failed to install initrd media"); -+ goto free_tbl; -+ } -+ -+ return GRUB_ERR_NONE; -+ -+free_tbl: -+ if (initrd_tbl) -+ { -+ grub_efi_free_pages ((grub_addr_t) initrd_tbl, -+ GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ } -+ -+ return GRUB_ERR_IO; -+} -+ -+void -+grub_loongarch_remove_initrd_params (void) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; -+ -+ if (!initrd_tbl) -+ return; -+ -+ b = grub_efi_system_table->boot_services; -+ b->install_configuration_table (&initrd_media_guid, NULL); -+ -+ grub_efi_free_pages ((grub_addr_t) initrd_tbl, -+ GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ -+ initrd_tbl = NULL; -+} -+ - - static grub_err_t - grub_linux_boot (void) -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -index f20a719b1386..462ce69cabd4 100644 ---- a/include/grub/loongarch64/linux.h -+++ b/include/grub/loongarch64/linux.h -@@ -179,6 +179,12 @@ struct loongsonlist_mem_map { - } GRUB_PACKED map[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; - }GRUB_PACKED; - -+grub_err_t -+grub_loongarch_setup_initrd_params (void); -+ -+void -+grub_loongarch_remove_initrd_params (void); -+ - grub_err_t - finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params); - --- -2.33.0 - diff --git a/1008-loongarch-Disable-relaxation-relocations.patch b/1008-loongarch-Disable-relaxation-relocations.patch deleted file mode 100644 index 0ee70f9..0000000 --- a/1008-loongarch-Disable-relaxation-relocations.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 115c628cc44f89207858d0c79e970e43da75c772 Mon Sep 17 00:00:00 2001 -From: Yingkun Meng -Date: Tue, 5 Dec 2023 19:22:14 +0800 -Subject: [PATCH] loongarch: Disable relaxation relocations - -commit 87247635c0d583cfbc1947107d23b40877d107b8 upstream. - -A working GRUB cannot be built with upcoming binutils and GCC, because linker -relaxation was added [1] causing new unsupported relocations to appear in modules. - -So we pass -mno-relax to GCC if it is supported, to disable relaxation and make -GRUB forward-compatible with new toolchains. - -While similar code already exists for sparc64 in configure.ac, sparc64 sets -LDFLAGS while LoongArch requires CFLAGS to be set. If we only set LDFLAGS on -LoongArch, GCC will still generate relaxation relocations in the .o files, so -the sparc64 code cannot be reused. - -[1] https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=56576f4a722b7398d35802ecf7d4185c27d6d69b - -Signed-off-by: Xiaotian Wu -Signed-off-by: Yingkun Meng -Change-Id: I09ef306dc8a0f8a59e9b7dbc53ae3fd3cc09ec55 ---- - configure.ac | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/configure.ac b/configure.ac -index 0db9d7d111b8..e010bc0db465 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -908,6 +908,29 @@ if test "x$target_cpu" = xloongarch64; then - TARGET_CFLAGS="$TARGET_CFLAGS -mno-explicit-relocs -fno-plt" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-explicit-relocs -fno-plt" - fi -+ -+ AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [ -+ grub_cv_target_cc_mno_relax=no -+ for cand in "-mno-relax" "-Wa,-mno-relax"; do -+ if test x"$grub_cv_target_cc_mno_relax" != xno ; then -+ break -+ fi -+ CFLAGS="$TARGET_CFLAGS $cand -Werror" -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -+ asm (".globl start; start:"); -+ void __main (void); -+ void __main (void) {} -+ int main (void); -+ ]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], []) -+ done -+ ]) -+ CFLAGS="$TARGET_CFLAGS" -+ -+ if test x"$grub_cv_target_cc_mno_relax" != xno ; then -+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_relax" -+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mno_relax" -+ fi -+ - TARGET_CFLAGS="$TARGET_CFLAGS -Wa,-mla-global-with-abs" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -Wa,-mla-global-with-abs" - fi --- -2.33.0 - diff --git a/Revert-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_C.patch b/Revert-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_C.patch deleted file mode 100644 index 6bc2c97..0000000 --- a/Revert-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_C.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 53b5629c9402e2d504866b6934303a8f8c2a5641 Mon Sep 17 00:00:00 2001 -From: Qiumiao Zhang -Date: Wed, 10 May 2023 19:11:17 +0800 -Subject: [PATCH] Revert "EFI: allocate kernel in EFI_RUNTIME_SERVICES_CODE - instead of EFI_LOADER_DATA." - -Allocates the kernel code as EFI_RUNTIME_SERVICES_CODE will cause the allocated -memory to be marked as "reserved" by BIOS, which will result in this memory being -always unavailable to the kernel. - -Let's fix it by reverting backport-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch. - -Signed-off-by: Qiumiao Zhang ---- - grub-core/loader/i386/efi/linux.c | 19 ++++++------------- - 1 file changed, 6 insertions(+), 13 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 92b2fb5..9e5c11a 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -86,9 +86,7 @@ kernel_free(void *addr, grub_efi_uintn_t size) - } - - static void * --kernel_alloc(grub_efi_uintn_t size, -- grub_efi_memory_type_t memtype, -- const char * const errmsg) -+kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) - { - void *addr = 0; - unsigned int i; -@@ -114,7 +112,7 @@ kernel_alloc(grub_efi_uintn_t size, - prev_max = max; - addr = grub_efi_allocate_pages_real (max, pages, - max_addresses[i].alloc_type, -- memtype); -+ GRUB_EFI_LOADER_DATA); - if (addr) - grub_dprintf ("linux", "Allocated at %p\n", addr); - } -@@ -244,8 +242,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) - } - } - -- initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA, -- N_("can't allocate initrd")); -+ initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); - if (initrd_mem == NULL) - goto fail; - grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); -@@ -396,8 +393,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - #endif - -- params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA, -- "cannot allocate kernel parameters"); -+ params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters"); - if (!params) - goto fail; - grub_dprintf ("linux", "params = %p\n", params); -@@ -419,9 +415,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_dprintf ("linux", "new lh is at %p\n", lh); - - grub_dprintf ("linux", "setting up cmdline\n"); -- cmdline = kernel_alloc (lh->cmdline_size + 1, -- GRUB_EFI_RUNTIME_SERVICES_DATA, -- N_("can't allocate cmdline")); -+ cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline")); - if (!cmdline) - goto fail; - grub_dprintf ("linux", "cmdline = %p\n", cmdline); -@@ -467,8 +461,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; - max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; - kernel_size = lh->init_size; -- kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE, -- N_("can't allocate kernel")); -+ kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel")); - restore_addresses(); - if (!kernel_mem) - goto fail; --- -2.19.1 - diff --git a/add-TPCM-support-with-ipmi-channel.patch b/add-TPCM-support-with-ipmi-channel.patch deleted file mode 100644 index d1511d9..0000000 --- a/add-TPCM-support-with-ipmi-channel.patch +++ /dev/null @@ -1,773 +0,0 @@ -From 2d7ef4b34427e1e1b2f55fdcc7868e7ce001a194 Mon Sep 17 00:00:00 2001 -From: "t.feng" -Date: Tue, 28 Feb 2023 16:25:30 +0800 -Subject: [PATCH] add tpcm support with ipmi channel - -t.feng(2): -add tpcm support with ipmi channel -use uefi hash interface - -zhangqiumiao(3): -reset response length when getting results failed -fix firmwarehash length and uiCmdLength error -clean code - -zhangqiumiao(4): -skip verification when just opening the grub.cfg without loading it -support control switch -modify GRUB_IPMI_TIMEOUT_MS from 7000 to 2000 - -Signed-off-by: "t.feng" -Signed-off-by: zhangqiumiao ---- - grub-core/Makefile.core.def | 6 + - grub-core/commands/efi/tpcm.c | 476 ++++++++++++++++++++++++++++++++++ - include/grub/efi/tpcm.h | 236 +++++++++++++++++ - 3 files changed, 718 insertions(+) - create mode 100644 grub-core/commands/efi/tpcm.c - create mode 100644 include/grub/efi/tpcm.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 6b00eb5..ee6ff17 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2564,6 +2564,12 @@ module = { - enable = efi; - }; - -+module = { -+ name = tpcm_kunpeng; -+ common = commands/efi/tpcm.c; -+ enable = efi; -+}; -+ - module = { - name = tr; - common = commands/tr.c; -diff --git a/grub-core/commands/efi/tpcm.c b/grub-core/commands/efi/tpcm.c -new file mode 100644 -index 0000000..57a4cea ---- /dev/null -+++ b/grub-core/commands/efi/tpcm.c -@@ -0,0 +1,476 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#define TRANS(value) (((value << 24 ) & 0xFF000000) | \ -+ ((value << 8 ) & 0x00FF0000) | \ -+ ((value >> 8 ) & 0x0000FF00) | \ -+ ((value >> 24 ) & 0x000000FF)) -+ -+static grub_efi_guid_t gIpmiInterfaceProtocolGuid = EFI_TPCM_GUID; -+static grub_efi_guid_t hash2_service_binding_guid = GRUB_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID; -+static grub_efi_guid_t hash2_guid = GRUB_EFI_HASH2_PROTOCOL_GUID; -+static grub_efi_guid_t sm3_guid = GRUB_HASH_ALGORITHM_SM3_GUID; -+ -+static grub_efi_ipmi_interface_protocol_t *tpcm_ipmi; -+static grub_efi_uint16_t grub_tcpm_file_type = GRUB_FILE_TYPE_NONE; -+ -+static grub_uint32_t bm_stage_base = 2000; -+static grub_efi_uint8_t permissive = 0; -+ -+static grub_efi_handle_t -+grub_efi_service_binding (grub_efi_guid_t *service_binding_guid) -+{ -+ grub_efi_service_binding_t *service; -+ grub_efi_status_t status; -+ grub_efi_handle_t child_dev = NULL; -+ grub_efi_handle_t *handles; -+ grub_efi_uintn_t num_handles; -+ -+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, service_binding_guid, 0, &num_handles); -+ if (!handles) -+ { -+ grub_printf ("couldn't locate service binding protocol handles\n"); -+ return NULL; -+ } -+ -+ service = grub_efi_open_protocol (handles[0], service_binding_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ if (!service) -+ { -+ grub_printf ("couldn't open efi service binding protocol\n"); -+ return NULL; -+ } -+ -+ status = efi_call_2 (service->create_child, service, &child_dev); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("Failed to create child device of efi service %x\n", status); -+ return NULL; -+ } -+ -+ return child_dev; -+} -+ -+static inline void -+util_dump_hex (const char *name, void *p, int bytes) -+{ -+ -+ int i = 0; -+ char *data = p; -+ int add_newline = 1; -+ grub_dprintf ("tpcm", "%s length=%d:\n", name, bytes); -+ if (bytes != 0) -+ { -+ grub_dprintf ("tpcm", "%02x ", (unsigned char)data[i]); -+ i++; -+ } -+ while (i < bytes) -+ { -+ grub_dprintf ("tpcm", "%02x ", (unsigned char)data[i]); -+ i++; -+ if (i % 16 == 0) -+ { -+ grub_dprintf("tpcm", "\n"); -+ add_newline = 0; -+ } -+ else -+ add_newline = 1; -+ } -+ if (add_newline) -+ grub_dprintf("tpcm", "\n"); -+} -+ -+static grub_efi_status_t -+grub_efi_hash (unsigned char *buf, grub_size_t size, unsigned char *content) -+{ -+ grub_efi_status_t status = GRUB_EFI_SUCCESS; -+ grub_efi_hash2_protocol_t *hash2; -+ grub_efi_handle_t hash_handle; -+ unsigned char output[DEFAULT_HASH_SIZE] = {0}; -+ grub_dprintf("tpcm", "grub_efi_hash binding service.\n"); -+ hash_handle = grub_efi_service_binding (&hash2_service_binding_guid); -+ if (!hash_handle) -+ { -+ grub_dprintf ("tpcm", "hash2 service binding failed.\n"); -+ status = GRUB_EFI_NOT_FOUND; -+ goto fail; -+ } -+ grub_dprintf("tpcm", "grub_efi_hash binding service success.\n"); -+ hash2 = grub_efi_open_protocol (hash_handle, &hash2_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ if (!hash2) -+ { -+ grub_dprintf ("tpcm", "hash2 protocol open failed.\n"); -+ status = GRUB_EFI_PROTOCOL_ERROR; -+ goto fail; -+ } -+ grub_dprintf("tpcm", "grub_efi_hash get protocol success.\n"); -+ status = hash2->hash_init(hash2, &sm3_guid); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_dprintf("tpcm", "hash_init failed.\n"); -+ goto fail; -+ } -+ status = hash2->hash_update(hash2, buf, size); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_dprintf("tpcm", "hash_update failed.\n"); -+ goto fail; -+ } -+ status = hash2->hash_final(hash2, output); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_dprintf("tpcm", "hash_final failed.\n"); -+ goto fail; -+ } -+ util_dump_hex ("tpcm BIOS hash output: ", output, DEFAULT_HASH_SIZE); -+ grub_memcpy(content, output, DEFAULT_HASH_SIZE); -+ -+fail: -+ return status; -+} -+ -+static grub_err_t -+tpcm_ipmi_init (grub_file_t io, -+ enum grub_file_type type __attribute__ ((unused)), -+ void **context, enum grub_verify_flags *flags) -+{ -+ *context = io->name; -+ grub_tcpm_file_type = type & GRUB_FILE_TYPE_MASK; -+ *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK; -+ return GRUB_ERR_NONE; -+} -+ -+static grub_efi_uint8_t -+get_firmware_hash_content(unsigned char *buf, grub_size_t size, unsigned char *content) -+{ -+ grub_efi_status_t status; -+ -+ grub_dprintf ("tpcm", "grub_efi_hash:\n"); -+ status = grub_efi_hash (buf, size, content); -+ -+ return status; -+} -+ -+static grub_err_t -+grub_tpcm_set_firmware_detailtype (grub_efi_uint8_t *type) -+{ -+ switch (grub_tcpm_file_type) -+ { -+ case GRUB_FILE_TYPE_LINUX_KERNEL: -+ *type = IPMI_FW_DETAIL_KERNEL; -+ break; -+ case GRUB_FILE_TYPE_LINUX_INITRD: -+ *type = IPMI_FW_DETAIL_INITRD; -+ break; -+ case GRUB_FILE_TYPE_CONFIG: -+ *type = IPMI_FW_DETAIL_GRUB_CFG; -+ break; -+ default: -+ grub_dprintf ("tpcm", "%d is not a file type that TPCM cares about.\n", grub_tcpm_file_type); -+ grub_tcpm_file_type = GRUB_FILE_TYPE_NONE; -+ break; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static void -+grub_tpcm_fillup_content (OEM_BMC_MEASURE_REQUSET *request_data, unsigned char *output) -+{ -+ grub_efi_uint32_t filename_len = 0; -+ switch (grub_tcpm_file_type) -+ { -+ case GRUB_FILE_TYPE_LINUX_KERNEL: -+ filename_len = grub_strlen("kernel"); -+ grub_memcpy ((grub_efi_uint8_t *)(request_data->FirmwareHashContent.uaObj), -+ "kernel", filename_len); -+ break; -+ case GRUB_FILE_TYPE_LINUX_INITRD: -+ filename_len = grub_strlen("initrd"); -+ grub_memcpy ((grub_efi_uint8_t *)(request_data->FirmwareHashContent.uaObj), -+ "initrd", filename_len); -+ break; -+ case GRUB_FILE_TYPE_CONFIG: -+ filename_len = grub_strlen("grub.cfg"); -+ grub_memcpy ((grub_efi_uint8_t *)(request_data->FirmwareHashContent.uaObj), -+ "grub.cfg", filename_len); -+ break; -+ default: -+ grub_dprintf ("tpcm", "%d is not a file type that TPCM cares about.\n", grub_tcpm_file_type); -+ break; -+ } -+ -+ request_data->FirmwareHashContent.uiCmdTag = TRANS (TPCM_TAG_REQ_COMMAND); -+ request_data->FirmwareHashContent.uiCmdLength = TRANS (sizeof (extern_simple_bmeasure_req_st)); -+ request_data->FirmwareHashContent.uiCmdCode = TRANS (TPCM_ORD_ExternSimpleBootMeasure); -+ request_data->FirmwareHashContent.uiPcr = TRANS (0); -+ -+ grub_uint32_t stage_base = bm_stage_base++; -+ request_data->FirmwareHashContent.uiStage = TRANS (stage_base); -+ -+ grub_memcpy ((grub_efi_uint8_t *)(request_data->FirmwareHashContent.uaDigest), -+ output, DEFAULT_HASH_SIZE); -+ request_data->FirmwareHashContent.uiObjLen = TRANS (filename_len); -+ -+ return; -+} -+ -+static grub_efi_status_t -+grub_tpcm_request_result (void) -+{ -+ grub_efi_status_t status = GRUB_EFI_SUCCESS; -+ grub_ipmi_cmd_header request = {IPMI_BMC_LUN, -+ IPMI_NETFN_OEM, -+ IPMI_CMD_GET_MEASURE_PARM}; -+ grub_efi_uint8_t response_length; -+ OEM_BMC_GET_RESULT_REQUSET get_result_request_data; -+ OEM_BMC_GET_RESULT_RESPONSE get_result_response_data; -+ -+ grub_efi_int16_t timeout_ms = GRUB_IPMI_TIMEOUT_MS; -+ -+ grub_memset (&get_result_request_data, 0, sizeof(get_result_request_data)); -+ grub_memset (&get_result_response_data, 0, sizeof(get_result_response_data)); -+ -+ get_result_request_data.OemSignature[0] = 0xDB; -+ get_result_request_data.OemSignature[1] = 0x07; -+ get_result_request_data.OemSignature[2] = 0x00; -+ get_result_request_data.SubCmd = IPMI_SUB_CMD_CONTROL_REQ; -+ get_result_request_data.FirmwareType = IPMI_FW_OS; -+ -+ // TODO: we should not load files expect: grub.cfg vmlinuz and initrd -+ grub_tpcm_set_firmware_detailtype (&(get_result_request_data.FirmwareDetailType)); -+ -+ while (timeout_ms > 0) -+ { -+ response_length = sizeof (OEM_BMC_GET_RESULT_RESPONSE); -+ grub_millisleep (200); -+ timeout_ms -= 200; -+ -+ grub_dprintf ("tpcm", "get result request: request_size[%lu], response_length[%d]\n", -+ sizeof(get_result_request_data), response_length); -+ -+ status = tpcm_ipmi->excute_ipmi_cmd (tpcm_ipmi, request, &get_result_request_data, -+ sizeof(get_result_request_data), &get_result_response_data, -+ &response_length, NULL); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_dprintf ("tpcm", "excute_ipmi_cmd failed, request sub_cmd:%d, ret:%lu\n", -+ get_result_request_data.SubCmd, status); -+ continue; -+ } -+ -+ if (response_length == sizeof (OEM_BMC_GET_RESULT_RESPONSE) && \ -+ get_result_response_data.ControlResult != IPMI_MEASURE_UNKNOW) -+ { -+ grub_dprintf ("tpcm", "request ControlResult success, ControlResult:%d\n", -+ get_result_response_data.ControlResult); -+ break; -+ } -+ } -+ -+ if (get_result_response_data.ControlResult == IPMI_MEASURE_SUCCESS) -+ { -+ return GRUB_EFI_SUCCESS; -+ } -+ else if (timeout_ms <= 0) -+ { -+ grub_dprintf ("tpcm", "request TPCM constrol result timout"); -+ return GRUB_EFI_TIMEOUT; -+ } -+ -+ return GRUB_EFI_UNSUPPORTED; -+} -+ -+static grub_err_t -+grub_tpcm_log_event (unsigned char *buf, grub_size_t size, const char *description) -+{ -+ grub_err_t err = GRUB_ERR_NONE; -+ grub_efi_status_t status = GRUB_EFI_SUCCESS; -+ grub_ipmi_cmd_header request = {IPMI_BMC_LUN, -+ IPMI_NETFN_OEM, -+ IPMI_CMD_GET_MEASURE_PARM}; -+ OEM_BMC_MEASURE_REQUSET *request_data = NULL; -+ OEM_BMC_MEASURE_RESPONSE response_data; -+ -+ unsigned char output[DEFAULT_HASH_SIZE] = {0}; -+ grub_efi_uint8_t response_length = sizeof (OEM_BMC_MEASURE_RESPONSE); -+ -+ grub_memset (&response_data, 0, sizeof (response_data)); -+ -+ request_data = grub_calloc (1, sizeof (OEM_BMC_MEASURE_REQUSET)); -+ if (!request_data) -+ { -+ grub_dprintf ("tpcm", "malloc request_data failed.\n"); -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); -+ return grub_errno; -+ } -+ -+ request_data->OemSignature[0] = 0xDB; -+ request_data->OemSignature[1] = 0x07; -+ request_data->OemSignature[2] = 0x00; -+ request_data->SubCmd = IPMI_SUB_CMD_MEASURE_REQ; -+ request_data->FirmwareType = IPMI_FW_OS; -+ request_data->FirmwareHashAlgoType = IPMI_FW_HASH_SM3; -+ -+ grub_tpcm_set_firmware_detailtype (&(request_data->FirmwareDetailType)); -+ -+ status = get_firmware_hash_content (buf, size, output); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ if (permissive) -+ grub_dprintf ("tpcm", "tpcm control switch turned off, ignore get firmware hash content failure.\n"); -+ else -+ { -+ grub_printf ("get firmware hash content failed\n"); -+ err = GRUB_ERR_BUG; -+ } -+ goto fail; -+ } -+ -+ request_data->FirmwareHashLen = sizeof(extern_simple_bmeasure_req_st); -+ grub_tpcm_fillup_content (request_data, output); -+ -+ status = tpcm_ipmi->excute_ipmi_cmd (tpcm_ipmi, request, request_data, -+ sizeof (OEM_BMC_MEASURE_REQUSET), &response_data, -+ &response_length, NULL); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ if (permissive) -+ grub_dprintf ("tpcm", "tpcm control switch turned off, ignore excute_ipmi_cmd failure.\n"); -+ else -+ { -+ err = grub_error (GRUB_ERR_BUG, -+ "excute_ipmi_cmd failed, request sub_cmd:0x%x, ret:%lu\n", -+ request_data->SubCmd, status); -+ } -+ goto fail; -+ } -+ grub_dprintf ("tpcm", "send tpcm measure request success\n"); -+ -+ status = grub_tpcm_request_result (); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ if (permissive) -+ grub_dprintf ("tpcm", "tpcm control switch turned off, ignore measurement failure.\n"); -+ else -+ { -+ err = grub_error (GRUB_ERR_BAD_SIGNATURE, "bad tpcm signature"); -+ goto fail; -+ } -+ } -+ else -+ grub_dprintf ("tpcm", "tpcm hash verify success, file:%s\n", description); -+ -+ fail: -+ if (request_data) -+ { -+ grub_free (request_data); -+ } -+ return err; -+} -+ -+static grub_efi_uint8_t -+tpcm_ipmi_get_switch (void) -+{ -+ grub_efi_status_t status = GRUB_EFI_SUCCESS; -+ grub_ipmi_cmd_header request = {IPMI_BMC_LUN, -+ IPMI_NETFN_OEM, -+ IPMI_CMD_GET_MEASURE_PARM}; -+ OEM_BMC_GET_SWITCH_REQUSET request_data; -+ OEM_BMC_GET_SWITCH_RESPONSE response_data; -+ grub_efi_uint8_t response_length; -+ -+ grub_memset (&request_data, 0, sizeof (request_data)); -+ grub_memset (&response_data, 0, sizeof (response_data)); -+ -+ request_data.OemSignature[0] = 0xDB; -+ request_data.OemSignature[1] = 0x07; -+ request_data.OemSignature[2] = 0x00; -+ request_data.SubCmd = IPMI_SUB_CMD_SWITCH_REQ; -+ request_data.FirmwareType = IPMI_FW_OS; -+ request_data.FirmwareDetailType = IPMI_FW_DETAIL_GRUB_CFG; -+ -+ response_length = sizeof (OEM_BMC_GET_SWITCH_RESPONSE); -+ -+ // TODO: 确认bios接口excute_ipmi_cmd, 请求开关控制结果这块代码是否需要轮询 -+ status = tpcm_ipmi->excute_ipmi_cmd (tpcm_ipmi, request, &request_data, -+ sizeof(request_data), &response_data, -+ &response_length, NULL); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_printf ("excute_ipmi_cmd failed, request sub_cmd:%d, ret:%lu\n", -+ request_data.SubCmd, status); -+ /* if we excute_ipmi_cmd, it could be the fllowing results: -+ * 1. uefi have this interface, but did not implement it. -+ * 2. uefi have implemented, but bmc did not support TPCM -+ * All of these situation should booting normally. -+ */ -+ goto out; -+ } -+ -+ if (response_data.ControlResult == IPMI_TPCM_OPEN || response_data.ControlResult == IPMI_TPCM_PERMISSIVE) -+ { -+ permissive = (response_data.ControlResult == IPMI_TPCM_PERMISSIVE) ? 1 : 0; -+ grub_dprintf ("tpcm", "tpcm: Enabled, ControlResult: %d\n", response_data.ControlResult); -+ return 1; -+ } -+ -+ out: -+ grub_dprintf ("tpcm", "tpcm: Disabled or Unknown, ControlResult: %d\n", response_data.ControlResult); -+ return 0; -+} -+ -+static grub_err_t -+tpcm_ipmi_measure (unsigned char *buf, grub_size_t size, const char *description) -+{ -+ if (tpcm_ipmi_get_switch()) -+ { -+ grub_dprintf("tpcm", "hash file: %s\n", description); -+ return grub_tpcm_log_event(buf, size, description); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+tpcm_ipmi_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size) -+{ -+ grub_err_t err; -+ err = tpcm_ipmi_measure (buf, size, context); -+ grub_tcpm_file_type = GRUB_FILE_TYPE_NONE; -+ return err; -+} -+ -+struct grub_file_verifier tpcm = -+ { -+ .name = "tpcm", -+ .init = tpcm_ipmi_init, -+ .write = tpcm_ipmi_write -+ }; -+ -+ -+GRUB_MOD_INIT(tpcm) -+{ -+ tpcm_ipmi = grub_efi_locate_protocol (&gIpmiInterfaceProtocolGuid, 0); -+ if (!tpcm_ipmi) -+ { -+ grub_dprintf ("tpcm", "locate IpmiInterfaceProtocol failed, TPCM unsupported in the machine.\n"); -+ return; -+ } -+ grub_verifier_register (&tpcm); -+} -+ -+GRUB_MOD_FINI(tpcm) -+{ -+ grub_verifier_unregister (&tpcm); -+} -+ -diff --git a/include/grub/efi/tpcm.h b/include/grub/efi/tpcm.h -new file mode 100644 -index 0000000..d4cf93b ---- /dev/null -+++ b/include/grub/efi/tpcm.h -@@ -0,0 +1,236 @@ -+#ifndef GRUB_EFI_TPCM_HEADER -+#define GRUB_EFI_TPCM_HEADER 1 -+ -+#define GRUB_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID \ -+ { \ -+ 0xda836f8d, 0x217f, 0x4ca0, { 0x99, 0xc2, 0x1c, 0xa4, 0xe1, 0x60, 0x77, 0xea } \ -+ } -+ -+#define GRUB_EFI_HASH2_PROTOCOL_GUID \ -+ { \ -+ 0x55b1d734, 0xc5e1, 0x49db, { 0x96, 0x47, 0xb1, 0x6a, 0xfb, 0xe, 0x30, 0x5b } \ -+ } -+ -+#define EFI_TPCM_GUID \ -+ { \ -+ 0xa37e200e, 0xda90, 0x473b, { 0x8b, 0xb5, 0x1d, 0x7b, 0x11, 0xba, 0x32, 0x33 } \ -+ } -+ -+#define GRUB_HASH_ALGORITHM_SM3_GUID \ -+ { \ -+ 0x9DCD754B, 0x3479, 0x27AD, { 0x56, 0x4C, 0x68, 0x7C, 0x68, 0xEC, 0xF9, 0xB9 } \ -+ } -+ -+ -+#define OEM_SIG_SIZE 3 -+#define FIRMWARE_VERSION_SIZE 32 -+#define FIRMWARE_HASH_CONTENT_SIZE 32 -+#define FIRMWARE_NAME_SIZE 32 -+#define GRUB_IPMI_TIMEOUT_MS 2000 -+ -+// LUN -+#define IPMI_BMC_LUN 0x00 -+// Net Function Definition -+#define IPMI_NETFN_OEM 0x30 -+ -+#define IPMI_CMD_GET_MEASURE_PARM 0x92 //change a name -+ -+#define IPMI_SUB_CMD_MEASURE_REQ 0x57 //change a name -+#define IPMI_SUB_CMD_CONTROL_REQ 0x58 -+#define IPMI_SUB_CMD_SWITCH_REQ 0x59 -+ -+//bmeasure -+#define DEFAULT_HASH_SIZE 32 -+#define MEASURE_DATA_MEM_SIZE 0x100000 -+ -+#define TPCM_TAG_REQ_COMMAND 0x000000C1 -+#define TPCM_ORD_ExternSimpleBootMeasure 0x00001053 -+ -+typedef struct { -+ grub_efi_uint32_t uiCmdTag; -+ grub_efi_uint32_t uiCmdLength; -+ grub_efi_uint32_t uiCmdCode; -+ grub_efi_uint32_t uiPcr; -+ grub_efi_uint32_t uiStage; -+ grub_efi_uint8_t uaDigest[DEFAULT_HASH_SIZE]; -+ grub_efi_uint32_t uiObjLen; -+ grub_efi_uint8_t uaObj[FIRMWARE_NAME_SIZE]; -+}extern_simple_bmeasure_req_st; -+ -+typedef struct { -+ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; -+ grub_efi_uint8_t SubCmd; -+ grub_efi_uint8_t FirmwareType; -+ grub_efi_uint8_t FirmwareDetailType; -+ grub_efi_uint8_t FirmwareHashAlgoType; -+ grub_efi_uint8_t FirmwareHashLen; -+ extern_simple_bmeasure_req_st FirmwareHashContent; -+ // reserved for kernel and initrd's version -+ grub_efi_uint8_t FirmwareVerionLen; -+ grub_efi_uint8_t FirmwareVerion[0]; -+} OEM_BMC_MEASURE_REQUSET; -+ -+typedef struct { -+ grub_efi_uint8_t CompletionCode; -+ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; -+} OEM_BMC_MEASURE_RESPONSE; -+ -+typedef struct { -+ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; -+ grub_efi_uint8_t SubCmd; -+ grub_efi_uint8_t FirmwareType; -+ grub_efi_uint8_t FirmwareDetailType; -+} OEM_BMC_GET_RESULT_REQUSET; -+ -+typedef struct { -+ /* In the specification of BMC <--> BIOS(GRUB2), we need CompletionCode -+ * But, BIOS has pre-processed CompletionCode in function: excute_ipmi_cmd -+ * So, we delete the word: -+ * grub_efi_uint8_t CompletionCode; -+ */ -+ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; -+ grub_efi_uint8_t ControlResult; -+} OEM_BMC_GET_RESULT_RESPONSE; -+ -+typedef struct { -+ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; -+ grub_efi_uint8_t SubCmd; -+ grub_efi_uint8_t FirmwareType; -+ grub_efi_uint8_t FirmwareDetailType; -+} OEM_BMC_GET_SWITCH_REQUSET; -+ -+typedef struct { -+ /* In the specification of BMC <--> BIOS(GRUB2), we need CompletionCode -+ * But, BIOS has pre-processed CompletionCode in function: excute_ipmi_cmd -+ * So, we delete the word: -+ * grub_efi_uint8_t CompletionCode; -+ */ -+ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; -+ grub_efi_uint8_t ControlResult; -+} OEM_BMC_GET_SWITCH_RESPONSE; -+ -+typedef enum { -+ IPMI_SYSTEM_INTERFACE_UNKNOWN, // IPMI_SYSTEM_INTERFACE_TYPE->UNKNOWN -+ IPMI_SYSTEM_INTERFACE_KCS, -+ IPMI_SYSTEM_INTERFACE_SMIC, -+ IPMI_SYSTEM_INTERFACE_BT, // IPMI_SYSTEM_INTERFACE_TYPE->BT -+ IPMI_SYSTEM_INTERFACE_SSIF, -+ IPMI_SYSTEM_INTERFACE_MAX_TYPE // IPMI_SYSTEM_INTERFACE_TYPE->MAX_TYPE -+} grub_ipmi_system_interface_type; -+ -+ -+typedef struct { -+ grub_efi_uint8_t lun : 2; -+ grub_efi_uint8_t net_fn : 6; -+ grub_efi_uint8_t cmd; -+} grub_ipmi_cmd_header; -+ -+typedef enum { -+ IPMI_MEMORY, -+ IPMI_IO, // IPMI_IO -+ IPMI_MAX_INTERFACE_ADDRESS_TYPE -+} grub_ipmi_interface_address_type; -+ -+typedef enum { -+ IPMI_FW_SHIM, -+ IPMI_FW_SHIM_GRUB, -+ IPMI_FW_OS -+} grub_ipmi_firmware_type; -+ -+typedef enum { -+ IPMI_FW_DETAIL_GRUB_CFG, -+ IPMI_FW_DETAIL_KERNEL, -+ IPMI_FW_DETAIL_INITRD -+} grub_ipmi_firmware_detail_type; -+ -+typedef enum { -+ IPMI_FW_HASH_SM3, -+ IPMI_FW_HASH_RESERVED1, -+ IPMI_FW_HASH_RESERVED2 -+} grub_ipmi_firmware_hash_algo_type; -+ -+typedef enum { -+ IPMI_MEASURE_UNKNOW, -+ IPMI_MEASURE_SUCCESS, -+ IPMI_MEASURE_FAIL -+} grub_ipmi_measure_result_type; -+ -+typedef enum { -+ IPMI_TPCM_UNKNOW, -+ IPMI_TPCM_OPEN, -+ IPMI_TPCM_CLOSE, -+ IPMI_TPCM_PERMISSIVE -+} grub_ipmi_tpcm_result_type; -+ -+ -+typedef grub_efi_uint8_t EFI_MD5_HASH2[16]; -+typedef grub_efi_uint8_t EFI_SHA1_HASH2[20]; -+typedef grub_efi_uint8_t EFI_SHA224_HASH2[28]; -+typedef grub_efi_uint8_t EFI_SHA256_HASH2[32]; -+typedef grub_efi_uint8_t EFI_SHA384_HASH2[48]; -+typedef grub_efi_uint8_t EFI_SHA512_HASH2[64]; -+typedef grub_efi_uint8_t EFI_SM3_HASH2[32]; -+ -+typedef union { -+ EFI_MD5_HASH2 Md5Hash; -+ EFI_SHA1_HASH2 Sha1Hash; -+ EFI_SHA224_HASH2 Sha224Hash; -+ EFI_SHA256_HASH2 Sha256Hash; -+ EFI_SHA384_HASH2 Sha384Hash; -+ EFI_SHA512_HASH2 Sha512Hash; -+ EFI_SM3_HASH2 Sm3Hash; -+} grub_efi_hash2_output; -+ -+struct grub_efi_hash2_protocol { -+ grub_efi_status_t -+ (*get_hash_size) (struct grub_efi_hash2_protocol *this, -+ grub_efi_guid_t *hash_algorithm, -+ grub_efi_uintn_t hash_size); -+ -+ grub_efi_status_t -+ (*hash) (struct grub_efi_hash2_protocol *this, -+ grub_efi_guid_t *hash_algorithm, -+ grub_efi_uint8_t *message, -+ grub_efi_uintn_t message_size, -+ grub_efi_hash2_output *hash); -+ -+ grub_efi_status_t -+ (*hash_init) (struct grub_efi_hash2_protocol *this, -+ grub_efi_guid_t *hash_algorithm); -+ -+ grub_efi_status_t -+ (*hash_update) (struct grub_efi_hash2_protocol *this, -+ grub_efi_uint8_t *message, -+ grub_efi_uintn_t message_size); -+ -+ grub_efi_status_t -+ (*hash_final) (struct grub_efi_hash2_protocol *this, -+ grub_efi_hash2_output *hash); -+}; -+typedef struct grub_efi_hash2_protocol grub_efi_hash2_protocol_t; -+ -+struct grub_efi_ipmi_interface_protocol { -+ grub_efi_status_t -+ (*excute_ipmi_cmd) (struct grub_efi_ipmi_interface_protocol *this, -+ grub_ipmi_cmd_header request, -+ void *send_data, -+ grub_efi_uint8_t send_length, -+ void *recv_data, -+ grub_efi_uint8_t *recv_length, -+ grub_efi_uint16_t *status_codes); -+ -+ grub_ipmi_system_interface_type -+ (*get_ipmi_interface_type) (struct grub_efi_ipmi_interface_protocol *this); -+ -+ grub_efi_uint16_t -+ (*get_ipmi_base_address) (struct grub_efi_ipmi_interface_protocol *this); -+ -+ grub_ipmi_interface_address_type -+ (*get_ipmi_base_address_type) (struct grub_efi_ipmi_interface_protocol *this); -+ -+ grub_efi_uint8_t -+ (*get_ipmi_version) (struct grub_efi_ipmi_interface_protocol *this); -+}; -+typedef struct grub_efi_ipmi_interface_protocol grub_efi_ipmi_interface_protocol_t; -+ -+#endif --- -2.27.0 - diff --git a/backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch b/backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch deleted file mode 100644 index fc3b46f..0000000 --- a/backport-Avoid-Wsign-compare-in-rijndael-do_setkey.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0cb7a4491684648a819022a4e71820bbaf114734 Mon Sep 17 00:00:00 2001 -From: Heinrich Schuchardt -Date: Fri, 13 Aug 2021 16:15:33 +0200 -Subject: libgcrypt: Avoid -Wsign-compare in rijndael do_setkey() - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=0cb7a4491684648a819022a4e71820bbaf114734 - -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Avoid a warning - - lib/libgcrypt-grub/cipher/rijndael.c:352:21: warning: - comparison of integer expressions of different signedness: - ‘int’ and ‘unsigned int’ [-Wsign-compare] - 352 | for (i = 0; i < keylen; i++) - | - -Signed-off-by: Heinrich Schuchardt -Reviewed-by: Daniel Kiper ---- - grub-core/lib/libgcrypt/cipher/rijndael.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/grub-core/lib/libgcrypt/cipher/rijndael.c b/grub-core/lib/libgcrypt/cipher/rijndael.c -index 559550b50..38e9a7c08 100644 ---- a/grub-core/lib/libgcrypt/cipher/rijndael.c -+++ b/grub-core/lib/libgcrypt/cipher/rijndael.c -@@ -181,7 +181,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) - static int initialized = 0; - static const char *selftest_failed=0; - int rounds; -- int i,j, r, t, rconpointer = 0; -+ unsigned int i; -+ int j, r, t, rconpointer = 0; - int KC; - union - { --- -cgit v1.2.1 - diff --git a/backport-CVE-2023-4692-fs-ntfs-Fix-an-OOB-write-when-parsing-the.patch b/backport-CVE-2023-4692-fs-ntfs-Fix-an-OOB-write-when-parsing-the.patch deleted file mode 100644 index b69abec..0000000 --- a/backport-CVE-2023-4692-fs-ntfs-Fix-an-OOB-write-when-parsing-the.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 998f950383270b8494efd17738cf4fb358705c6c Mon Sep 17 00:00:00 2001 -From: Maxim Suhanov -Date: Mon, 28 Aug 2023 16:31:57 +0300 -Subject: [PATCH 1/6] fs/ntfs: Fix an OOB write when parsing the - $ATTRIBUTE_LIST attribute for the $MFT file - -When parsing an extremely fragmented $MFT file, i.e., the file described -using the $ATTRIBUTE_LIST attribute, current NTFS code will reuse a buffer -containing bytes read from the underlying drive to store sector numbers, -which are consumed later to read data from these sectors into another buffer. - -These sectors numbers, two 32-bit integers, are always stored at predefined -offsets, 0x10 and 0x14, relative to first byte of the selected entry within -the $ATTRIBUTE_LIST attribute. Usually, this won't cause any problem. - -However, when parsing a specially-crafted file system image, this may cause -the NTFS code to write these integers beyond the buffer boundary, likely -causing the GRUB memory allocator to misbehave or fail. These integers contain -values which are controlled by on-disk structures of the NTFS file system. - -Such modification and resulting misbehavior may touch a memory range not -assigned to the GRUB and owned by firmware or another EFI application/driver. - -This fix introduces checks to ensure that these sector numbers are never -written beyond the boundary. - -Fixes: CVE-2023-4692 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=43651027d24e62a7a463254165e1e46e42aecdea -Conflict:NA - -Reported-by: Maxim Suhanov -Signed-off-by: Maxim Suhanov -Reviewed-by: Daniel Kiper ---- - grub-core/fs/ntfs.c | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index 2f34f76..c8d3683 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -184,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - } - if (at->attr_end) - { -- grub_uint8_t *pa; -+ grub_uint8_t *pa, *pa_end; - - at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); - if (at->emft_buf == NULL) -@@ -209,11 +209,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - } - at->attr_nxt = at->edat_buf; - at->attr_end = at->edat_buf + u32at (pa, 0x30); -+ pa_end = at->edat_buf + n; - } - else - { - at->attr_nxt = at->attr_end + u16at (pa, 0x14); - at->attr_end = at->attr_end + u32at (pa, 4); -+ pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); - } - at->flags |= GRUB_NTFS_AF_ALST; - while (at->attr_nxt < at->attr_end) -@@ -230,6 +232,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - at->flags |= GRUB_NTFS_AF_GPOS; - at->attr_cur = at->attr_nxt; - pa = at->attr_cur; -+ -+ if ((pa >= pa_end) || (pa_end - pa < 0x18)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list"); -+ return NULL; -+ } -+ - grub_set_unaligned32 ((char *) pa + 0x10, - grub_cpu_to_le32 (at->mft->data->mft_start)); - grub_set_unaligned32 ((char *) pa + 0x14, -@@ -240,6 +249,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - { - if (*pa != attr) - break; -+ -+ if ((pa >= pa_end) || (pa_end - pa < 0x18)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list"); -+ return NULL; -+ } -+ - if (read_attr - (at, pa + 0x10, - u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), --- -2.19.1 - diff --git a/backport-CVE-2023-4693-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the.patch b/backport-CVE-2023-4693-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the.patch deleted file mode 100644 index add2b3c..0000000 --- a/backport-CVE-2023-4693-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0636bff015fe6f2df6975cdfac6e264e2649fc26 Mon Sep 17 00:00:00 2001 -From: Maxim Suhanov -Date: Mon, 28 Aug 2023 16:32:33 +0300 -Subject: [PATCH 2/6] fs/ntfs: Fix an OOB read when reading data from the - resident $DATA attribute - -When reading a file containing resident data, i.e., the file data is stored in -the $DATA attribute within the NTFS file record, not in external clusters, -there are no checks that this resident data actually fits the corresponding -file record segment. - -When parsing a specially-crafted file system image, the current NTFS code will -read the file data from an arbitrary, attacker-chosen memory offset and of -arbitrary, attacker-chosen length. - -This allows an attacker to display arbitrary chunks of memory, which could -contain sensitive information like password hashes or even plain-text, -obfuscated passwords from BS EFI variables. - -This fix implements a check to ensure that resident data is read from the -corresponding file record segment only. - -Fixes: CVE-2023-4693 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=0ed2458cc4eff6d9a9199527e2a0b6d445802f94 -Conflict:NA - -Reported-by: Maxim Suhanov -Signed-off-by: Maxim Suhanov -Reviewed-by: Daniel Kiper ---- - grub-core/fs/ntfs.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index c8d3683..4d1fe42 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -401,7 +401,18 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, - { - if (ofs + len > u32at (pa, 0x10)) - return grub_error (GRUB_ERR_BAD_FS, "read out of range"); -- grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len); -+ -+ if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) -+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large"); -+ -+ if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) -+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range"); -+ -+ if (u16at (pa, 0x14) + u32at (pa, 0x10) > -+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa) -+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range"); -+ -+ grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len); - return 0; - } - --- -2.19.1 - diff --git a/backport-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch b/backport-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch deleted file mode 100644 index 3a78f4d..0000000 --- a/backport-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 9 Feb 2022 16:08:20 -0500 -Subject: [PATCH] EFI: allocate kernel in EFI_RUNTIME_SERVICES_CODE instead of - EFI_LOADER_DATA. - -On some of the firmwares with more security mitigations, EFI_LOADER_DATA -doesn't get you executable memory, and we take a fault and reboot when -we enter kernel. - -This patch correctly allocates the kernel code as EFI_RUNTIME_SERVICES_CODE -rather than EFI_LOADER_DATA. - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Peter Jones -[rharwood: use kernel_size] -Signed-off-by: Robbie Harwood ---- - grub-core/loader/i386/efi/linux.c | 19 +++++++++++++------ - 1 file changed, 13 insertions(+), 6 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 9e5c11ac69..92b2fb5091 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -86,7 +86,9 @@ kernel_free(void *addr, grub_efi_uintn_t size) - } - - static void * --kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) -+kernel_alloc(grub_efi_uintn_t size, -+ grub_efi_memory_type_t memtype, -+ const char * const errmsg) - { - void *addr = 0; - unsigned int i; -@@ -112,7 +114,7 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) - prev_max = max; - addr = grub_efi_allocate_pages_real (max, pages, - max_addresses[i].alloc_type, -- GRUB_EFI_LOADER_DATA); -+ memtype); - if (addr) - grub_dprintf ("linux", "Allocated at %p\n", addr); - } -@@ -242,7 +244,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) - } - } - -- initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); -+ initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA, -+ N_("can't allocate initrd")); - if (initrd_mem == NULL) - goto fail; - grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); -@@ -393,7 +396,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - #endif - -- params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters"); -+ params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA, -+ "cannot allocate kernel parameters"); - if (!params) - goto fail; - grub_dprintf ("linux", "params = %p\n", params); -@@ -415,7 +419,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_dprintf ("linux", "new lh is at %p\n", lh); - - grub_dprintf ("linux", "setting up cmdline\n"); -- cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline")); -+ cmdline = kernel_alloc (lh->cmdline_size + 1, -+ GRUB_EFI_RUNTIME_SERVICES_DATA, -+ N_("can't allocate cmdline")); - if (!cmdline) - goto fail; - grub_dprintf ("linux", "cmdline = %p\n", cmdline); -@@ -461,7 +467,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; - max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; - kernel_size = lh->init_size; -- kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel")); -+ kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE, -+ N_("can't allocate kernel")); - restore_addresses(); - if (!kernel_mem) - goto fail; diff --git a/backport-Fix-partmap_test-for-arm-efi.patch b/backport-Fix-partmap_test-for-arm-efi.patch deleted file mode 100644 index bd8d77a..0000000 --- a/backport-Fix-partmap_test-for-arm-efi.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 57a393ca59b3358aec61af10edbc79d8c366e5e4 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Tue, 12 Oct 2021 19:39:55 -0500 -Subject: tests: Fix partmap_test for arm*-efi, disk numbering has changed - -Perhaps using a newer UEFI firmware is the reason for the created test disk -showing up as hd2 instead of hd3. - -Conflict:NA -Reference:http://git.savannah.gnu.org/cgit/grub.git/patch/tests/partmap_test.in?id=57a393ca59b3358aec61af10edbc79d8c366e5e4 - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - tests/partmap_test.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -(limited to 'tests/partmap_test.in') - -diff --git a/tests/partmap_test.in b/tests/partmap_test.in -index 6ef518b..7353dc7 100644 ---- a/tests/partmap_test.in -+++ b/tests/partmap_test.in -@@ -89,7 +89,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in - disk=arc/scsi0/disk0/rdisk0 - ;; - arm*-efi) -- disk=hd3 -+ disk=hd2 - ;; - *) - disk=hd0 --- -cgit v1.1 - diff --git a/backport-RISC-V-Handle-R_RISCV_CALL_PLT-reloc.patch b/backport-RISC-V-Handle-R_RISCV_CALL_PLT-reloc.patch deleted file mode 100644 index 8ff06bc..0000000 --- a/backport-RISC-V-Handle-R_RISCV_CALL_PLT-reloc.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 403d6540cd608b2706cfa0cb4713f7e4b490ff45 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Thu, 23 Feb 2023 13:15:08 -0800 -Subject: [PATCH] RISC-V: Handle R_RISCV_CALL_PLT reloc - -GNU assembler starting 2.40 release always generates R_RISCV_CALL_PLT -reloc for call in assembler [1], similarly LLVM does not make -distinction between R_RISCV_CALL_PLT and R_RISCV_CALL [2]. - -Fixes "grub-mkimage: error: relocation 0x13 is not implemented yet.". - -[1] https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=70f35d72ef04cd23771875c1661c9975044a749c -[2] https://reviews.llvm.org/D132530 - -Signed-off-by: Khem Raj -Reviewed-by: Daniel Kiper ---- - grub-core/kern/riscv/dl.c | 1 + - util/grub-mkimagexx.c | 2 ++ - 2 files changed, 3 insertions(+) - -diff --git a/grub-core/kern/riscv/dl.c b/grub-core/kern/riscv/dl.c -index f26b12aaa..896653bb4 100644 ---- a/grub-core/kern/riscv/dl.c -+++ b/grub-core/kern/riscv/dl.c -@@ -188,6 +188,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - break; - - case R_RISCV_CALL: -+ case R_RISCV_CALL_PLT: - { - grub_uint32_t *abs_place = place; - grub_ssize_t off = sym_addr - (grub_addr_t) place; -diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c -index a1927e786..c5fb336e9 100644 ---- a/util/grub-mkimagexx.c -+++ b/util/grub-mkimagexx.c -@@ -1294,6 +1294,7 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, - } - break; - case R_RISCV_CALL: -+ case R_RISCV_CALL_PLT: - { - grub_uint32_t hi20, lo12; - -@@ -1726,6 +1727,7 @@ translate_relocation_pe (struct translate_context *ctx, - case R_RISCV_BRANCH: - case R_RISCV_JAL: - case R_RISCV_CALL: -+ case R_RISCV_CALL_PLT: - case R_RISCV_PCREL_HI20: - case R_RISCV_PCREL_LO12_I: - case R_RISCV_PCREL_LO12_S: --- -2.39.1 - diff --git a/backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch b/backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch deleted file mode 100644 index 10f7de4..0000000 --- a/backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch +++ /dev/null @@ -1,213 +0,0 @@ -From c9198e80f1aa2e9ae9e2bdc8b6f9e9ef601f0971 Mon Sep 17 00:00:00 2001 -From: Colin Watson -Date: Mon, 13 Jan 2014 12:13:10 +0000 -Subject: [PATCH] Read /etc/default/grub.d/*.cfg after /etc/default/grub - -Bug-Ubuntu: https://bugs.launchpad.net/bugs/901600 -Forwarded: no -Last-Update: 2021-09-24 - -Reference:https://sources.debian.org/src/grub2/2.06-8.1/debian/patches/default-grub-d.patch/ -Conflict:NA ---- - grub-core/osdep/unix/config.c | 128 ++++++++++++++++++++++++++++------ - util/grub-mkconfig.in | 5 ++ - 2 files changed, 112 insertions(+), 21 deletions(-) - -diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c -index 46a8815..5a8c584 100644 ---- a/grub-core/osdep/unix/config.c -+++ b/grub-core/osdep/unix/config.c -@@ -24,6 +24,9 @@ - #include - #include - #include -+#include -+#include -+#include - #include - #include - #include -@@ -61,13 +64,27 @@ grub_util_get_localedir (void) - return LOCALEDIR; - } - -+struct cfglist -+{ -+ struct cfglist *next; -+ struct cfglist *prev; -+ char *path; -+}; -+ - void - grub_util_load_config (struct grub_util_config *cfg) - { - pid_t pid; - const char *argv[4]; -- char *script, *ptr; -+ char *script = NULL, *ptr; - const char *cfgfile, *iptr; -+ char *cfgdir; -+ grub_util_fd_dir_t d; -+ struct cfglist *cfgpaths = NULL, *cfgpath, *next_cfgpath; -+ int num_cfgpaths = 0; -+ size_t len_cfgpaths = 0; -+ char **sorted_cfgpaths = NULL; -+ int i; - FILE *f = NULL; - int fd; - const char *v; -@@ -96,29 +113,88 @@ grub_util_load_config (struct grub_util_config *cfg) - } - - cfgfile = grub_util_get_config_filename (); -- if (!grub_util_is_regular (cfgfile)) -- return; -+ if (grub_util_is_regular (cfgfile)) -+ { -+ size_t sz; -+ -+ ++num_cfgpaths; -+ sz = strlen (cfgfile); -+ if (grub_mul (sz, 4, &sz) || -+ grub_add (sz, sizeof (". ''; ") - 1, &sz) || -+ grub_add (len_cfgpaths, sz, &len_cfgpaths)) -+ grub_util_error ("%s", _("overflow is detected")); -+ } -+ -+ cfgdir = xasprintf ("%s.d", cfgfile); -+ d = grub_util_fd_opendir (cfgdir); -+ if (d) -+ { -+ grub_util_fd_dirent_t de; -+ -+ while ((de = grub_util_fd_readdir (d))) -+ { -+ const char *ext = strrchr (de->d_name, '.'); -+ size_t sz; -+ -+ if (!ext || strcmp (ext, ".cfg") != 0) -+ continue; -+ -+ cfgpath = xmalloc (sizeof (*cfgpath)); -+ cfgpath->path = grub_util_path_concat (2, cfgdir, de->d_name); -+ grub_list_push (GRUB_AS_LIST_P (&cfgpaths), GRUB_AS_LIST (cfgpath)); -+ ++num_cfgpaths; -+ sz = strlen (cfgpath->path); -+ if (grub_mul (sz, 4, &sz) || -+ grub_add (sz, sizeof (". ''; ") - 1, &sz) || -+ grub_add (len_cfgpaths, sz, &len_cfgpaths)) -+ grub_util_error ("%s", _("overflow is detected")); -+ } -+ grub_util_fd_closedir (d); -+ } -+ -+ if (num_cfgpaths == 0) -+ goto out; -+ -+ sorted_cfgpaths = xcalloc (num_cfgpaths, sizeof (*sorted_cfgpaths)); -+ i = 0; -+ if (grub_util_is_regular (cfgfile)) -+ sorted_cfgpaths[i++] = xstrdup (cfgfile); -+ FOR_LIST_ELEMENTS_SAFE (cfgpath, next_cfgpath, cfgpaths) -+ { -+ sorted_cfgpaths[i++] = cfgpath->path; -+ free (cfgpath); -+ } -+ assert (i == num_cfgpaths); -+ qsort (sorted_cfgpaths + 1, num_cfgpaths - 1, sizeof (*sorted_cfgpaths), -+ (int (*) (const void *, const void *)) strcmp); - - argv[0] = "sh"; - argv[1] = "-c"; - -- script = xcalloc (4, strlen (cfgfile) + 300); -+ if (grub_add (len_cfgpaths, 300, &len_cfgpaths)) -+ grub_util_error ("%s", _("overflow is detected")); -+ script = xmalloc (len_cfgpaths); - - ptr = script; -- memcpy (ptr, ". '", 3); -- ptr += 3; -- for (iptr = cfgfile; *iptr; iptr++) -+ for (i = 0; i < num_cfgpaths; i++) - { -- if (*iptr == '\\') -+ memcpy (ptr, ". '", 3); -+ ptr += 3; -+ for (iptr = sorted_cfgpaths[i]; *iptr; iptr++) - { -- memcpy (ptr, "'\\''", 4); -- ptr += 4; -- continue; -+ if (*iptr == '\\') -+ { -+ memcpy (ptr, "'\\''", 4); -+ ptr += 4; -+ continue; -+ } -+ *ptr++ = *iptr; - } -- *ptr++ = *iptr; -+ memcpy (ptr, "'; ", 3); -+ ptr += 3; - } - -- strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\nSUSE_BTRFS_SNAPSHOT_BOOTING=%s\\n\" " -+ strcpy (ptr, "printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\nSUSE_BTRFS_SNAPSHOT_BOOTING=%s\\n\" " - "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\" \"$SUSE_BTRFS_SNAPSHOT_BOOTING\""); - - argv[2] = script; -@@ -138,15 +214,25 @@ grub_util_load_config (struct grub_util_config *cfg) - waitpid (pid, NULL, 0); - } - if (f) -- return; -+ goto out; - -- f = grub_util_fopen (cfgfile, "r"); -- if (f) -+ for (i = 0; i < num_cfgpaths; i++) - { -- grub_util_parse_config (f, cfg, 0); -- fclose (f); -+ f = grub_util_fopen (sorted_cfgpaths[i], "r"); -+ if (f) -+ { -+ grub_util_parse_config (f, cfg, 0); -+ fclose (f); -+ } -+ else -+ grub_util_warn (_("cannot open configuration file `%s': %s"), -+ cfgfile, strerror (errno)); - } -- else -- grub_util_warn (_("cannot open configuration file `%s': %s"), -- cfgfile, strerror (errno)); -+ -+out: -+ free (script); -+ for (i = 0; i < num_cfgpaths; i++) -+ free (sorted_cfgpaths[i]); -+ free (sorted_cfgpaths); -+ free (cfgdir); - } -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index 520a672..e3f2ae8 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -164,6 +164,11 @@ fi - if test -f ${sysconfdir}/default/grub ; then - . ${sysconfdir}/default/grub - fi -+for x in ${sysconfdir}/default/grub.d/*.cfg ; do -+ if [ -e "${x}" ]; then -+ . "${x}" -+ fi -+done - - eval "$("${grub_get_kernel_settings}")" || true - --- -2.19.1 - diff --git a/backport-Revert-iee1275-datetime-Fix-off-by-1-error.patch b/backport-Revert-iee1275-datetime-Fix-off-by-1-error.patch deleted file mode 100644 index eaedca2..0000000 --- a/backport-Revert-iee1275-datetime-Fix-off-by-1-error.patch +++ /dev/null @@ -1,46 +0,0 @@ -From be257de00c8edbbe8e26d83769c6d36ea1f2a734 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Mon, 24 Jan 2022 20:10:51 -0600 -Subject: Revert "iee1275/datetime: Fix off-by-1 error." - -This is causing the test grub_cmd_date() to fail because the returned -date is one day more than it should be. - -This reverts commit 607d66116 (iee1275/datetime: Fix off-by-1 error.). - -Signed-off-by: Glenn Washburn -Tested-by: Daniel Axtens -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=be257de00c8edbbe8e26d83769c6d36ea1f2a734 - ---- - grub-core/lib/ieee1275/datetime.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/lib/ieee1275/datetime.c b/grub-core/lib/ieee1275/datetime.c -index b81fba2..74578f1 100644 ---- a/grub-core/lib/ieee1275/datetime.c -+++ b/grub-core/lib/ieee1275/datetime.c -@@ -95,7 +95,7 @@ grub_get_datetime (struct grub_datetime *datetime) - - datetime->year = args.year; - datetime->month = args.month; -- datetime->day = args.day + 1; -+ datetime->day = args.day; - datetime->hour = args.hour; - datetime->minute = args.minute; - datetime->second = args.second; -@@ -140,7 +140,7 @@ grub_set_datetime (struct grub_datetime *datetime) - - args.year = datetime->year; - args.month = datetime->month; -- args.day = datetime->day - 1; -+ args.day = datetime->day; - args.hour = datetime->hour; - args.minute = datetime->minute; - args.second = datetime->second; --- -cgit v1.1 - diff --git a/backport-commands-acpi-Use-xsdt_addr-if-present.patch b/backport-commands-acpi-Use-xsdt_addr-if-present.patch deleted file mode 100644 index c851e38..0000000 --- a/backport-commands-acpi-Use-xsdt_addr-if-present.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b2b477e6b23a207321e2f9d7fde1a1624ef318dc Mon Sep 17 00:00:00 2001 -From: Qiumiao Zhang -Date: Tue, 13 Jun 2023 11:17:36 +0800 -Subject: [PATCH] commands/acpi: Use xsdt_addr if present - -According to the ACPI specification, in ACPI 2.0 or later, an -ACPI-compatible OS must use the XSDT if present. So, we should -use xsdt_addr instead of rsdt_addr if xsdt_addr is valid. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=b2b477e6b23a207321e2f9d7fde1a1624ef318dc -Conflict:NA - -Signed-off-by: Qiumiao Zhang -Reviewed-by: Daniel Kiper ---- - grub-core/commands/acpi.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c -index deec4bb43..1c034463c 100644 ---- a/grub-core/commands/acpi.c -+++ b/grub-core/commands/acpi.c -@@ -514,7 +514,11 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) - /* Set revision variables to replicate the same version as host. */ - rev1 = ! rsdp->revision; - rev2 = rsdp->revision; -- rsdt = (struct grub_acpi_table_header *) (grub_addr_t) rsdp->rsdt_addr; -+ if (rev2 && ((struct grub_acpi_table_header *) (grub_addr_t) ((struct grub_acpi_rsdp_v20 *) rsdp)->xsdt_addr) != NULL) -+ rsdt = (struct grub_acpi_table_header *) (grub_addr_t) ((struct grub_acpi_rsdp_v20 *) rsdp)->xsdt_addr; -+ else -+ rsdt = (struct grub_acpi_table_header *) (grub_addr_t) rsdp->rsdt_addr; -+ - /* Load host tables. */ - for (entry_ptr = (grub_uint32_t *) (rsdt + 1); - entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt) --- -2.27.0 - diff --git a/backport-commands-boot-Add-API-to-pass-context-to-loader.patch b/backport-commands-boot-Add-API-to-pass-context-to-loader.patch deleted file mode 100644 index e1e96a7..0000000 --- a/backport-commands-boot-Add-API-to-pass-context-to-loader.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Fri, 29 Apr 2022 21:16:02 +0100 -Subject: [PATCH] commands/boot: Add API to pass context to loader - -Loaders rely on global variables for saving context which is consumed -in the boot hook and freed in the unload hook. In the case where a loader -command is executed twice, calling grub_loader_set a second time executes -the unload hook, but in some cases this runs when the loader's global -context has already been updated, resulting in the updated context being -freed and potential use-after-free bugs when the boot hook is subsequently -called. - -This adds a new API (grub_loader_set_ex) which allows a loader to specify -context that is passed to its boot and unload hooks. This is an alternative -to requiring that loaders call grub_loader_unset before mutating their -global context. - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Chris Coulson -(cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3) ---- - grub-core/commands/boot.c | 66 +++++++++++++++++++++++++++++++++++++++++------ - include/grub/loader.h | 5 ++++ - 2 files changed, 63 insertions(+), 8 deletions(-) - -diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c -index bbca81e947..53691a62d9 100644 ---- a/grub-core/commands/boot.c -+++ b/grub-core/commands/boot.c -@@ -27,10 +27,20 @@ - - GRUB_MOD_LICENSE ("GPLv3+"); - --static grub_err_t (*grub_loader_boot_func) (void); --static grub_err_t (*grub_loader_unload_func) (void); -+static grub_err_t (*grub_loader_boot_func) (void *); -+static grub_err_t (*grub_loader_unload_func) (void *); -+static void *grub_loader_context; - static int grub_loader_flags; - -+struct grub_simple_loader_hooks -+{ -+ grub_err_t (*boot) (void); -+ grub_err_t (*unload) (void); -+}; -+ -+/* Don't heap allocate this to avoid making grub_loader_set fallible. */ -+static struct grub_simple_loader_hooks simple_loader_hooks; -+ - struct grub_preboot - { - grub_err_t (*preboot_func) (int); -@@ -44,6 +54,29 @@ static int grub_loader_loaded; - static struct grub_preboot *preboots_head = 0, - *preboots_tail = 0; - -+static grub_err_t -+grub_simple_boot_hook (void *context) -+{ -+ struct grub_simple_loader_hooks *hooks; -+ -+ hooks = (struct grub_simple_loader_hooks *) context; -+ return hooks->boot (); -+} -+ -+static grub_err_t -+grub_simple_unload_hook (void *context) -+{ -+ struct grub_simple_loader_hooks *hooks; -+ grub_err_t ret; -+ -+ hooks = (struct grub_simple_loader_hooks *) context; -+ -+ ret = hooks->unload (); -+ grub_memset (hooks, 0, sizeof (*hooks)); -+ -+ return ret; -+} -+ - int - grub_loader_is_loaded (void) - { -@@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd) - } - - void --grub_loader_set (grub_err_t (*boot) (void), -- grub_err_t (*unload) (void), -- int flags) -+grub_loader_set_ex (grub_err_t (*boot) (void *), -+ grub_err_t (*unload) (void *), -+ void *context, -+ int flags) - { - if (grub_loader_loaded && grub_loader_unload_func) -- grub_loader_unload_func (); -+ grub_loader_unload_func (grub_loader_context); - - grub_loader_boot_func = boot; - grub_loader_unload_func = unload; -+ grub_loader_context = context; - grub_loader_flags = flags; - - grub_loader_loaded = 1; - } - -+void -+grub_loader_set (grub_err_t (*boot) (void), -+ grub_err_t (*unload) (void), -+ int flags) -+{ -+ grub_loader_set_ex (grub_simple_boot_hook, -+ grub_simple_unload_hook, -+ &simple_loader_hooks, -+ flags); -+ -+ simple_loader_hooks.boot = boot; -+ simple_loader_hooks.unload = unload; -+} -+ - void - grub_loader_unset(void) - { - if (grub_loader_loaded && grub_loader_unload_func) -- grub_loader_unload_func (); -+ grub_loader_unload_func (grub_loader_context); - - grub_loader_boot_func = 0; - grub_loader_unload_func = 0; -+ grub_loader_context = 0; - - grub_loader_loaded = 0; - } -@@ -158,7 +208,7 @@ grub_loader_boot (void) - return err; - } - } -- err = (grub_loader_boot_func) (); -+ err = (grub_loader_boot_func) (grub_loader_context); - - for (cur = preboots_tail; cur; cur = cur->prev) - if (! err) -diff --git a/include/grub/loader.h b/include/grub/loader.h -index b208642821..1846fa6c5f 100644 ---- a/include/grub/loader.h -+++ b/include/grub/loader.h -@@ -40,6 +40,11 @@ void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void), - grub_err_t (*unload) (void), - int flags); - -+void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *), -+ grub_err_t (*unload) (void *), -+ void *context, -+ int flags); -+ - /* Unset current loader, if any. */ - void EXPORT_FUNC (grub_loader_unset) (void); - diff --git a/backport-commands-efi-efifwsetup-Add-missing-grub_free-s.patch b/backport-commands-efi-efifwsetup-Add-missing-grub_free-s.patch deleted file mode 100644 index fac1587..0000000 --- a/backport-commands-efi-efifwsetup-Add-missing-grub_free-s.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 01d1953fc50764206daad12d9b5dd68721353315 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Thu, 18 Aug 2022 13:50:09 -0400 -Subject: commands/efi/efifwsetup: Add missing grub_free()s - -Each call of grub_efi_get_variable() needs a grub_free(). - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=01d1953fc50764206daad12d9b5dd68721353315 -Conflict:NA - -Signed-off-by: Robbie Harwood -Reviewed-by: Daniel Kiper ---- - grub-core/commands/efi/efifwsetup.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c -index 328c45e..50cecb4 100644 ---- a/grub-core/commands/efi/efifwsetup.c -+++ b/grub-core/commands/efi/efifwsetup.c -@@ -33,17 +33,20 @@ efifwsetup_is_supported (void) - grub_efi_uint64_t *os_indications_supported = NULL; - grub_size_t oi_size = 0; - grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ grub_efi_boolean_t ret = 0; - - grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size, - (void **) &os_indications_supported); - - if (!os_indications_supported) -- return 0; -+ goto done; - - if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) -- return 1; -+ ret = 1; - -- return 0; -+ done: -+ grub_free (os_indications_supported); -+ return ret; - } - - static grub_err_t -@@ -67,6 +70,8 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), - if (old_os_indications != NULL && oi_size == sizeof (os_indications)) - os_indications |= *old_os_indications; - -+ grub_free (old_os_indications); -+ - status = grub_efi_set_variable ("OsIndications", &global, &os_indications, - sizeof (os_indications)); - if (status != GRUB_ERR_NONE) --- -2.19.1 - diff --git a/backport-commands-search-Fix-bug-stopping-iteration-when-no-floppy-is-used.patch b/backport-commands-search-Fix-bug-stopping-iteration-when-no-floppy-is-used.patch deleted file mode 100644 index 21026fa..0000000 --- a/backport-commands-search-Fix-bug-stopping-iteration-when-no-floppy-is-used.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 68ba54c2298604146be83cae144dafd1cfd1fe2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Tue, 8 Feb 2022 08:39:10 +0100 -Subject: commands/search: Fix bug stopping iteration when --no-floppy is used -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When using --no-floppy and a floppy was encountered, iterate_device() -was returning 1, causing the iteration to stop instead of continuing. - -Signed-off-by: Renaud Métrich -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=68ba54c2298604146be83cae144dafd1cfd1fe2d - ---- - grub-core/commands/search.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c -index ed090b3..51656e3 100644 ---- a/grub-core/commands/search.c -+++ b/grub-core/commands/search.c -@@ -64,7 +64,7 @@ iterate_device (const char *name, void *data) - /* Skip floppy drives when requested. */ - if (ctx->no_floppy && - name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') -- return 1; -+ return 0; - - #ifdef DO_SEARCH_FS_UUID - #define compare_fn grub_strcasecmp --- -cgit v1.1 - diff --git a/backport-correct-closing-of-SNP-protocol.patch b/backport-correct-closing-of-SNP-protocol.patch deleted file mode 100644 index 485c745..0000000 --- a/backport-correct-closing-of-SNP-protocol.patch +++ /dev/null @@ -1,112 +0,0 @@ -From efd9406e12df2b66e6704bad0ce3225aa3051c0e Mon Sep 17 00:00:00 2001 -From: Heinrich Schuchardt -Date: Mon, 29 Nov 2021 16:00:28 +0100 -Subject: efinet: Correct closing of SNP protocol - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=efd9406e12df2b66e6704bad0ce3225aa3051c0e - -In the context of the implementation of the EFI_LOAD_FILE2_PROTOCOL for -the initial ramdisk it was observed that opening the SNP protocol failed. -https://lists.gnu.org/archive/html/grub-devel/2021-10/msg00020.html -This is due to an incorrect call to CloseProtocol(). - -The first parameter of CloseProtocol() is the handle, not the interface. - -We call OpenProtocol() with ControllerHandle == NULL. Hence we must also -call CloseProtcol() with ControllerHandel == NULL. - -Each call of OpenProtocol() for the same network card handle is expected to -return the same interface pointer. If we want to close the protocol which -we opened non-exclusively when searching for a card, we have to do this -before opening the protocol exclusively. - -As there is no guarantee that we successfully open the protocol add checks -in the transmit and receive functions. - -Reported-by: Andreas Schwab -Signed-off-by: Heinrich Schuchardt -Reviewed-by: Daniel Kiper ---- - grub-core/net/drivers/efi/efinet.c | 31 ++++++++++++++++++++++--------- - 1 file changed, 22 insertions(+), 9 deletions(-) - -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 5388f95..2c81fd0 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -39,6 +39,9 @@ send_card_buffer (struct grub_net_card *dev, - grub_uint64_t limit_time = grub_get_time_ms () + 4000; - void *txbuf; - -+ if (net == NULL) -+ return grub_error (GRUB_ERR_IO, -+ N_("network protocol not available, can't send packet")); - if (dev->txbusy) - while (1) - { -@@ -101,6 +104,9 @@ get_card_packet (struct grub_net_card *dev) - struct grub_net_buff *nb; - int i; - -+ if (net == NULL) -+ return NULL; -+ - for (i = 0; i < 2; i++) - { - if (!dev->rcvbuf) -@@ -148,12 +154,20 @@ open_card (struct grub_net_card *dev) - { - grub_efi_simple_network_t *net; - -- /* Try to reopen SNP exlusively to close any active MNP protocol instance -- that may compete for packet polling -+ if (dev->efi_net != NULL) -+ { -+ efi_call_4 (grub_efi_system_table->boot_services->close_protocol, -+ dev->efi_handle, &net_io_guid, -+ grub_efi_image_handle, NULL); -+ dev->efi_net = NULL; -+ } -+ /* -+ * Try to reopen SNP exlusively to close any active MNP protocol instance -+ * that may compete for packet polling. - */ - net = grub_efi_open_protocol (dev->efi_handle, &net_io_guid, - GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE); -- if (net) -+ if (net != NULL) - { - if (net->mode->state == GRUB_EFI_NETWORK_STOPPED - && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) -@@ -192,13 +206,12 @@ open_card (struct grub_net_card *dev) - efi_call_6 (net->receive_filters, net, filters, 0, 0, 0, NULL); - } - -- efi_call_4 (grub_efi_system_table->boot_services->close_protocol, -- dev->efi_net, &net_io_guid, -- grub_efi_image_handle, dev->efi_handle); - dev->efi_net = net; -+ } else { -+ return grub_error (GRUB_ERR_NET_NO_CARD, "%s: can't open protocol", -+ dev->name); - } - -- /* If it failed we just try to run as best as we can */ - return GRUB_ERR_NONE; - } - -@@ -208,8 +221,8 @@ close_card (struct grub_net_card *dev) - efi_call_1 (dev->efi_net->shutdown, dev->efi_net); - efi_call_1 (dev->efi_net->stop, dev->efi_net); - efi_call_4 (grub_efi_system_table->boot_services->close_protocol, -- dev->efi_net, &net_io_guid, -- grub_efi_image_handle, dev->efi_handle); -+ dev->efi_handle, &net_io_guid, -+ grub_efi_image_handle, 0); - } - - static struct grub_net_card_driver efidriver = --- -cgit v1.1 - diff --git a/backport-disk-diskfilter-Check-calloc-result-for-NULL.patch b/backport-disk-diskfilter-Check-calloc-result-for-NULL.patch deleted file mode 100644 index fc392f2..0000000 --- a/backport-disk-diskfilter-Check-calloc-result-for-NULL.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 12e20a6a695f4967b30a95bb52e4e2e0a10c9094 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Sun, 21 Aug 2022 22:22:35 +1000 -Subject: [PATCH] disk/diskfilter: Check calloc() result for NULL - -With wildly corrupt inputs, we can end up trying to calloc a very -large amount of memory, which will fail and give us a NULL pointer. -We need to check that to avoid a crash. (And, even if we blocked -such inputs, it is good practice to check the results of allocations -anyway.) - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=12e20a6a695f4967b30a95bb52e4e2e0a10c9094 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/diskfilter.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c -index 2edcff6e8..4ac50320e 100644 ---- a/grub-core/disk/diskfilter.c -+++ b/grub-core/disk/diskfilter.c -@@ -1163,6 +1163,9 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, - array->lvs->segments->raid_member_size = disk_size; - array->lvs->segments->nodes - = grub_calloc (nmemb, sizeof (array->lvs->segments->nodes[0])); -+ if (array->lvs->segments->nodes == NULL) -+ goto fail; -+ - array->lvs->segments->stripe_size = stripe_size; - for (i = 0; i < nmemb; i++) - { --- -2.28.0.windows.1 - diff --git a/backport-disk-diskfilter-Don-t-make-a-RAID-array-with-more-th.patch b/backport-disk-diskfilter-Don-t-make-a-RAID-array-with-more-th.patch deleted file mode 100644 index 4326f32..0000000 --- a/backport-disk-diskfilter-Don-t-make-a-RAID-array-with-more-th.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 2a5e3c1f2aed88c2289fb595da8308e898b87915 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 19 Oct 2022 20:23:22 +1100 -Subject: [PATCH] disk/diskfilter: Don't make a RAID array with more than 1024 - disks - -This is "belt and braces" with commit 12e20a6a695f (disk/diskfilter: -Check calloc() result for NULL): we end up trying to use too much memory -in situations like corrupted Linux software RAID setups purporting to -use a huge number of disks. Simply refuse to permit such configurations. - -1024 is a bit arbitrary, yes, and I feel a bit like I'm tempting fate -here, but I think 1024 disks in an array (that GRUB has to read to boot!) -should be enough for anyone. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=2a5e3c1f2aed88c2289fb595da8308e898b87915 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/disk/diskfilter.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c -index 4ac50320e..1c568927b 100644 ---- a/grub-core/disk/diskfilter.c -+++ b/grub-core/disk/diskfilter.c -@@ -1046,6 +1046,13 @@ grub_diskfilter_make_raid (grub_size_t uuidlen, char *uuid, int nmemb, - struct grub_diskfilter_pv *pv; - grub_err_t err; - -+ /* We choose not to support more than 1024 disks. */ -+ if (nmemb < 1 || nmemb > 1024) -+ { -+ grub_free (uuid); -+ return NULL; -+ } -+ - switch (level) - { - case 1: --- -2.28.0.windows.1 - diff --git a/backport-disk-efi-efidisk-Pass-buffers-with-higher-alignment.patch b/backport-disk-efi-efidisk-Pass-buffers-with-higher-alignment.patch deleted file mode 100644 index 000ae6d..0000000 --- a/backport-disk-efi-efidisk-Pass-buffers-with-higher-alignment.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 8dc558b124056da61a30fcad15723cc652d94e0d Mon Sep 17 00:00:00 2001 -From: Stefan Agner -Date: Tue, 31 May 2022 17:53:43 +0200 -Subject: [PATCH] disk/efi/efidisk: Pass buffers with higher alignment - -Some devices report IoAlign values but seem to require buffers with -higher alignment. - -The UEFI specification is saying: "IoAlign values of 0 and 1 mean that -the buffer can be placed anywhere in memory. Otherwise, IoAlign must -be a power of 2, and the requirement is that the start address of -a buffer must be evenly divisible by IoAlign with no remainder." - -Some devices report IoAlign of 2, however seem to require 4 bytes -aligned buffers. It seems that this got misinterpreted by some vendors -assuming IoAlign is 2^IoAlign. There is also such a hint in an example -in earlier versions of the Driver Writer's Guide: - - ScsiPassThruMode.IoAlign = 2; //Data must be aligned on 4-byte boundary - -Some devices report no alignment requirements at all but seem to read -corrupted data or report read errors when passing unaligned buffers. - -Work around by using an alignment of at least BlockSize (typically 512 -bytes) in any case. If IoAlign (interpreted as per UEFI specification) -requests a higher alignment than BlockSize, follow IoAlign still. - -Note: The problem has only noticed with compressed squashfs. It seems -that ext4 (and presumably other file system drivers) pass buffers with -a higher alignment already. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=858a0745c89262d1f35b9d3d3a208573732d7e36 -Conflict:NA - -Signed-off-by: Stefan Agner -Acked-by: Heinrich Schuchardt -Reviewed-by: Daniel Kiper - ---- - grub-core/disk/efi/efidisk.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c -index fe8ba6e..cfc0176 100644 ---- a/grub-core/disk/efi/efidisk.c -+++ b/grub-core/disk/efi/efidisk.c -@@ -553,8 +553,19 @@ grub_efidisk_readwrite (struct grub_disk *disk, grub_disk_addr_t sector, - d = disk->data; - bio = d->block_io; - -- /* Set alignment to 1 if 0 specified */ -- io_align = bio->media->io_align ? bio->media->io_align : 1; -+ /* -+ * If IoAlign is > 1, it should represent the required alignment. However, -+ * some UEFI implementations seem to report IoAlign=2 but require 2^IoAlign. -+ * Some implementation seem to require alignment despite not reporting any -+ * specific requirements. -+ * -+ * Make sure to use buffers which are at least aligned to block size. -+ */ -+ if (bio->media->io_align < bio->media->block_size) -+ io_align = bio->media->block_size; -+ else -+ io_align = bio->media->io_align; -+ - num_bytes = size << disk->log_sector_size; - - if ((grub_addr_t) buf & (io_align - 1)) --- -2.27.0 - diff --git a/backport-disk-ldm-Fix-resource-leak.patch b/backport-disk-ldm-Fix-resource-leak.patch deleted file mode 100644 index 1739577..0000000 --- a/backport-disk-ldm-Fix-resource-leak.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 971dd6599d838ed21f38f7261c7bdda59f9bbdae Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Wed, 10 Nov 2021 15:49:29 -0500 -Subject: disk/ldm: Fix resource leak - -Commit 23e39f50ca7a (disk/ldm: Make sure comp data is freed before exiting from -make_vg()) fixed several spots in make_vg() where comp data was leaking memory -when an error was being handled but missed one. To avoid leaking memory, comp -should be freed when an error is being handled after comp has been successfully -allocated memory in the for loop. - -Fixes: 23e39f50ca7a (disk/ldm: Make sure comp data is freed before exiting from make_vg()) -Fixes: CID 73804 - -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=971dd6599d838ed21f38f7261c7bdda59f9bbdae - -Signed-off-by: Alec Brown -Reviewed-by: Daniel Kiper ---- - grub-core/disk/ldm.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c -index 4577a51..337abf7 100644 ---- a/grub-core/disk/ldm.c -+++ b/grub-core/disk/ldm.c -@@ -487,6 +487,7 @@ make_vg (grub_disk_t disk, - ptr = vblk[i].dynamic; - if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) - { -+ grub_free (comp); - goto fail2; - } - comp->internal_id = grub_malloc ((grub_size_t) ptr[0] + 2); --- -cgit v1.1 - diff --git a/backport-double-grub-x86_64-efi-mm-pool.patch b/backport-double-grub-x86_64-efi-mm-pool.patch deleted file mode 100644 index 92e2f3d..0000000 --- a/backport-double-grub-x86_64-efi-mm-pool.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 6d56530bd04534f038f775624e1c4942a8bf95de Mon Sep 17 00:00:00 2001 -From: fengtao -Date: Mon, 14 Feb 2022 16:17:15 +0800 -Subject: [PATCH] double grub x86_64-efi mm pool - -grub2 will construct mm pool by uefi memory function -for grub memory manger, grub_malloc, grub_free, etc. - -but we have limit memory address under x86_64 platform in -commit:456eb8632e7(Try to pick better locations for kernel and initrd) -so, x86_64 can only address available ram under 4GB. - -there comes a problem, when available memory under 4GB is not enough, -and initrd is large, like 200MB~300MB. we got out of memory when -verifiers use grub_malloc. - -Finally, we descide to double grub mm pool when we init it. And what -the point is, we cannot init all of the available memory under 4GB. -you can read commit:5ff84fb244b -(x86-efi: Allow initrd+params+cmdline allocations above 4GB.) - ---- - grub-core/kern/efi/mm.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index f64f79e..50116a6 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -658,7 +658,11 @@ grub_efi_mm_init (void) - /* By default, request a quarter of the available memory. */ - total_pages = get_total_pages (filtered_memory_map, desc_size, - filtered_memory_map_end); -+#if defined(__x86_64__) -+ required_pages = (total_pages >> 1); -+#else - required_pages = (total_pages >> 2); -+#endif - if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE)) - required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE); - else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE)) --- -2.27.0 - diff --git a/backport-enable-http-and-https-boot.patch b/backport-enable-http-and-https-boot.patch deleted file mode 100644 index 6b4c912..0000000 --- a/backport-enable-http-and-https-boot.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 354c1679b70fd7f1773ab9bb3fffc7261be42e6b Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Wed, 22 Feb 2017 14:27:50 +0800 -Subject: [PATCH] enable http and https boot - -The patch adapts to the open source code for log printing. - -V1: - * Add preliminary support of UEFI networking protocols - * Support UEFI HTTPS Boot - -V2: - * Workaround http data access in firmware - * Fix DNS device path parsing for efinet device - * Relaxed UEFI Protocol requirement - * Support Intel OPA (Omni-Path Architecture) PXE Boot - -V3: - * Fix bufio in calculating address of next_buf - * Check HTTP respond code - * Use HEAD request method to test before GET - * Finish HTTP transaction in one go - * Fix bsc#1076132 - -Reference:https://src.fedoraproject.org/rpms/grub2/blob/f35/f/0095-Support-UEFI-networking-protocols.patch -Conflict:NA - -Signed-off-by: Michael Chang -[pjones: make efi_netfs not duplicate symbols from efinet] -Signed-off-by: Peter Jones ---- - grub-core/net/efi/http.c | 2 ++ - grub-core/net/efi/net.c | 5 +++++ - include/grub/efi/http.h | 4 ++-- - 3 files changed, 9 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index fc8cb25..5dfe165 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -187,6 +187,8 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - url = grub_xasprintf ("%s://%s%s", protocol, server, name); - } - -+ grub_dprintf ("httpboot", "url: %s\n", url); -+ - if (!url) - { - return grub_errno; -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index a3f0535..6e3b37f 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -795,7 +795,10 @@ match_route (const char *server) - err = grub_efi_net_parse_address (server, &ip4, &ip6, &is_ip6, 0); - - if (err) -+ { -+ grub_dprintf ("httpboot", "server parse failed, please check!\n"); - return NULL; -+ } - - if (is_ip6) - { -@@ -1227,6 +1230,8 @@ grub_net_open_real (const char *name __attribute__ ((unused))) - return NULL; - } - -+ grub_dprintf ("httpboot", "server: %s\n", server); -+ - /*FIXME: Use DNS translate name to address */ - net_interface = match_route (server); - -diff --git a/include/grub/efi/http.h b/include/grub/efi/http.h -index c5e9a89..ad164ba 100644 ---- a/include/grub/efi/http.h -+++ b/include/grub/efi/http.h -@@ -171,9 +171,9 @@ typedef struct { - grub_efi_http_request_data_t *request; - grub_efi_http_response_data_t *response; - } data; -- grub_efi_uint32_t header_count; -+ grub_efi_uintn_t header_count; - grub_efi_http_header_t *headers; -- grub_efi_uint32_t body_length; -+ grub_efi_uintn_t body_length; - void *body; - } grub_efi_http_message_t; - --- -2.23.0 - diff --git a/backport-fbutil-Fix-integer-overflow.patch b/backport-fbutil-Fix-integer-overflow.patch deleted file mode 100644 index 41b4ebb..0000000 --- a/backport-fbutil-Fix-integer-overflow.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 1eac01c147b4d85d2ec4a7e5671fa4345f2e8549 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Tue, 6 Sep 2022 03:03:21 +0800 -Subject: [PATCH 09/13] fbutil: Fix integer overflow - -Expressions like u64 = u32 * u32 are unsafe because their products are -truncated to u32 even if left hand side is u64. This patch fixes all -problems like that one in fbutil. - -To get right result not only left hand side have to be u64 but it's also -necessary to cast at least one of the operands of all leaf operators of -right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be -u64 = (u64)u32 * u32 + (u64)u32 * u32. - -For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any -combination of values in (grub_uint64_t)u32 * u32 + u32 expression will -not overflow grub_uint64_t. - -Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable. -They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32. - -This patch also adds a comment to grub_video_fb_get_video_ptr() which -says it's arguments must be valid and no sanity check is performed -(like its siblings in grub-core/video/fb/fbutil.c). - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/video/fb/fbutil.c | 4 ++-- - include/grub/fbutil.h | 13 +++++++++---- - 2 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c -index b98bb51fe..25ef39f47 100644 ---- a/grub-core/video/fb/fbutil.c -+++ b/grub-core/video/fb/fbutil.c -@@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source, - case 1: - if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) - { -- int bit_index = y * source->mode_info->width + x; -+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x; - grub_uint8_t *ptr = source->data + bit_index / 8; - int bit_pos = 7 - bit_index % 8; - color = (*ptr >> bit_pos) & 0x01; -@@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source, - case 1: - if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) - { -- int bit_index = y * source->mode_info->width + x; -+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x; - grub_uint8_t *ptr = source->data + bit_index / 8; - int bit_pos = 7 - bit_index % 8; - *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos); -diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h -index 4205eb917..78a1ab3b4 100644 ---- a/include/grub/fbutil.h -+++ b/include/grub/fbutil.h -@@ -31,14 +31,19 @@ struct grub_video_fbblit_info - grub_uint8_t *data; - }; - --/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level -- and it doesn't make sense, in general, to ask for a pointer -- to a particular pixel's data. */ -+/* -+ * Don't use for 1-bit bitmaps, addressing needs to be done at the bit level -+ * and it doesn't make sense, in general, to ask for a pointer -+ * to a particular pixel's data. -+ * -+ * This function assumes that bounds checking has been done in previous phase -+ * and they are opted out in here. -+ */ - static inline void * - grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, - unsigned int x, unsigned int y) - { -- return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel; -+ return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel; - } - - /* Advance pointer by VAL bytes. If there is no unaligned access available, --- -2.27.0 - diff --git a/backport-fix-misspelled-variable-BUILD_LDFAGS.patch b/backport-fix-misspelled-variable-BUILD_LDFAGS.patch deleted file mode 100644 index 7a8188c..0000000 --- a/backport-fix-misspelled-variable-BUILD_LDFAGS.patch +++ /dev/null @@ -1,30 +0,0 @@ -From d17eddab81eab790689b00172a9ee8351548de82 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Tue, 7 Dec 2021 23:36:31 -0600 -Subject: configure: Fix misspelled variable BUILD_LDFAGS -> BUILD_LDFLAGS - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=d17eddab81eab790689b00172a9ee8351548de82 - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 8d1c81a..4f649ed 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1649,7 +1649,7 @@ CC="$BUILD_CC" - CPP="$BUILD_CPP" - CFLAGS="$BUILD_CFLAGS" - CPPFLAGS="$BUILD_CPPFLAGS" --LDFLAGS="$BUILD_LDFAGS" -+LDFLAGS="$BUILD_LDFLAGS" - - unset ac_cv_c_bigendian - unset ac_cv_header_ft2build_h --- -cgit v1.1 - diff --git a/backport-fix-null-pointer-dereference-when-paring-ICMP6_ROUTE.patch b/backport-fix-null-pointer-dereference-when-paring-ICMP6_ROUTE.patch deleted file mode 100644 index a83031c..0000000 --- a/backport-fix-null-pointer-dereference-when-paring-ICMP6_ROUTE.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9d7f329418139b0604071aee333d621c960915ca Mon Sep 17 00:00:00 2001 -From: Qiumiao Zhang -Date: Thu, 5 May 2022 10:35:14 +0800 -Subject: [PATCH] fix null pointer dereference when paring - ICMP6_ROUTER_ADVERTISE messages - ---- - grub-core/net/icmp6.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c -index 56a3ec5..fb88961 100644 ---- a/grub-core/net/icmp6.c -+++ b/grub-core/net/icmp6.c -@@ -480,7 +480,7 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - - /* May not have gotten slaac info, find a global address on this - card. */ -- if (route_inf == NULL) -+ if (route_inf == NULL && orig_inf != NULL) - { - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { --- -2.23.0 - diff --git a/backport-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch b/backport-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch deleted file mode 100644 index 340e699..0000000 --- a/backport-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 22b77b87e10a3a6c9bb9885415bc9a9c678378e6 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 28 Oct 2022 17:29:16 +0800 -Subject: [PATCH 12/13] font: Assign null_font to glyphs in ascii_font_glyph[] - -The calculations in blit_comb() need information from glyph's font, e.g. -grub_font_get_xheight(main_glyph->font). However, main_glyph->font is -NULL if main_glyph comes from ascii_font_glyph[]. Therefore -grub_font_get_*() crashes because of NULL pointer. - -There is already a solution, the null_font. So, assign it to those glyphs -in ascii_font_glyph[]. - -Reported-by: Daniel Axtens -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index cf15dc2f9..3821937e6 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -137,7 +137,7 @@ ascii_glyph_lookup (grub_uint32_t code) - ascii_font_glyph[current]->offset_x = 0; - ascii_font_glyph[current]->offset_y = -2; - ascii_font_glyph[current]->device_width = 8; -- ascii_font_glyph[current]->font = NULL; -+ ascii_font_glyph[current]->font = &null_font; - - grub_memcpy (ascii_font_glyph[current]->bitmap, - &ascii_bitmaps[current * ASCII_BITMAP_SIZE], --- -2.27.0 - diff --git a/backport-font-Assign-null_font-to-unknown_glyph.patch b/backport-font-Assign-null_font-to-unknown_glyph.patch deleted file mode 100644 index 610ed22..0000000 --- a/backport-font-Assign-null_font-to-unknown_glyph.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f6806966478c601a96e1f3e0e5e85cf5036555c0 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 5 Dec 2022 19:29:37 +0800 -Subject: font: Assign null_font to unknown_glyph - -Like glyphs in ascii_font_glyph[], assign null_font to -unknown_glyph->font in order to prevent grub_font_get_*() from -dereferencing NULL pointer. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=f6806966478c601a96e1f3e0e5e85cf5036555c0 -Conflict:NA - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 19a47f8..674043d 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -177,6 +177,7 @@ grub_font_loader_init (void) - unknown_glyph->offset_x = 0; - unknown_glyph->offset_y = -3; - unknown_glyph->device_width = 8; -+ unknown_glyph->font = &null_font; - grub_memcpy (unknown_glyph->bitmap, - unknown_glyph_bitmap, sizeof (unknown_glyph_bitmap)); - --- -cgit v1.1 - diff --git a/backport-font-Check-return-value-of-grub_malloc-in-ascii_glyph_lookup.patch b/backport-font-Check-return-value-of-grub_malloc-in-ascii_glyph_lookup.patch deleted file mode 100644 index e733daa..0000000 --- a/backport-font-Check-return-value-of-grub_malloc-in-ascii_glyph_lookup.patch +++ /dev/null @@ -1,40 +0,0 @@ -From d7ed2ebcd69df123fde8ae1ba9163e2b93c47bbf Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 5 Dec 2022 19:29:36 +0800 -Subject: font: Check return value of grub_malloc() in ascii_glyph_lookup() - -There is a problem in ascii_glyph_lookup(). It doesn't check the return -value of grub_malloc(). If memory can't be allocated, then NULL pointer -will be written to. - -This patch fixes the problem by fallbacking to unknown_glyph when -grub_malloc() returns NULL. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=d7ed2ebcd69df123fde8ae1ba9163e2b93c47bbf -Conflict:NA - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 3821937..19a47f8 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -131,6 +131,11 @@ ascii_glyph_lookup (grub_uint32_t code) - { - ascii_font_glyph[current] = - grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE); -+ if (ascii_font_glyph[current] == NULL) -+ { -+ ascii_font_glyph[current] = unknown_glyph; -+ continue; -+ } - - ascii_font_glyph[current]->width = 8; - ascii_font_glyph[current]->height = 16; --- -cgit v1.1 - diff --git a/backport-font-Fix-an-integer-underflow-in-blit_comb.patch b/backport-font-Fix-an-integer-underflow-in-blit_comb.patch deleted file mode 100644 index e28460a..0000000 --- a/backport-font-Fix-an-integer-underflow-in-blit_comb.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 992c06191babc1e109caf40d6a07ec6fdef427af Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 24 Oct 2022 08:05:35 +0800 -Subject: [PATCH 10/13] font: Fix an integer underflow in blit_comb() - -The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may -evaluate to a very big invalid value even if both ctx.bounds.height and -combining_glyphs[i]->height are small integers. For example, if -ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this -expression evaluates to 2147483647 (expected -1). This is because -coordinates are allowed to be negative but ctx.bounds.height is an -unsigned int. So, the subtraction operates on unsigned ints and -underflows to a very big value. The division makes things even worse. -The quotient is still an invalid value even if converted back to int. - -This patch fixes the problem by casting ctx.bounds.height to int. As -a result the subtraction will operate on int and grub_uint16_t which -will be promoted to an int. So, the underflow will no longer happen. Other -uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int, -to ensure coordinates are always calculated on signed integers. - -Fixes: CVE-2022-3775 - -Reported-by: Daniel Axtens -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index abd412a5e..3d3d803e8 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1203,12 +1203,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - ctx.bounds.height = main_glyph->height; - - above_rightx = main_glyph->offset_x + main_glyph->width; -- above_righty = ctx.bounds.y + ctx.bounds.height; -+ above_righty = ctx.bounds.y + (int) ctx.bounds.height; - - above_leftx = main_glyph->offset_x; -- above_lefty = ctx.bounds.y + ctx.bounds.height; -+ above_lefty = ctx.bounds.y + (int) ctx.bounds.height; - -- below_rightx = ctx.bounds.x + ctx.bounds.width; -+ below_rightx = ctx.bounds.x + (int) ctx.bounds.width; - below_righty = ctx.bounds.y; - - comb = grub_unicode_get_comb (glyph_id); -@@ -1221,7 +1221,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - - if (!combining_glyphs[i]) - continue; -- targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; -+ targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; - /* CGJ is to avoid diacritics reordering. */ - if (comb[i].code - == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) -@@ -1231,8 +1231,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - case GRUB_UNICODE_COMB_OVERLAY: - do_blit (combining_glyphs[i], - targetx, -- (ctx.bounds.height - combining_glyphs[i]->height) / 2 -- - (ctx.bounds.height + ctx.bounds.y), &ctx); -+ ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2 -+ - ((int) ctx.bounds.height + ctx.bounds.y), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; - break; -@@ -1305,7 +1305,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - /* Fallthrough. */ - case GRUB_UNICODE_STACK_ATTACHED_ABOVE: - do_blit (combining_glyphs[i], targetx, -- -(ctx.bounds.height + ctx.bounds.y + space -+ -((int) ctx.bounds.height + ctx.bounds.y + space - + combining_glyphs[i]->height), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; -@@ -1313,7 +1313,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - - case GRUB_UNICODE_COMB_HEBREW_DAGESH: - do_blit (combining_glyphs[i], targetx, -- -(ctx.bounds.height / 2 + ctx.bounds.y -+ -((int) ctx.bounds.height / 2 + ctx.bounds.y - + combining_glyphs[i]->height / 2), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; --- -2.27.0 - diff --git a/backport-font-Fix-integer-overflow-in-BMP-index.patch b/backport-font-Fix-integer-overflow-in-BMP-index.patch deleted file mode 100644 index e401afc..0000000 --- a/backport-font-Fix-integer-overflow-in-BMP-index.patch +++ /dev/null @@ -1,65 +0,0 @@ -From b9396daf1c2e3cdc0a1e69b056852e0769fb24de Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 15 Aug 2022 02:04:58 +0800 -Subject: [PATCH 06/13] font: Fix integer overflow in BMP index - -The BMP index (font->bmp_idx) is designed as a reverse lookup table of -char entries (font->char_index), in order to speed up lookups for BMP -chars (i.e. code < 0x10000). The values in BMP index are the subscripts -of the corresponding char entries, stored in grub_uint16_t, while 0xffff -means not found. - -This patch fixes the problem of large subscript truncated to grub_uint16_t, -leading BMP index to return wrong char entry or report false miss. The -code now checks for bounds and uses BMP index as a hint, and fallbacks -to binary-search if necessary. - -On the occasion add a comment about BMP index is initialized to 0xffff. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 9e3e0a94e..e4cb0d867 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -300,6 +300,8 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct - font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); - if (!font->bmp_idx) - return 1; -+ -+ /* Init the BMP index array to 0xffff. */ - grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t)); - - -@@ -328,7 +330,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct - return 1; - } - -- if (entry->code < 0x10000) -+ if (entry->code < 0x10000 && i < 0xffff) - font->bmp_idx[entry->code] = i; - - last_code = entry->code; -@@ -696,9 +698,12 @@ find_glyph (const grub_font_t font, grub_uint32_t code) - /* Use BMP index if possible. */ - if (code < 0x10000 && font->bmp_idx) - { -- if (font->bmp_idx[code] == 0xffff) -- return 0; -- return &table[font->bmp_idx[code]]; -+ if (font->bmp_idx[code] < 0xffff) -+ return &table[font->bmp_idx[code]]; -+ /* -+ * When we are here then lookup in BMP index result in miss, -+ * fallthough to binary-search. -+ */ - } - - /* Do a binary search in `char_index', which is ordered by code point. */ --- -2.27.0 - diff --git a/backport-font-Fix-integer-overflow-in-ensure_comb_space.patch b/backport-font-Fix-integer-overflow-in-ensure_comb_space.patch deleted file mode 100644 index 406f4df..0000000 --- a/backport-font-Fix-integer-overflow-in-ensure_comb_space.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 23843fe8947e4da955a05ad3d1858725bfcb56c8 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 5 Aug 2022 02:27:05 +0800 -Subject: [PATCH 05/13] font: Fix integer overflow in ensure_comb_space() - -In fact it can't overflow at all because glyph_id->ncomb is only 8-bit -wide. But let's keep safe if somebody changes the width of glyph_id->ncomb -in the future. This patch also fixes the inconsistency between -render_max_comb_glyphs and render_combining_glyphs when grub_malloc() -returns NULL. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index a8576ffec..9e3e0a94e 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1468,14 +1468,18 @@ ensure_comb_space (const struct grub_unicode_glyph *glyph_id) - if (glyph_id->ncomb <= render_max_comb_glyphs) - return; - -- render_max_comb_glyphs = 2 * glyph_id->ncomb; -- if (render_max_comb_glyphs < 8) -+ if (grub_mul (glyph_id->ncomb, 2, &render_max_comb_glyphs)) -+ render_max_comb_glyphs = 0; -+ if (render_max_comb_glyphs > 0 && render_max_comb_glyphs < 8) - render_max_comb_glyphs = 8; - grub_free (render_combining_glyphs); -- render_combining_glyphs = grub_malloc (render_max_comb_glyphs -- * sizeof (render_combining_glyphs[0])); -+ render_combining_glyphs = (render_max_comb_glyphs > 0) ? -+ grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL; - if (!render_combining_glyphs) -- grub_errno = 0; -+ { -+ render_max_comb_glyphs = 0; -+ grub_errno = GRUB_ERR_NONE; -+ } - } - - int --- -2.27.0 - diff --git a/backport-font-Fix-integer-underflow-in-binary-search-of-char-.patch b/backport-font-Fix-integer-underflow-in-binary-search-of-char-.patch deleted file mode 100644 index fb8de3e..0000000 --- a/backport-font-Fix-integer-underflow-in-binary-search-of-char-.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 1d2015598cc7a9fca4b39186273e3519a88e80c7 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Sun, 14 Aug 2022 18:09:38 +0800 -Subject: [PATCH 07/13] font: Fix integer underflow in binary search of char - index - -If search target is less than all entries in font->index then "hi" -variable is set to -1, which translates to SIZE_MAX and leads to errors. - -This patch fixes the problem by replacing the entire binary search code -with the libstdc++'s std::lower_bound() implementation. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 40 ++++++++++++++++++++++------------------ - 1 file changed, 22 insertions(+), 18 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index e4cb0d867..abd412a5e 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -688,12 +688,12 @@ read_be_int16 (grub_file_t file, grub_int16_t * value) - static inline struct char_index_entry * - find_glyph (const grub_font_t font, grub_uint32_t code) - { -- struct char_index_entry *table; -- grub_size_t lo; -- grub_size_t hi; -- grub_size_t mid; -+ struct char_index_entry *table, *first, *end; -+ grub_size_t len; - - table = font->char_index; -+ if (table == NULL) -+ return NULL; - - /* Use BMP index if possible. */ - if (code < 0x10000 && font->bmp_idx) -@@ -706,25 +706,29 @@ find_glyph (const grub_font_t font, grub_uint32_t code) - */ - } - -- /* Do a binary search in `char_index', which is ordered by code point. */ -- lo = 0; -- hi = font->num_chars - 1; -- -- if (!table) -- return 0; -+ /* -+ * Do a binary search in char_index which is ordered by code point. -+ * The code below is the same as libstdc++'s std::lower_bound(). -+ */ -+ first = table; -+ len = font->num_chars; -+ end = first + len; - -- while (lo <= hi) -+ while (len > 0) - { -- mid = lo + (hi - lo) / 2; -- if (code < table[mid].code) -- hi = mid - 1; -- else if (code > table[mid].code) -- lo = mid + 1; -+ grub_size_t half = len >> 1; -+ struct char_index_entry *middle = first + half; -+ -+ if (middle->code < code) -+ { -+ first = middle + 1; -+ len = len - half - 1; -+ } - else -- return &table[mid]; -+ len = half; - } - -- return 0; -+ return (first < end && first->code == code) ? first : NULL; - } - - /* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded --- -2.27.0 - diff --git a/backport-font-Fix-several-integer-overflows-in-grub_font_cons.patch b/backport-font-Fix-several-integer-overflows-in-grub_font_cons.patch deleted file mode 100644 index ed81351..0000000 --- a/backport-font-Fix-several-integer-overflows-in-grub_font_cons.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 768e1ef2fc159f6e14e7246e4be09363708ac39e Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 5 Aug 2022 01:58:27 +0800 -Subject: [PATCH 03/13] font: Fix several integer overflows in - grub_font_construct_glyph() - -This patch fixes several integer overflows in grub_font_construct_glyph(). -Glyphs of invalid size, zero or leading to an overflow, are rejected. -The inconsistency between "glyph" and "max_glyph_size" when grub_malloc() -returns NULL is fixed too. - -Fixes: CVE-2022-2601 - -Reported-by: Zhang Boyang -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 29 +++++++++++++++++------------ - 1 file changed, 17 insertions(+), 12 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index e781521a7..e6548892f 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1517,6 +1517,7 @@ grub_font_construct_glyph (grub_font_t hinted_font, - struct grub_video_signed_rect bounds; - static struct grub_font_glyph *glyph = 0; - static grub_size_t max_glyph_size = 0; -+ grub_size_t cur_glyph_size; - - ensure_comb_space (glyph_id); - -@@ -1533,29 +1534,33 @@ grub_font_construct_glyph (grub_font_t hinted_font, - if (!glyph_id->ncomb && !glyph_id->attributes) - return main_glyph; - -- if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) -+ if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) || -+ grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size)) -+ return main_glyph; -+ -+ if (max_glyph_size < cur_glyph_size) - { - grub_free (glyph); -- max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2; -- if (max_glyph_size < 8) -- max_glyph_size = 8; -- glyph = grub_malloc (max_glyph_size); -+ if (grub_mul (cur_glyph_size, 2, &max_glyph_size)) -+ max_glyph_size = 0; -+ glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL; - } - if (!glyph) - { -+ max_glyph_size = 0; - grub_errno = GRUB_ERR_NONE; - return main_glyph; - } - -- grub_memset (glyph, 0, sizeof (*glyph) -- + (bounds.width * bounds.height -- + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT); -+ grub_memset (glyph, 0, cur_glyph_size); - - glyph->font = main_glyph->font; -- glyph->width = bounds.width; -- glyph->height = bounds.height; -- glyph->offset_x = bounds.x; -- glyph->offset_y = bounds.y; -+ if (bounds.width == 0 || bounds.height == 0 || -+ grub_cast (bounds.width, &glyph->width) || -+ grub_cast (bounds.height, &glyph->height) || -+ grub_cast (bounds.x, &glyph->offset_x) || -+ grub_cast (bounds.y, &glyph->offset_y)) -+ return main_glyph; - - if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) - grub_font_blit_glyph_mirror (glyph, main_glyph, --- -2.27.0 - diff --git a/backport-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch b/backport-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch deleted file mode 100644 index 5efb396..0000000 --- a/backport-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 9c76ec09ae08155df27cd237eaea150b4f02f532 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 5 Aug 2022 00:51:20 +0800 -Subject: [PATCH 02/13] font: Fix size overflow in - grub_font_get_glyph_internal() - -The length of memory allocation and file read may overflow. This patch -fixes the problem by using safemath macros. - -There is a lot of code repetition like "(x * y + 7) / 8". It is unsafe -if overflow happens. This patch introduces grub_video_bitmap_calc_1bpp_bufsz(). -It is safe replacement for such code. It has safemath-like prototype. - -This patch also introduces grub_cast(value, pointer), it casts value to -typeof(*pointer) then store the value to *pointer. It returns true when -overflow occurs or false if there is no overflow. The semantics of arguments -and return value are designed to be consistent with other safemath macros. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 17 +++++++++++++---- - include/grub/bitmap.h | 18 ++++++++++++++++++ - include/grub/safemath.h | 2 ++ - 3 files changed, 33 insertions(+), 4 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 756ca0abf..e781521a7 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -739,7 +739,8 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) - grub_int16_t xoff; - grub_int16_t yoff; - grub_int16_t dwidth; -- int len; -+ grub_ssize_t len; -+ grub_size_t sz; - - if (index_entry->glyph) - /* Return cached glyph. */ -@@ -768,9 +769,17 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) - return 0; - } - -- len = (width * height + 7) / 8; -- glyph = grub_malloc (sizeof (struct grub_font_glyph) + len); -- if (!glyph) -+ /* Calculate real struct size of current glyph. */ -+ if (grub_video_bitmap_calc_1bpp_bufsz (width, height, &len) || -+ grub_add (sizeof (struct grub_font_glyph), len, &sz)) -+ { -+ remove_font (font); -+ return 0; -+ } -+ -+ /* Allocate and initialize the glyph struct. */ -+ glyph = grub_malloc (sz); -+ if (glyph == NULL) - { - remove_font (font); - return 0; -diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h -index 149d37bfe..431048936 100644 ---- a/include/grub/bitmap.h -+++ b/include/grub/bitmap.h -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #define IMAGE_HW_MAX_PX 16384 - -@@ -81,6 +82,23 @@ grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) - return bitmap->mode_info.height; - } - -+/* -+ * Calculate and store the size of data buffer of 1bit bitmap in result. -+ * Equivalent to "*result = (width * height + 7) / 8" if no overflow occurs. -+ * Return true when overflow occurs or false if there is no overflow. -+ * This function is intentionally implemented as a macro instead of -+ * an inline function. Although a bit awkward, it preserves data types for -+ * safemath macros and reduces macro side effects as much as possible. -+ * -+ * XXX: Will report false overflow if width * height > UINT64_MAX. -+ */ -+#define grub_video_bitmap_calc_1bpp_bufsz(width, height, result) \ -+({ \ -+ grub_uint64_t _bitmap_pixels; \ -+ grub_mul ((width), (height), &_bitmap_pixels) ? 1 : \ -+ grub_cast (_bitmap_pixels / GRUB_CHAR_BIT + !!(_bitmap_pixels % GRUB_CHAR_BIT), (result)); \ -+}) -+ - void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap, - struct grub_video_mode_info *mode_info); - -diff --git a/include/grub/safemath.h b/include/grub/safemath.h -index 51290d355..fbd9b5925 100644 ---- a/include/grub/safemath.h -+++ b/include/grub/safemath.h -@@ -30,6 +30,8 @@ - #define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res) - #define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res) - -+#define grub_cast(a, res) grub_add ((a), 0, (res)) -+ - #else - #error gcc 5.1 or newer or clang 3.8 or newer is required - #endif --- -2.27.0 - diff --git a/backport-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch b/backport-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch deleted file mode 100644 index 9ab6159..0000000 --- a/backport-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 9d81f71c6b8f55cf20cd56f5fe29c759df9b48cc Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 24 Oct 2022 07:15:41 +0800 -Subject: [PATCH 11/13] font: Harden grub_font_blit_glyph() and - grub_font_blit_glyph_mirror() - -As a mitigation and hardening measure add sanity checks to -grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch -makes these two functions do nothing if target blitting area isn't fully -contained in target bitmap. Therefore, if complex calculations in caller -overflows and malicious coordinates are given, we are still safe because -any coordinates which result in out-of-bound-write are rejected. However, -this patch only checks for invalid coordinates, and doesn't provide any -protection against invalid source glyph or destination glyph, e.g. -mismatch between glyph size and buffer size. - -This hardening measure is designed to mitigate possible overflows in -blit_comb(). If overflow occurs, it may return invalid bounding box -during dry run and call grub_font_blit_glyph() with malicious -coordinates during actual blitting. However, we are still safe because -the scratch glyph itself is valid, although its size makes no sense, and -any invalid coordinates are rejected. - -It would be better to call grub_fatal() if illegal parameter is detected. -However, doing this may end up in a dangerous recursion because grub_fatal() -would print messages to the screen and we are in the progress of drawing -characters on the screen. - -Reported-by: Daniel Axtens -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 3d3d803e8..cf15dc2f9 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1069,8 +1069,15 @@ static void - grub_font_blit_glyph (struct grub_font_glyph *target, - struct grub_font_glyph *src, unsigned dx, unsigned dy) - { -+ grub_uint16_t max_x, max_y; - unsigned src_bit, tgt_bit, src_byte, tgt_byte; - unsigned i, j; -+ -+ /* Harden against out-of-bound writes. */ -+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) || -+ (grub_add (dy, src->height, &max_y) || max_y > target->height)) -+ return; -+ - for (i = 0; i < src->height; i++) - { - src_bit = (src->width * i) % 8; -@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target, - struct grub_font_glyph *src, - unsigned dx, unsigned dy) - { -+ grub_uint16_t max_x, max_y; - unsigned tgt_bit, src_byte, tgt_byte; - signed src_bit; - unsigned i, j; -+ -+ /* Harden against out-of-bound writes. */ -+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) || -+ (grub_add (dy, src->height, &max_y) || max_y > target->height)) -+ return; -+ - for (i = 0; i < src->height; i++) - { - src_bit = (src->width * i + src->width - 1) % 8; --- -2.27.0 - diff --git a/backport-font-Reject-fonts-with-negative-max_char_width-or-max_char_height.patch b/backport-font-Reject-fonts-with-negative-max_char_width-or-max_char_height.patch deleted file mode 100644 index b3bd71f..0000000 --- a/backport-font-Reject-fonts-with-negative-max_char_width-or-max_char_height.patch +++ /dev/null @@ -1,36 +0,0 @@ -From faca60df7686a9a3ad9693e8a7b2c6a3a823d133 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 5 Dec 2022 19:29:38 +0800 -Subject: font: Reject fonts with negative max_char_width or max_char_height - -If max_char_width or max_char_height are negative wrong values can be propagated -by grub_font_get_max_char_width() or grub_font_get_max_char_height(). Prevent -this from happening. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=faca60df7686a9a3ad9693e8a7b2c6a3a823d133 -Conflict:NA - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 674043d..24adcb3 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -644,8 +644,8 @@ grub_font_load (const char *filename) - font->max_char_width, font->max_char_height, font->num_chars); - #endif - -- if (font->max_char_width == 0 -- || font->max_char_height == 0 -+ if (font->max_char_width <= 0 -+ || font->max_char_height <= 0 - || font->num_chars == 0 - || font->char_index == 0 || font->ascent == 0 || font->descent == 0) - { --- -cgit v1.1 - diff --git a/backport-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch b/backport-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch deleted file mode 100644 index ed6b0eb..0000000 --- a/backport-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch +++ /dev/null @@ -1,33 +0,0 @@ -From f6b6236077f059e64ee315f2d7acb8fa4eda87c5 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Wed, 3 Aug 2022 19:45:33 +0800 -Subject: [PATCH 01/13] font: Reject glyphs exceeds font->max_glyph_width or - font->max_glyph_height - -Check glyph's width and height against limits specified in font's -metadata. Reject the glyph (and font) if such limits are exceeded. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 42189c325..756ca0abf 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -760,7 +760,9 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) - || read_be_uint16 (font->file, &height) != 0 - || read_be_int16 (font->file, &xoff) != 0 - || read_be_int16 (font->file, &yoff) != 0 -- || read_be_int16 (font->file, &dwidth) != 0) -+ || read_be_int16 (font->file, &dwidth) != 0 -+ || width > font->max_char_width -+ || height > font->max_char_height) - { - remove_font (font); - return 0; --- -2.27.0 - diff --git a/backport-font-Remove-grub_font_dup_glyph.patch b/backport-font-Remove-grub_font_dup_glyph.patch deleted file mode 100644 index 60d735c..0000000 --- a/backport-font-Remove-grub_font_dup_glyph.patch +++ /dev/null @@ -1,42 +0,0 @@ -From c51292274ded3259eb04c2f1c8d253ffbdb5216a Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 5 Aug 2022 02:13:29 +0800 -Subject: [PATCH 04/13] font: Remove grub_font_dup_glyph() - -Remove grub_font_dup_glyph() since nobody is using it since 2013, and -I'm too lazy to fix the integer overflow problem in it. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/font/font.c | 14 -------------- - 1 file changed, 14 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index e6548892f..a8576ffec 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1055,20 +1055,6 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) - return best_glyph; - } - --#if 0 --static struct grub_font_glyph * --grub_font_dup_glyph (struct grub_font_glyph *glyph) --{ -- static struct grub_font_glyph *ret; -- ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8); -- if (!ret) -- return NULL; -- grub_memcpy (ret, glyph, sizeof (*ret) -- + (glyph->width * glyph->height + 7) / 8); -- return ret; --} --#endif -- - /* FIXME: suboptimal. */ - static void - grub_font_blit_glyph (struct grub_font_glyph *target, --- -2.27.0 - diff --git a/backport-fs-affs-Fix-resource-leaks.patch b/backport-fs-affs-Fix-resource-leaks.patch deleted file mode 100644 index 85a6afb..0000000 --- a/backport-fs-affs-Fix-resource-leaks.patch +++ /dev/null @@ -1,65 +0,0 @@ -From ebf32bc4e9561800b9fda59560277cbee6302643 Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Wed, 2 Feb 2022 19:08:21 -0500 -Subject: fs/affs: Fix resource leaks - -In commit 178ac5107389 (affs: Fix memory leaks), fixes were made to -grub_affs_iterate_dir() to prevent memory leaks from occurring after it -returns without freeing node. However, there were still some instances -where node was causing a memory leak when the function returns after -calling grub_affs_create_node(). In this function, new memory is -allocated to node but doesn't get freed until the hook() function is -called near the end. Before hook() is called, node should be freed in -grub_affs_create_node() before returning out of it. - -Fixes: 178ac5107389 (affs: Fix memory leaks) -Fixes: CID 73759 - -Signed-off-by: Alec Brown -Reviewed-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=ebf32bc4e9561800b9fda59560277cbee6302643 - ---- - grub-core/fs/affs.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c -index cafcd0f..7b9e620 100644 ---- a/grub-core/fs/affs.c -+++ b/grub-core/fs/affs.c -@@ -370,17 +370,26 @@ grub_affs_create_node (grub_fshelp_node_t dir, - GRUB_DISK_SECTOR_SIZE - GRUB_AFFS_FILE_LOCATION, - sizeof ((*node)->di), (char *) &(*node)->di); - if (err) -- return 1; -+ { -+ grub_free (*node); -+ return 1; -+ } - continue; - } - default: -- return 0; -+ { -+ grub_free (*node); -+ return 0; -+ } - } - break; - } - - if (nest == 8) -- return 0; -+ { -+ grub_free (*node); -+ return 0; -+ } - - type |= GRUB_FSHELP_CASE_INSENSITIVE; - --- -cgit v1.1 - diff --git a/backport-fs-fat-Dont-error-when-mtime-is-0.patch b/backport-fs-fat-Dont-error-when-mtime-is-0.patch deleted file mode 100644 index 7d4e0f2..0000000 --- a/backport-fs-fat-Dont-error-when-mtime-is-0.patch +++ /dev/null @@ -1,69 +0,0 @@ -From e43f3d93b28cce852c110c7a8e40d8311bcd8bb1 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Fri, 15 Jul 2022 16:13:02 -0400 -Subject: fs/fat: Don't error when mtime is 0 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In the wild, we occasionally see valid ESPs where some file modification -times are 0. For instance: - - ├── [Dec 31 1979] EFI - │ ├── [Dec 31 1979] BOOT - │ │ ├── [Dec 31 1979] BOOTX64.EFI - │ │ └── [Dec 31 1979] fbx64.efi - │ └── [Jun 27 02:41] fedora - │ ├── [Dec 31 1979] BOOTX64.CSV - │ ├── [Dec 31 1979] fonts - │ ├── [Mar 14 03:35] fw - │ │ ├── [Mar 14 03:35] fwupd-359c1169-abd6-4a0d-8bce-e4d4713335c1.cap - │ │ ├── [Mar 14 03:34] fwupd-9d255c4b-2d88-4861-860d-7ee52ade9463.cap - │ │ └── [Mar 14 03:34] fwupd-b36438d8-9128-49d2-b280-487be02d948b.cap - │ ├── [Dec 31 1979] fwupdx64.efi - │ ├── [May 10 10:47] grub.cfg - │ ├── [Jun 3 12:38] grub.cfg.new.new - │ ├── [May 10 10:41] grub.cfg.old - │ ├── [Jun 27 02:41] grubenv - │ ├── [Dec 31 1979] grubx64.efi - │ ├── [Dec 31 1979] mmx64.efi - │ ├── [Dec 31 1979] shim.efi - │ ├── [Dec 31 1979] shimx64.efi - │ └── [Dec 31 1979] shimx64-fedora.efi - └── [Dec 31 1979] FSCK0000.REC - - 5 directories, 17 files - -This causes grub-probe failure, which in turn causes grub-mkconfig -failure. They are valid filesystems that appear intact, and the Linux -FAT stack is able to mount and manipulate them without complaint. - -The check for mtime of 0 has been present since -20def1a3c3952982395cd7c3ea7e78638527962b (fat: support file -modification times). - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=e43f3d93b28cce852c110c7a8e40d8311bcd8bb1 -Conflict:NA - -Signed-off-by: Robbie Harwood -Reviewed-by: Daniel Kiper ---- - grub-core/fs/fat.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c -index 0951b2e..c5efed7 100644 ---- a/grub-core/fs/fat.c -+++ b/grub-core/fs/fat.c -@@ -1027,9 +1027,6 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, - grub_le_to_cpu16 (ctxt.dir.w_date), - &info.mtime); - #endif -- if (info.mtimeset == 0) -- grub_error (GRUB_ERR_OUT_OF_RANGE, -- "invalid modification timestamp for %s", path); - - if (hook (ctxt.filename, &info, hook_data)) - break; --- -cgit v1.1 diff --git a/backport-fs-iso9660-Add-check-to-prevent-infinite-loop.patch b/backport-fs-iso9660-Add-check-to-prevent-infinite-loop.patch deleted file mode 100644 index e771550..0000000 --- a/backport-fs-iso9660-Add-check-to-prevent-infinite-loop.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 4e0bab34ece7b757a1b96be59ba54a009a5cc354 Mon Sep 17 00:00:00 2001 -From: Lidong Chen -Date: Fri, 20 Jan 2023 19:39:38 +0000 -Subject: fs/iso9660: Add check to prevent infinite loop - -There is no check for the end of block when reading -directory extents. It resulted in read_node() always -read from the same offset in the while loop, thus -caused infinite loop. The fix added a check for the -end of the block and ensure the read is within directory -boundary. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/patch/?id=4e0bab34ece7b757a1b96be59ba54a009a5cc354 -Conflict:NA - -Signed-off-by: Lidong Chen -Reviewed-by: Thomas Schmitt -Reviewed-by: Daniel Kiper ---- - grub-core/fs/iso9660.c | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c -index df9f778..24d84a5 100644 ---- a/grub-core/fs/iso9660.c -+++ b/grub-core/fs/iso9660.c -@@ -801,6 +801,16 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, - while (dirent.flags & FLAG_MORE_EXTENTS) - { - offset += dirent.len; -+ -+ /* offset should within the dir's len. */ -+ if (offset > len) -+ { -+ if (ctx.filename_alloc) -+ grub_free (ctx.filename); -+ grub_free (node); -+ return 0; -+ } -+ - if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) - { - if (ctx.filename_alloc) -@@ -808,6 +818,18 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, - grub_free (node); - return 0; - } -+ -+ /* -+ * It is either the end of block or zero-padded sector, -+ * skip to the next block. -+ */ -+ if (!dirent.len) -+ { -+ offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ; -+ dirent.flags |= FLAG_MORE_EXTENTS; -+ continue; -+ } -+ - if (node->have_dirents >= node->alloc_dirents) - { - struct grub_fshelp_node *new_node; --- -cgit v1.1 - diff --git a/backport-fs-iso9660-Avoid-reading-past-the-entry-boundary.patch b/backport-fs-iso9660-Avoid-reading-past-the-entry-boundary.patch deleted file mode 100644 index 682d7ac..0000000 --- a/backport-fs-iso9660-Avoid-reading-past-the-entry-boundary.patch +++ /dev/null @@ -1,54 +0,0 @@ -From c44b1428c4c7d2bb01359fd885720af87e10b1b2 Mon Sep 17 00:00:00 2001 -From: Lidong Chen -Date: Fri, 20 Jan 2023 19:39:40 +0000 -Subject: fs/iso9660: Avoid reading past the entry boundary - -Added a check for the SP entry data boundary before reading it. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=c44b1428c4c7d2bb01359fd885720af87e10b1b2 -Conflict:NA - -Signed-off-by: Lidong Chen -Reviewed-by: Thomas Schmitt -Reviewed-by: Daniel Kiper ---- - grub-core/fs/iso9660.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c -index 230048a..ecf6bbe 100644 ---- a/grub-core/fs/iso9660.c -+++ b/grub-core/fs/iso9660.c -@@ -415,6 +415,9 @@ set_rockridge (struct grub_iso9660_data *data) - if (!sua_size) - return GRUB_ERR_NONE; - -+ if (sua_size < GRUB_ISO9660_SUSP_HEADER_SZ) -+ return grub_error (GRUB_ERR_BAD_FS, "invalid rock ridge entry size"); -+ - sua = grub_malloc (sua_size); - if (! sua) - return grub_errno; -@@ -441,8 +444,17 @@ set_rockridge (struct grub_iso9660_data *data) - rootnode.have_symlink = 0; - rootnode.dirents[0] = data->voldesc.rootdir; - -- /* The 2nd data byte stored how many bytes are skipped every time -- to get to the SUA (System Usage Area). */ -+ /* The size of SP (version 1) is fixed to 7. */ -+ if (sua_size < 7 || entry->len < 7) -+ { -+ grub_free (sua); -+ return grub_error (GRUB_ERR_BAD_FS, "corrupted rock ridge entry"); -+ } -+ -+ /* -+ * The 2nd data byte stored how many bytes are skipped every time -+ * to get to the SUA (System Usage Area). -+ */ - data->susp_skip = entry->data[2]; - entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); - --- -cgit v1.1 - diff --git a/backport-fs-iso9660-Fix-memory-leaks-in-grub_iso9660_susp_ite.patch b/backport-fs-iso9660-Fix-memory-leaks-in-grub_iso9660_susp_ite.patch deleted file mode 100644 index 81bb3fa..0000000 --- a/backport-fs-iso9660-Fix-memory-leaks-in-grub_iso9660_susp_ite.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 7338cbe91a24ee9639597a0d8bebc32b8b46c26c Mon Sep 17 00:00:00 2001 -From: "t.feng" -Date: Tue, 29 Nov 2022 17:14:13 +0800 -Subject: [PATCH] fs/iso9660: Fix memory leaks in grub_iso9660_susp_iterate() - -Fixes: 99373ce47 (* grub-core/fs/iso9660.c: Remove nested functions) - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=7338cbe91a24ee9639597a0d8bebc32b8b46c26c -Conflict:NA - -Signed-off-by: t.feng -Reviewed-by: Thomas Schmitt -Reviewed-by: Daniel Kiper ---- - grub-core/fs/iso9660.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c -index 91817ec1f..df9f7783b 100644 ---- a/grub-core/fs/iso9660.c -+++ b/grub-core/fs/iso9660.c -@@ -279,7 +279,10 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - /* Load a part of the System Usage Area. */ - err = read_node (node, off, sua_size, sua); - if (err) -- return err; -+ { -+ grub_free (sua); -+ return err; -+ } - - for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; - entry = (struct grub_iso9660_susp_entry *) -@@ -309,7 +312,10 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - err = grub_disk_read (node->data->disk, ce_block, off, - sua_size, sua); - if (err) -- return err; -+ { -+ grub_free (sua); -+ return err; -+ } - - entry = (struct grub_iso9660_susp_entry *) sua; - } --- -2.28.0.windows.1 - diff --git a/backport-fs-iso9660-Incorrect-check-for-entry-boundary.patch b/backport-fs-iso9660-Incorrect-check-for-entry-boundary.patch deleted file mode 100644 index ec0d5da..0000000 --- a/backport-fs-iso9660-Incorrect-check-for-entry-boundary.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 77f657dc9e67a1fd6b1941609a4ed798e99bcae2 Mon Sep 17 00:00:00 2001 -From: Lidong Chen -Date: Fri, 20 Jan 2023 19:39:41 +0000 -Subject: fs/iso9660: Incorrect check for entry boundary - -An SL entry consists of the entry info and the component area. -The entry info should take up 5 bytes instead of sizeof(*entry). -The area after the first 5 bytes is the component area. It is -incorrect to use the sizeof(*entry) to check the entry boundary. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=77f657dc9e67a1fd6b1941609a4ed798e99bcae2 -Conflict:NA - -Signed-off-by: Lidong Chen -Reviewed-by: Thomas Schmitt -Reviewed-by: Daniel Kiper ---- - grub-core/fs/iso9660.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c -index ecf6bbe..64ea3d4 100644 ---- a/grub-core/fs/iso9660.c -+++ b/grub-core/fs/iso9660.c -@@ -669,10 +669,23 @@ susp_iterate_dir (struct grub_iso9660_susp_entry *entry, - else if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0) - { - unsigned int pos = 1; -+ unsigned int csize; - -- /* The symlink is not stored as a POSIX symlink, translate it. */ -- while (pos + sizeof (*entry) < entry->len) -+ /* The symlink is not stored as a POSIX symlink, translate it. */ -+ while ((pos + GRUB_ISO9660_SUSP_HEADER_SZ + 1) < entry->len) - { -+ /* -+ * entry->len is GRUB_ISO9660_SUSP_HEADER_SZ + 1 (the FLAGS) + -+ * length of the "Component Area". The length of a component -+ * record is 2 (pos and pos + 1) plus the "Component Content", -+ * of which starts at pos + 2. entry->data[pos] is the -+ * "Component Flags"; entry->data[pos + 1] is the length -+ * of the component. -+ */ -+ csize = entry->data[pos + 1] + 2; -+ if (GRUB_ISO9660_SUSP_HEADER_SZ + 1 + csize > entry->len) -+ break; -+ - /* The current position is the `Component Flag'. */ - switch (entry->data[pos] & 30) - { --- -cgit v1.1 - diff --git a/backport-fs-iso9660-Prevent-read-past-the-end-of-system-use-area.patch b/backport-fs-iso9660-Prevent-read-past-the-end-of-system-use-area.patch deleted file mode 100644 index 8cd79b0..0000000 --- a/backport-fs-iso9660-Prevent-read-past-the-end-of-system-use-area.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 8f41d35fcecb65746b60aaa99936cbbdf5fb27ba Mon Sep 17 00:00:00 2001 -From: Lidong Chen -Date: Wed, 1 Feb 2023 17:08:44 +0100 -Subject: fs/iso9660: Prevent read past the end of system use area - -In the code, the for loop advanced the entry pointer to the next entry before -checking if the next entry is within the system use area boundary. Another -issue in the code was that there is no check for the size of system use area. -For a corrupted system, the size of system use area can be less than the size -of minimum SUSP entry size (4 bytes). These can cause buffer overrun. The fixes -added the checks to ensure the read is valid and within the boundary. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=8f41d35fcecb65746b60aaa99936cbbdf5fb27ba -Conflict:NA - -Signed-off-by: Lidong Chen -Reviewed-by: Thomas Schmitt -Reviewed-by: Daniel Kiper ---- - grub-core/fs/iso9660.c | 30 +++++++++++++++++++++++++++--- - 1 file changed, 27 insertions(+), 3 deletions(-) - -diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c -index 24d84a5..230048a 100644 ---- a/grub-core/fs/iso9660.c -+++ b/grub-core/fs/iso9660.c -@@ -49,6 +49,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); - #define GRUB_ISO9660_VOLDESC_PART 3 - #define GRUB_ISO9660_VOLDESC_END 255 - -+#define GRUB_ISO9660_SUSP_HEADER_SZ 4 -+ - /* The head of a volume descriptor. */ - struct grub_iso9660_voldesc - { -@@ -272,6 +274,9 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - if (sua_size <= 0) - return GRUB_ERR_NONE; - -+ if (sua_size < GRUB_ISO9660_SUSP_HEADER_SZ) -+ return grub_error (GRUB_ERR_BAD_FS, "invalid susp entry size"); -+ - sua = grub_malloc (sua_size); - if (!sua) - return grub_errno; -@@ -284,10 +289,14 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - return err; - } - -- for (entry = (struct grub_iso9660_susp_entry *) sua; (char *) entry < (char *) sua + sua_size - 1 && entry->len > 0; -- entry = (struct grub_iso9660_susp_entry *) -- ((char *) entry + entry->len)) -+ entry = (struct grub_iso9660_susp_entry *) sua; -+ -+ while (entry->len > 0) - { -+ /* Ensure the entry is within System Use Area. */ -+ if ((char *) entry + entry->len > (sua + sua_size)) -+ break; -+ - /* The last entry. */ - if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0) - break; -@@ -303,6 +312,16 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - off = grub_le_to_cpu32 (ce->off); - ce_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ; - -+ if (sua_size <= 0) -+ break; -+ -+ if (sua_size < GRUB_ISO9660_SUSP_HEADER_SZ) -+ { -+ grub_free (sua); -+ return grub_error (GRUB_ERR_BAD_FS, -+ "invalid continuation area in CE entry"); -+ } -+ - grub_free (sua); - sua = grub_malloc (sua_size); - if (!sua) -@@ -325,6 +344,11 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - grub_free (sua); - return 0; - } -+ -+ entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len); -+ -+ if (((sua + sua_size) - (char *) entry) < GRUB_ISO9660_SUSP_HEADER_SZ) -+ break; - } - - grub_free (sua); --- -cgit v1.1 - diff --git a/backport-fs-iso9660-Prevent-skipping-CE-or-ST-at-start-of-continuation-area.patch b/backport-fs-iso9660-Prevent-skipping-CE-or-ST-at-start-of-continuation-area.patch deleted file mode 100644 index 25f31c3..0000000 --- a/backport-fs-iso9660-Prevent-skipping-CE-or-ST-at-start-of-continuation-area.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 2a96eab759aff74c2a214da66eefeb1e770c0820 Mon Sep 17 00:00:00 2001 -From: Thomas Schmitt -Date: Wed, 1 Feb 2023 17:28:49 +0100 -Subject: fs/iso9660: Prevent skipping CE or ST at start of continuation area - -If processing of a SUSP CE entry leads to a continuation area which -begins by entry CE or ST, then these entries were skipped without -interpretation. In case of CE this would lead to premature end of -processing the SUSP entries of the file. In case of ST this could -cause following non-SUSP bytes to be interpreted as SUSP entries. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=2a96eab759aff74c2a214da66eefeb1e770c0820 -Conflict:NA - -Signed-off-by: Thomas Schmitt -Tested-by: Lidong Chen -Reviewed-by: Thomas Schmitt -Reviewed-by: Daniel Kiper ---- - grub-core/fs/iso9660.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c -index 64ea3d4..acccf5f 100644 ---- a/grub-core/fs/iso9660.c -+++ b/grub-core/fs/iso9660.c -@@ -50,6 +50,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - #define GRUB_ISO9660_VOLDESC_END 255 - - #define GRUB_ISO9660_SUSP_HEADER_SZ 4 -+#define GRUB_ISO9660_MAX_CE_HOPS 100000 - - /* The head of a volume descriptor. */ - struct grub_iso9660_voldesc -@@ -270,6 +271,7 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - char *sua; - struct grub_iso9660_susp_entry *entry; - grub_err_t err; -+ int ce_counter = 0; - - if (sua_size <= 0) - return GRUB_ERR_NONE; -@@ -307,6 +309,13 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - struct grub_iso9660_susp_ce *ce; - grub_disk_addr_t ce_block; - -+ if (++ce_counter > GRUB_ISO9660_MAX_CE_HOPS) -+ { -+ grub_free (sua); -+ return grub_error (GRUB_ERR_BAD_FS, -+ "suspecting endless CE loop"); -+ } -+ - ce = (struct grub_iso9660_susp_ce *) entry; - sua_size = grub_le_to_cpu32 (ce->len); - off = grub_le_to_cpu32 (ce->off); -@@ -337,6 +346,13 @@ grub_iso9660_susp_iterate (grub_fshelp_node_t node, grub_off_t off, - } - - entry = (struct grub_iso9660_susp_entry *) sua; -+ /* -+ * The hook function will not process CE or ST. -+ * Advancing to the next entry would skip them. -+ */ -+ if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0 -+ || grub_strncmp ((char *) entry->sig, "ST", 2) == 0) -+ continue; - } - - if (hook (entry, hook_arg)) --- -cgit v1.1 - diff --git a/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-a-volume-label.patch b/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-a-volume-label.patch deleted file mode 100644 index 55b1ef4..0000000 --- a/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-a-volume-label.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 4e1d08ad2465dcc2c79d3be9c92ec166d8420a98 Mon Sep 17 00:00:00 2001 -From: Maxim Suhanov -Date: Mon, 28 Aug 2023 16:38:19 +0300 -Subject: [PATCH 5/6] fs/ntfs: Fix an OOB read when parsing a volume label - -This fix introduces checks to ensure that an NTFS volume label is always -read from the corresponding file record segment. - -The current NTFS code allows the volume label string to be read from an -arbitrary, attacker-chosen memory location. However, the bytes read are -always treated as UTF-16LE. So, the final string displayed is mostly -unreadable and it can't be easily converted back to raw bytes. - -The lack of this check is a minor issue, likely not causing a significant -data leak. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=1fe82c41e070385e273d7bb1cfb482627a3c28e8 -Conflict:NA - -Reported-by: Maxim Suhanov -Signed-off-by: Maxim Suhanov -Reviewed-by: Daniel Kiper ---- - grub-core/fs/ntfs.c | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index 2404566..e26dd59 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -1209,13 +1209,29 @@ grub_ntfs_label (grub_device_t device, char **label) - - init_attr (&mft->attr, mft); - pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME); -+ -+ if (pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); -+ goto fail; -+ } -+ -+ if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa < 0x16) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); -+ goto fail; -+ } -+ - if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10))) - { - int len; - - len = u32at (pa, 0x10) / 2; - pa += u16at (pa, 0x14); -- *label = get_utf8 (pa, len); -+ if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len) -+ *label = get_utf8 (pa, len); -+ else -+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label"); - } - - fail: --- -2.19.1 - diff --git a/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-bitmaps-for-ind.patch b/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-bitmaps-for-ind.patch deleted file mode 100644 index 6d6fd87..0000000 --- a/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-bitmaps-for-ind.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 6dc553d0c6ef77518789eb774f76d07f7a2e38c2 Mon Sep 17 00:00:00 2001 -From: Maxim Suhanov -Date: Mon, 28 Aug 2023 16:33:44 +0300 -Subject: [PATCH 4/6] fs/ntfs: Fix an OOB read when parsing bitmaps for index - attributes - -This fix introduces checks to ensure that bitmaps for directory indices -are never read beyond their actual sizes. - -The lack of this check is a minor issue, likely not exploitable in any way. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=7a5a116739fa6d8a625da7d6b9272c9a2462f967 -Conflict:NA - -Reported-by: Maxim Suhanov -Signed-off-by: Maxim Suhanov -Reviewed-by: Daniel Kiper ---- - grub-core/fs/ntfs.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index c015044..2404566 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -839,6 +839,25 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - - if (is_resident) - { -+ if (bitmap_len > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap too large"); -+ goto done; -+ } -+ -+ if (cur_pos >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range"); -+ goto done; -+ } -+ -+ if (u16at (cur_pos, 0x14) + u32at (cur_pos, 0x10) > -+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range"); -+ goto done; -+ } -+ - grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14), - bitmap_len); - } --- -2.19.1 - diff --git a/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-directory-entri.patch b/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-directory-entri.patch deleted file mode 100644 index 9430315..0000000 --- a/backport-fs-ntfs-Fix-an-OOB-read-when-parsing-directory-entri.patch +++ /dev/null @@ -1,76 +0,0 @@ -From d5b4e4198fa932e13f3abfec8d4cda1c7709499d Mon Sep 17 00:00:00 2001 -From: Maxim Suhanov -Date: Mon, 28 Aug 2023 16:33:17 +0300 -Subject: [PATCH 3/6] fs/ntfs: Fix an OOB read when parsing directory entries - from resident and non-resident index attributes - -This fix introduces checks to ensure that index entries are never read -beyond the corresponding directory index. - -The lack of this check is a minor issue, likely not exploitable in any way. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=7e5f031a6a6a3decc2360a7b0c71abbe598e7354 -Conflict:NA - -Reported-by: Maxim Suhanov -Signed-off-by: Maxim Suhanov -Reviewed-by: Daniel Kiper ---- - grub-core/fs/ntfs.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index 4d1fe42..c015044 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -599,7 +599,7 @@ get_utf8 (grub_uint8_t *in, grub_size_t len) - } - - static int --list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, -+list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t *end_pos, - grub_fshelp_iterate_dir_hook_t hook, void *hook_data) - { - grub_uint8_t *np; -@@ -610,6 +610,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, - grub_uint8_t namespace; - char *ustr; - -+ if ((pos >= end_pos) || (end_pos - pos < 0x52)) -+ break; -+ - if (pos[0xC] & 2) /* end signature */ - break; - -@@ -617,6 +620,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, - ns = *(np++); - namespace = *(np++); - -+ if (2 * ns > end_pos - pos - 0x52) -+ break; -+ - /* - * Ignore files in DOS namespace, as they will reappear as Win32 - * names. -@@ -802,7 +808,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - } - - cur_pos += 0x10; /* Skip index root */ -- ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, hook_data); -+ ret = list_file (mft, cur_pos + u16at (cur_pos, 0), -+ at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR), -+ hook, hook_data); - if (ret) - goto done; - -@@ -889,6 +897,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - (const grub_uint8_t *) "INDX"))) - goto done; - ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)], -+ indx + (mft->data->idx_size << GRUB_NTFS_BLK_SHR), - hook, hook_data); - if (ret) - goto done; --- -2.19.1 - diff --git a/backport-fs-ntfs-Make-code-more-readable.patch b/backport-fs-ntfs-Make-code-more-readable.patch deleted file mode 100644 index c5a445f..0000000 --- a/backport-fs-ntfs-Make-code-more-readable.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 85c172921afc3fb9a3533a60df48cfff640a237d Mon Sep 17 00:00:00 2001 -From: Maxim Suhanov -Date: Mon, 28 Aug 2023 16:40:07 +0300 -Subject: [PATCH 6/6] fs/ntfs: Make code more readable - -Move some calls used to access NTFS attribute header fields into -functions with human-readable names. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=e58b870ff926415e23fc386af41ff81b2f588763 -Conflict:NA - -Suggested-by: Daniel Kiper -Signed-off-by: Maxim Suhanov -Reviewed-by: Daniel Kiper ---- - grub-core/fs/ntfs.c | 48 +++++++++++++++++++++++++++++++-------------- - 1 file changed, 33 insertions(+), 15 deletions(-) - -diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c -index e26dd59..deb058a 100644 ---- a/grub-core/fs/ntfs.c -+++ b/grub-core/fs/ntfs.c -@@ -52,6 +52,24 @@ u64at (void *ptr, grub_size_t ofs) - return grub_le_to_cpu64 (grub_get_unaligned64 ((char *) ptr + ofs)); - } - -+static grub_uint16_t -+first_attr_off (void *mft_buf_ptr) -+{ -+ return u16at (mft_buf_ptr, 0x14); -+} -+ -+static grub_uint16_t -+res_attr_data_off (void *res_attr_ptr) -+{ -+ return u16at (res_attr_ptr, 0x14); -+} -+ -+static grub_uint32_t -+res_attr_data_len (void *res_attr_ptr) -+{ -+ return u32at (res_attr_ptr, 0x10); -+} -+ - grub_ntfscomp_func_t grub_ntfscomp_func; - - static grub_err_t -@@ -106,7 +124,7 @@ init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft) - { - at->mft = mft; - at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0; -- at->attr_nxt = mft->buf + u16at (mft->buf, 0x14); -+ at->attr_nxt = mft->buf + first_attr_off (mft->buf); - at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL; - } - -@@ -154,7 +172,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - return NULL; - } - -- new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)]; -+ new_pos = &at->emft_buf[first_attr_off (at->emft_buf)]; - while (*new_pos != 0xFF) - { - if ((*new_pos == *at->attr_cur) -@@ -213,7 +231,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) - } - else - { -- at->attr_nxt = at->attr_end + u16at (pa, 0x14); -+ at->attr_nxt = at->attr_end + res_attr_data_off (pa); - at->attr_end = at->attr_end + u32at (pa, 4); - pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); - } -@@ -399,20 +417,20 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest, - - if (pa[8] == 0) - { -- if (ofs + len > u32at (pa, 0x10)) -+ if (ofs + len > res_attr_data_len (pa)) - return grub_error (GRUB_ERR_BAD_FS, "read out of range"); - -- if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) -+ if (res_attr_data_len (pa) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) - return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large"); - - if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR)) - return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range"); - -- if (u16at (pa, 0x14) + u32at (pa, 0x10) > -+ if (res_attr_data_off (pa) + res_attr_data_len (pa) > - (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa) - return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range"); - -- grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len); -+ grub_memcpy (dest, pa + res_attr_data_off (pa) + ofs, len); - return 0; - } - -@@ -556,7 +574,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno) - (unsigned long long) mftno); - - if (!pa[8]) -- mft->size = u32at (pa, 0x10); -+ mft->size = res_attr_data_len (pa); - else - mft->size = u64at (pa, 0x30); - -@@ -801,7 +819,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - (u32at (cur_pos, 0x18) != 0x490024) || - (u32at (cur_pos, 0x1C) != 0x300033)) - continue; -- cur_pos += u16at (cur_pos, 0x14); -+ cur_pos += res_attr_data_off (cur_pos); - if (*cur_pos != 0x30) /* Not filename index */ - continue; - break; -@@ -830,7 +848,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - { - int is_resident = (cur_pos[8] == 0); - -- bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) : -+ bitmap_len = ((is_resident) ? res_attr_data_len (cur_pos) : - u32at (cur_pos, 0x28)); - - bmp = grub_malloc (bitmap_len); -@@ -851,14 +869,14 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, - goto done; - } - -- if (u16at (cur_pos, 0x14) + u32at (cur_pos, 0x10) > -+ if (res_attr_data_off (cur_pos) + res_attr_data_len (cur_pos) > - (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos) - { - grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range"); - goto done; - } - -- grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14), -+ grub_memcpy (bmp, cur_pos + res_attr_data_off (cur_pos), - bitmap_len); - } - else -@@ -1222,12 +1240,12 @@ grub_ntfs_label (grub_device_t device, char **label) - goto fail; - } - -- if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10))) -+ if ((pa) && (pa[8] == 0) && (res_attr_data_len (pa))) - { - int len; - -- len = u32at (pa, 0x10) / 2; -- pa += u16at (pa, 0x14); -+ len = res_attr_data_len (pa) / 2; -+ pa += res_attr_data_off (pa); - if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len) - *label = get_utf8 (pa, len); - else --- -2.19.1 - diff --git a/backport-fs-squash4-Fix-memory-leaks-in-grub_squash_iterate_d.patch b/backport-fs-squash4-Fix-memory-leaks-in-grub_squash_iterate_d.patch deleted file mode 100644 index 532b850..0000000 --- a/backport-fs-squash4-Fix-memory-leaks-in-grub_squash_iterate_d.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 98ae234000abdabf9db125c87a2db8b81157af72 Mon Sep 17 00:00:00 2001 -From: "t.feng" -Date: Tue, 29 Nov 2022 17:14:14 +0800 -Subject: [PATCH] fs/squash4: Fix memory leaks in grub_squash_iterate_dir() - -Fixes: 20dd511c8 (Handle "." and ".." on squashfs) - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=98ae234000abdabf9db125c87a2db8b81157af72 -Conflict:NA - -Signed-off-by: t.feng -Reviewed-by: Daniel Kiper ---- - grub-core/fs/squash4.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - -diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c -index 02b1f9b6d..a30e6ebe1 100644 ---- a/grub-core/fs/squash4.c -+++ b/grub-core/fs/squash4.c -@@ -550,7 +550,10 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, - + node->stack[node->stsize - 1].ino_chunk, - node->stack[node->stsize - 1].ino_offset); - if (err) -- return 0; -+ { -+ grub_free (node); -+ return 0; -+ } - - if (hook ("..", GRUB_FSHELP_DIR, node, hook_data)) - return 1; -@@ -600,7 +603,10 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, - grub_le_to_cpu64 (dir->data->sb.diroffset) - + chunk, off); - if (err) -- return 0; -+ { -+ grub_free (buf); -+ return 0; -+ } - - off += grub_le_to_cpu16 (di.namelen) + 1; - buf[grub_le_to_cpu16 (di.namelen) + 1] = 0; -@@ -612,11 +618,17 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir, - if (grub_add (dir->stsize, 1, &sz) || - grub_mul (sz, sizeof (dir->stack[0]), &sz) || - grub_add (sz, sizeof (*node), &sz)) -- return 0; -+ { -+ grub_free (buf); -+ return 0; -+ } - - node = grub_malloc (sz); - if (! node) -- return 0; -+ { -+ grub_free (buf); -+ return 0; -+ } - - grub_memcpy (node, dir, sz - sizeof(dir->stack[0])); - --- -2.28.0.windows.1 - diff --git a/backport-fs-udf-Fix-out-of-bounds-access.patch b/backport-fs-udf-Fix-out-of-bounds-access.patch deleted file mode 100644 index c0cc8a8..0000000 --- a/backport-fs-udf-Fix-out-of-bounds-access.patch +++ /dev/null @@ -1,119 +0,0 @@ -From a24ea9241cb42e8ba670ac8d8ce54275df73a271 Mon Sep 17 00:00:00 2001 -From: Lidong Chen -Date: Wed, 7 Jun 2023 01:31:06 +0000 -Subject: fs/udf: Fix out of bounds access - -Implemented a boundary check before advancing the allocation -descriptors pointer. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=a24ea9241cb42e8ba670ac8d8ce54275df73a271 -Conflict:NA - -Signed-off-by: Lidong Chen -Reviewed-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - grub-core/fs/udf.c | 38 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 38 insertions(+) - -diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c -index 7679ea3..b836e61 100644 ---- a/grub-core/fs/udf.c -+++ b/grub-core/fs/udf.c -@@ -114,6 +114,10 @@ GRUB_MOD_LICENSE ("GPLv3+"); - #define GRUB_UDF_PARTMAP_TYPE_1 1 - #define GRUB_UDF_PARTMAP_TYPE_2 2 - -+#define GRUB_UDF_INVALID_STRUCT_PTR(_ptr, _struct) \ -+ ((char *) (_ptr) >= end_ptr || \ -+ ((grub_ssize_t) (end_ptr - (char *) (_ptr)) < (grub_ssize_t) sizeof (_struct))) -+ - struct grub_udf_lb_addr - { - grub_uint32_t block_num; -@@ -458,6 +462,7 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) - char *ptr; - grub_ssize_t len; - grub_disk_addr_t filebytes; -+ char *end_ptr; - - switch (U16 (node->block.fe.tag.tag_ident)) - { -@@ -476,9 +481,17 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) - return 0; - } - -+ end_ptr = (char *) node + get_fshelp_size (node->data); -+ - if ((U16 (node->block.fe.icbtag.flags) & GRUB_UDF_ICBTAG_FLAG_AD_MASK) - == GRUB_UDF_ICBTAG_FLAG_AD_SHORT) - { -+ if (GRUB_UDF_INVALID_STRUCT_PTR (ptr, struct grub_udf_short_ad)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); -+ return 0; -+ } -+ - struct grub_udf_short_ad *ad = (struct grub_udf_short_ad *) ptr; - - filebytes = fileblock * U32 (node->data->lvd.bsize); -@@ -542,10 +555,22 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) - filebytes -= adlen; - ad++; - len -= sizeof (struct grub_udf_short_ad); -+ -+ if (GRUB_UDF_INVALID_STRUCT_PTR (ad, struct grub_udf_short_ad)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); -+ return 0; -+ } - } - } - else - { -+ if (GRUB_UDF_INVALID_STRUCT_PTR (ptr, struct grub_udf_long_ad)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); -+ return 0; -+ } -+ - struct grub_udf_long_ad *ad = (struct grub_udf_long_ad *) ptr; - - filebytes = fileblock * U32 (node->data->lvd.bsize); -@@ -611,6 +636,12 @@ grub_udf_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) - filebytes -= adlen; - ad++; - len -= sizeof (struct grub_udf_long_ad); -+ -+ if (GRUB_UDF_INVALID_STRUCT_PTR (ad, struct grub_udf_long_ad)) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); -+ return 0; -+ } - } - } - -@@ -630,6 +661,7 @@ grub_udf_read_file (grub_fshelp_node_t node, - case GRUB_UDF_ICBTAG_FLAG_AD_IN_ICB: - { - char *ptr; -+ char *end_ptr = (char *) node + get_fshelp_size (node->data); - - ptr = ((U16 (node->block.fe.tag.tag_ident) == GRUB_UDF_TAG_IDENT_FE) ? - ((char *) &node->block.fe.ext_attr[0] -@@ -637,6 +669,12 @@ grub_udf_read_file (grub_fshelp_node_t node, - ((char *) &node->block.efe.ext_attr[0] - + U32 (node->block.efe.ext_attr_length))); - -+ if ((ptr + pos + len) > end_ptr) -+ { -+ grub_error (GRUB_ERR_BAD_FS, "corrupted UDF file system"); -+ return 0; -+ } -+ - grub_memcpy (buf, ptr + pos, len); - - return len; --- -cgit v1.1 - diff --git a/backport-fs-xfs-Fix-memory-leaks-in-XFS-module.patch b/backport-fs-xfs-Fix-memory-leaks-in-XFS-module.patch deleted file mode 100644 index d5c229d..0000000 --- a/backport-fs-xfs-Fix-memory-leaks-in-XFS-module.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 2e32d2357443d596d8d9067116152ec49be02a4a Mon Sep 17 00:00:00 2001 -From: "t.feng" -Date: Tue, 29 Nov 2022 17:14:15 +0800 -Subject: [PATCH] fs/xfs: Fix memory leaks in XFS module - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=2e32d2357443d596d8d9067116152ec49be02a4a -Conflict:NA - -Signed-off-by: t.feng -Reviewed-by: Daniel Kiper ---- - grub-core/fs/xfs.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c -index d6de7f1a2..b67407690 100644 ---- a/grub-core/fs/xfs.c -+++ b/grub-core/fs/xfs.c -@@ -585,7 +585,10 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) - if (grub_disk_read (node->data->disk, - GRUB_XFS_FSB_TO_BLOCK (node->data, get_fsb (keys, i - 1 + recoffset)) << (node->data->sblock.log2_bsize - GRUB_DISK_SECTOR_BITS), - 0, node->data->bsize, leaf)) -- return 0; -+ { -+ grub_free (leaf); -+ return 0; -+ } - - if ((!node->data->hascrc && - grub_strncmp ((char *) leaf->magic, "BMAP", 4)) || -@@ -751,6 +754,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename, - if (err) - { - grub_print_error (); -+ grub_free (fdiro); - return 0; - } - -@@ -861,7 +865,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, - blk << dirblk_log2, - dirblk_size, dirblock, 0); - if (numread != dirblk_size) -- return 0; -+ { -+ grub_free (dirblock); -+ return 0; -+ } - - entries = (grub_be_to_cpu32 (tail->leaf_count) - - grub_be_to_cpu32 (tail->leaf_stale)); --- -2.28.0.windows.1 - diff --git a/backport-gentpl_py-Remove-interp-section-from-img-files.patch b/backport-gentpl_py-Remove-interp-section-from-img-files.patch deleted file mode 100644 index b60492e..0000000 --- a/backport-gentpl_py-Remove-interp-section-from-img-files.patch +++ /dev/null @@ -1,35 +0,0 @@ -From b58aa4e2095943303126fff706d73f18f7caab35 Mon Sep 17 00:00:00 2001 -From: Nicholas Vinson -Date: Fri, 13 Jan 2023 02:56:35 -0500 -Subject: gentpl.py: Remove .interp section from .img files - -When building .img files, a .interp section from the .image files will -sometimes be copied into the .img file. This additional section pushes -the .img file beyond the 512-byte limit and causes grub-install to fail -to run for i386-pc platforms. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=b58aa4e2095943303126fff706d73f18f7caab35 -Conflict:NA - -Signed-off-by: Nicholas Vinson -Reviewed-by: Daniel Kiper ---- - gentpl.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gentpl.py b/gentpl.py -index 9f51e4f..88abe5b 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -766,7 +766,7 @@ def image(defn, platform): - if test x$(TARGET_APPLE_LINKER) = x1; then \ - $(MACHO2IMG) $< $@; \ - else \ -- $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .note.gnu.property -R .ARM.exidx $< $@; \ -+ $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .note.gnu.property -R .ARM.exidx -R .interp $< $@; \ - fi - """) - --- -cgit v1.1 - diff --git a/backport-grub-core-loader-arm64-linux.c-do-not-validate-kerne.patch b/backport-grub-core-loader-arm64-linux.c-do-not-validate-kerne.patch deleted file mode 100644 index de4f190..0000000 --- a/backport-grub-core-loader-arm64-linux.c-do-not-validate-kerne.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitri John Ledkov -Date: Fri, 4 Mar 2022 11:29:31 +0100 -Subject: [PATCH] grub-core/loader/arm64/linux.c: do not validate kernel twice - -Call to grub_file_open(, GRUB_FILE_TYPE_LINUX_KERNEL) already passes -the kernel file through shim-lock verifier when secureboot is on. Thus -there is no need to validate the kernel image again. And when doing so -again, duplicate PCR measurement is performed, breaking measurements -compatibility with 2.04+linuxefi. - -This patch must not be ported to older editions of grub code bases -that do not have verifiers framework, or it is not builtin, or -shim-lock-verifier is an optional module. - -Signed-off-by: Dimitri John Ledkov ---- - grub-core/loader/arm64/linux.c | 13 ------------- - 1 file changed, 13 deletions(-) - -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index f18d90bd749..d2af47c2c0a 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -34,7 +34,6 @@ - #include - #include - #include --#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -341,7 +340,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_off_t filelen; - grub_uint32_t align; - void *kernel = NULL; -- int rc; - - grub_dl_ref (my_mod); - -@@ -370,17 +368,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -- { -- rc = grub_linuxefi_secure_validate (kernel, filelen); -- if (rc <= 0) -- { -- grub_error (GRUB_ERR_INVALID_COMMAND, -- N_("%s has invalid signature"), argv[0]); -- goto fail; -- } -- } -- - if (grub_arch_efi_linux_check_image (kernel) != GRUB_ERR_NONE) - goto fail; - if (parse_pe_header (kernel, &kernel_size, &handover_offset, &align) != GRUB_ERR_NONE) diff --git a/backport-grub-core-loader-efi-chainloader.c-do-not-validate-c.patch b/backport-grub-core-loader-efi-chainloader.c-do-not-validate-c.patch deleted file mode 100644 index 498a6d7..0000000 --- a/backport-grub-core-loader-efi-chainloader.c-do-not-validate-c.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitri John Ledkov -Date: Fri, 4 Mar 2022 09:31:43 +0100 -Subject: [PATCH] grub-core/loader/efi/chainloader.c: do not validate - chainloader twice - -On secureboot systems, with shimlock verifier, call to -grub_file_open(, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE) will already -pass the chainloader target through shim-lock protocol verify -call. And create a TPM measurement. If verification fails, -grub_cmd_chainloader will fail at file open time. - -This makes previous code paths for negative, and zero return codes -from grub_linuxefi_secure_validate unreachable under secureboot. But -also breaking measurements compatibility with 2.04+linuxefi codebases, -as the chainloader file is passed through shim_lock->verify() twice -(via verifier & direct call to grub_linuxefi_secure_validate) -extending the PCRs twice. - -This reduces grub_loader options to perform -grub_secureboot_chainloader when secureboot is on, and otherwise -attempt grub_chainloader_boot. - -It means that booting with secureboot off, yet still with shim (which -always verifies things successfully), will stop choosing -grub_secureboot_chainloader, and opting for a more regular -loadimage/startimage codepath. If we want to use the -grub_secureboot_chainloader codepath in such scenarios we should adapt -the code to simply check for shim_lock protocol presence / -shim_lock->context() success?! But I am not sure if that is necessary. - -This patch must not be ported to older editions of grub code bases -that do not have verifiers framework, or it is not builtin, or -shim-lock-verifier is an optional module. - -Signed-off-by: Dimitri John Ledkov ---- - grub-core/loader/efi/chainloader.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 3af6b122926..644cd2e56fe 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -906,7 +906,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_efi_device_path_t *dp = 0; - char *filename; - void *boot_image = 0; -- int rc; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -@@ -1082,9 +1081,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - orig_dev = 0; - } - -- rc = grub_linuxefi_secure_validate((void *)(unsigned long)address, fsize); -- grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc); -- if (rc > 0) -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { - grub_file_close (file); - grub_device_close (dev); -@@ -1092,7 +1089,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_secureboot_chainloader_unload, 0); - return 0; - } -- else if (rc == 0) -+ else - { - grub_load_and_start_image(boot_image); - grub_file_close (file); -@@ -1101,7 +1098,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - - return 0; - } -- // -1 fall-through to fail - - fail: - if (orig_dev) diff --git a/backport-grub-core-loader-efi-linux.c-drop-now-unused-grub_li.patch b/backport-grub-core-loader-efi-linux.c-drop-now-unused-grub_li.patch deleted file mode 100644 index d23f465..0000000 --- a/backport-grub-core-loader-efi-linux.c-drop-now-unused-grub_li.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitri John Ledkov -Date: Fri, 4 Mar 2022 11:36:09 +0100 -Subject: [PATCH] grub-core/loader/efi/linux.c: drop now unused - grub_linuxefi_secure_validate - -Drop the now unused grub_linuxefi_secure_validate() as all prior users -of this API now rely on the shim-lock-verifier codepath instead. - -This patch must not be ported to older editions of grub code bases -that do not have verifiers framework, or it is not builtin, or -shim-lock-verifier is an optional module. - -Signed-off-by: Dimitri John Ledkov ---- - grub-core/loader/efi/linux.c | 40 ---------------------------------------- - include/grub/efi/linux.h | 2 -- - 2 files changed, 42 deletions(-) - -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index 9260731c107..9265cf4200a 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -24,46 +24,6 @@ - #include - #include - --#define SHIM_LOCK_GUID \ -- { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} } -- --struct grub_efi_shim_lock --{ -- grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size); --}; --typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; -- --// Returns 1 on success, -1 on error, 0 when not available --int --grub_linuxefi_secure_validate (void *data, grub_uint32_t size) --{ -- grub_efi_guid_t guid = SHIM_LOCK_GUID; -- grub_efi_shim_lock_t *shim_lock; -- grub_efi_status_t status; -- -- shim_lock = grub_efi_locate_protocol(&guid, NULL); -- grub_dprintf ("secureboot", "shim_lock: %p\n", shim_lock); -- if (!shim_lock) -- { -- grub_dprintf ("secureboot", "shim not available\n"); -- return 0; -- } -- -- grub_dprintf ("secureboot", "Asking shim to verify kernel signature\n"); -- status = shim_lock->verify (data, size); -- grub_dprintf ("secureboot", "shim_lock->verify(): %ld\n", (long int)status); -- if (status == GRUB_EFI_SUCCESS) -- { -- grub_dprintf ("secureboot", "Kernel signature verification passed\n"); -- return 1; -- } -- -- grub_dprintf ("secureboot", "Kernel signature verification failed (0x%lx)\n", -- (unsigned long) status); -- -- return -1; --} -- - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wcast-align" - -diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h -index 0033d9305a9..887b02fd9f3 100644 ---- a/include/grub/efi/linux.h -+++ b/include/grub/efi/linux.h -@@ -22,8 +22,6 @@ - #include - #include - --int --EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size); - grub_err_t - EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset, - void *kernel_param); diff --git a/backport-grub-core-loader-i386-efi-linux.c-do-not-validate-ke.patch b/backport-grub-core-loader-i386-efi-linux.c-do-not-validate-ke.patch deleted file mode 100644 index a0be664..0000000 --- a/backport-grub-core-loader-i386-efi-linux.c-do-not-validate-ke.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitri John Ledkov -Date: Thu, 3 Mar 2022 13:10:56 +0100 -Subject: [PATCH] grub-core/loader/i386/efi/linux.c: do not validate kernels - twice - -On codebases that have shim-lock-verifier built into the grub core -(like 2.06 upstream), shim-lock-verifier is in enforcing mode when -booted with secureboot. It means that grub_cmd_linux() command -attempts to perform shim validate upon opening linux kernel image, -including kernel measurement. And the verifier correctly returns file -open error when shim validate protocol is not present or shim fails to -validate the kernel. - -This makes the call to grub_linuxefi_secure_validate() redundant, but -also harmful. As validating the kernel image twice, extends the PCRs -with the same measurement twice. Which breaks existing sealing -policies when upgrading from grub2.04+rhboot+sb+linuxefi to -grub2.06+rhboot+sb+linuxefi builds. It is also incorrect to measure -the kernel twice. - -This patch must not be ported to older editions of grub code bases -that do not have verifiers framework, or it is not builtin, or -shim-lock-verifier is an optional module. - -This patch is tested to ensure that unsigned kernels are not possible -to boot in secureboot mode when shim rejects kernel, or shim protocol -is missing, and that the measurements become stable once again. The -above also ensures that CVE-2020-15705 is not reintroduced. - -Signed-off-by: Dimitri John Ledkov ---- - grub-core/loader/i386/efi/linux.c | 13 ------------- - 1 file changed, 13 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 3cf0f9b330b..941df6400b9 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -30,7 +30,6 @@ - #include - #include - #include --#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -278,7 +277,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_ssize_t start, filelen; - void *kernel = NULL; - int setup_header_end_offset; -- int rc; - - grub_dl_ref (my_mod); - -@@ -308,17 +306,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -- { -- rc = grub_linuxefi_secure_validate (kernel, filelen); -- if (rc <= 0) -- { -- grub_error (GRUB_ERR_INVALID_COMMAND, -- N_("%s has invalid signature"), argv[0]); -- goto fail; -- } -- } -- - lh = (struct linux_i386_kernel_header *)kernel; - grub_dprintf ("linux", "original lh is at %p\n", kernel); - diff --git a/backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch b/backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch deleted file mode 100644 index 4060a18..0000000 --- a/backport-io-gzio-Fix-possible-use-of-uninitialized-variable-in-huft_build.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 29d44a236a5e939b8ff24e6c31141d5b1e48f693 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 26 Oct 2021 15:02:40 +0000 -Subject: io/gzio: Fix possible use of uninitialized variable in huft_build() - -In huft_build() it is possible to reach the for loop where "r" is being -assigned to "q[j]" without "r.v" ever being initialized. - -Fixes: CID 314024 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=29d44a236a5e939b8ff24e6c31141d5b1e48f693 - ---- - grub-core/io/gzio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c -index aea86a0..10156e5 100644 ---- a/grub-core/io/gzio.c -+++ b/grub-core/io/gzio.c -@@ -447,7 +447,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */ - int l; /* bits per table (returned in m) */ - register unsigned *p; /* pointer into c[], b[], or v[] */ - register struct huft *q; /* points to current table */ -- struct huft r; /* table entry for structure assignment */ -+ struct huft r = {0}; /* table entry for structure assignment */ - struct huft *u[BMAX]; /* table stack */ - unsigned v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ --- -cgit v1.1 diff --git a/backport-kern-Check-for-NULL-when-closing-devices-and-disks.patch b/backport-kern-Check-for-NULL-when-closing-devices-and-disks.patch deleted file mode 100644 index 7e06a1f..0000000 --- a/backport-kern-Check-for-NULL-when-closing-devices-and-disks.patch +++ /dev/null @@ -1,50 +0,0 @@ -From d09387287b7bbd7770bc9d172cc0e06181183e02 Mon Sep 17 00:00:00 2001 -From: Oliver Steffen -Date: Fri, 26 May 2023 13:35:50 +0200 -Subject: kern: Check for NULL when closing devices and disks - -Add checks for NULL pointers to grub_device_close() and -grub_disk_close() to make these functions more robust. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=d09387287b7bbd7770bc9d172cc0e06181183e02 -Conflict:NA - -Signed-off-by: Oliver Steffen -Reviewed-by: Daniel Kiper ---- - grub-core/kern/device.c | 3 +++ - grub-core/kern/disk.c | 4 ++++ - 2 files changed, 7 insertions(+) - -diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c -index f58b58c..2a6d81f 100644 ---- a/grub-core/kern/device.c -+++ b/grub-core/kern/device.c -@@ -72,6 +72,9 @@ grub_device_open (const char *name) - grub_err_t - grub_device_close (grub_device_t device) - { -+ if (device == NULL) -+ return GRUB_ERR_NONE; -+ - if (device->disk) - grub_disk_close (device->disk); - -diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c -index 05a28ab..3ca8528 100644 ---- a/grub-core/kern/disk.c -+++ b/grub-core/kern/disk.c -@@ -294,6 +294,10 @@ void - grub_disk_close (grub_disk_t disk) - { - grub_partition_t part; -+ -+ if (disk == NULL) -+ return; -+ - grub_dprintf ("disk", "Closing `%s'...\n", disk->name); - - if (disk->dev && disk->dev->disk_close) --- -2.19.1 - diff --git a/backport-kern-acpi-Use-xsdt_addr-if-present.patch b/backport-kern-acpi-Use-xsdt_addr-if-present.patch deleted file mode 100644 index fb236e6..0000000 --- a/backport-kern-acpi-Use-xsdt_addr-if-present.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 4fb58cf0afe83d921e1072d58a4f899696d8fe7e Mon Sep 17 00:00:00 2001 -From: Qiumiao Zhang -Date: Tue, 13 Jun 2023 11:20:51 +0800 -Subject: [PATCH] kern/acpi: Use xsdt_addr if present - -According to the ACPI specification, in ACPI 2.0 or later, an -ACPI-compatible OS must use the XSDT if present. So, we should -use xsdt_addr instead of rsdt_addr if xsdt_addr is valid. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=4fb58cf0afe83d921e1072d58a4f899696d8fe7e -Conflict:NA - -Signed-off-by: Qiumiao Zhang -Reviewed-by: Daniel Kiper ---- - grub-core/kern/acpi.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/grub-core/kern/acpi.c b/grub-core/kern/acpi.c -index 5746ac0..524c402 100644 ---- a/grub-core/kern/acpi.c -+++ b/grub-core/kern/acpi.c -@@ -99,12 +99,6 @@ grub_acpi_find_fadt (void) - if (fadt) - return fadt; - rsdpv2 = grub_machine_acpi_get_rsdpv2 (); -- if (rsdpv2) -- fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) -- (grub_addr_t) rsdpv2->rsdpv1.rsdt_addr, -- GRUB_ACPI_FADT_SIGNATURE); -- if (fadt) -- return fadt; - if (rsdpv2 - #if GRUB_CPU_SIZEOF_VOID_P != 8 - && !(rsdpv2->xsdt_addr >> 32) -@@ -115,5 +109,11 @@ grub_acpi_find_fadt (void) - GRUB_ACPI_FADT_SIGNATURE); - if (fadt) - return fadt; -+ if (rsdpv2) -+ fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) -+ (grub_addr_t) rsdpv2->rsdpv1.rsdt_addr, -+ GRUB_ACPI_FADT_SIGNATURE); -+ if (fadt) -+ return fadt; - return 0; - } --- -2.27.0 - diff --git a/backport-kern-buffer-Handle-NULL-input-pointer-in-grub_buffer.patch b/backport-kern-buffer-Handle-NULL-input-pointer-in-grub_buffer.patch deleted file mode 100644 index bca97f3..0000000 --- a/backport-kern-buffer-Handle-NULL-input-pointer-in-grub_buffer.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 82ff9faa5bff5b3669bc4144bfc9b2279d344483 Mon Sep 17 00:00:00 2001 -From: Jagannathan Raman -Date: Mon, 17 Oct 2022 14:04:39 +0000 -Subject: [PATCH] kern/buffer: Handle NULL input pointer in grub_buffer_free() - -The grub_buffer_free() should handle NULL input pointer, similar to -grub_free(). If the pointer is not referencing any memory location, -grub_buffer_free() need not perform any function. - -Fixes: CID 396931 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=82ff9faa5bff5b3669bc4144bfc9b2279d344483 -Conflict:NA - -Signed-off-by: Jagannathan Raman -Reviewed-by: Ross Philipson -Reviewed-by: Daniel Kiper ---- - grub-core/kern/buffer.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/buffer.c b/grub-core/kern/buffer.c -index 9f5f8b867..a2587729c 100644 ---- a/grub-core/kern/buffer.c -+++ b/grub-core/kern/buffer.c -@@ -49,8 +49,11 @@ grub_buffer_new (grub_size_t sz) - void - grub_buffer_free (grub_buffer_t buf) - { -- grub_free (buf->data); -- grub_free (buf); -+ if (buf != NULL) -+ { -+ grub_free (buf->data); -+ grub_free (buf); -+ } - } - - grub_err_t --- -2.28.0.windows.1 - diff --git a/backport-kern-efi-mm-Fix-use-after-free-in-finish-boot-services.patch b/backport-kern-efi-mm-Fix-use-after-free-in-finish-boot-services.patch deleted file mode 100644 index 532a0a6..0000000 --- a/backport-kern-efi-mm-Fix-use-after-free-in-finish-boot-services.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 6f05a277961dc801ba6de4f0f3bc22184ae80b0f Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Mon, 22 May 2023 16:52:49 -0400 -Subject: kern/efi/mm: Fix use-after-free in finish boot services - -In grub-core/kern/efi/mm.c, grub_efi_finish_boot_services() has an instance -where the memory for the variable finish_mmap_buf is freed, but on the next -iteration of a while loop, grub_efi_get_memory_map() uses finish_mmap_buf. To -prevent this, we can set finish_mmap_buf to NULL after the free. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=6f05a277961dc801ba6de4f0f3bc22184ae80b0f -Conflict:NA - -Signed-off-by: Alec Brown -Reviewed-by: Daniel Kiper ---- - grub-core/kern/efi/mm.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 2be0e69..6a6fba8 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -263,6 +263,7 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, - &finish_desc_size, &finish_desc_version) <= 0) - { - grub_free (finish_mmap_buf); -+ finish_mmap_buf = NULL; - return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); - } - -@@ -274,10 +275,12 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, - if (status != GRUB_EFI_INVALID_PARAMETER) - { - grub_free (finish_mmap_buf); -+ finish_mmap_buf = NULL; - return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services"); - } - - grub_free (finish_mmap_buf); -+ finish_mmap_buf = NULL; - grub_printf ("Trying to terminate EFI services again\n"); - } - grub_efi_is_finished = 1; --- -cgit v1.1 - diff --git a/backport-kern-efi-sb-Enforce-verification-of-font-files.patch b/backport-kern-efi-sb-Enforce-verification-of-font-files.patch deleted file mode 100644 index 04b29f2..0000000 --- a/backport-kern-efi-sb-Enforce-verification-of-font-files.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 93a786a00163e50c29f0394df198518617e1c9a5 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Sun, 14 Aug 2022 15:51:54 +0800 -Subject: [PATCH 08/13] kern/efi/sb: Enforce verification of font files - -As a mitigation and hardening measure enforce verification of font -files. Then only trusted font files can be load. This will reduce the -attack surface at cost of losing the ability of end-users to customize -fonts if e.g. UEFI Secure Boot is enabled. Vendors can always customize -fonts because they have ability to pack fonts into their GRUB bundles. - -This goal is achieved by: - - * Removing GRUB_FILE_TYPE_FONT from shim lock verifier's - skip-verification list. - - * Adding GRUB_FILE_TYPE_FONT to lockdown verifier's defer-auth list, - so font files must be verified by a verifier before they can be loaded. - -Suggested-by: Daniel Kiper -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/kern/efi/sb.c | 1 - - grub-core/kern/lockdown.c | 1 + - 2 files changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c -index 89c4bb3fd..db42c2539 100644 ---- a/grub-core/kern/efi/sb.c -+++ b/grub-core/kern/efi/sb.c -@@ -145,7 +145,6 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)), - case GRUB_FILE_TYPE_PRINT_BLOCKLIST: - case GRUB_FILE_TYPE_TESTLOAD: - case GRUB_FILE_TYPE_GET_SIZE: -- case GRUB_FILE_TYPE_FONT: - case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY: - case GRUB_FILE_TYPE_CAT: - case GRUB_FILE_TYPE_HEXCAT: -diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c -index 0bc70fd42..af6d493cd 100644 ---- a/grub-core/kern/lockdown.c -+++ b/grub-core/kern/lockdown.c -@@ -51,6 +51,7 @@ lockdown_verifier_init (grub_file_t io __attribute__ ((unused)), - case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE: - case GRUB_FILE_TYPE_ACPI_TABLE: - case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE: -+ case GRUB_FILE_TYPE_FONT: - *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH; - - /* Fall through. */ --- -2.27.0 - diff --git a/backport-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch b/backport-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch deleted file mode 100644 index bc0d527..0000000 --- a/backport-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 6fe755c5c07bb386fda58306bfd19e4a1c974c53 Mon Sep 17 00:00:00 2001 -From: Julian Andres Klode -Date: Thu, 2 Dec 2021 15:03:53 +0100 -Subject: kern/efi/sb: Reject non-kernel files in the shim_lock verifier - -We must not allow other verifiers to pass things like the GRUB modules. -Instead of maintaining a blocklist, maintain an allowlist of things -that we do not care about. - -This allowlist really should be made reusable, and shared by the -lockdown verifier, but this is the minimal patch addressing -security concerns where the TPM verifier was able to mark modules -as verified (or the OpenPGP verifier for that matter), when it -should not do so on shim-powered secure boot systems. - -Fixes: CVE-2022-28735 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=6fe755c5c07bb386fda58306bfd19e4a1c974c53 -Conflict:NA - -Signed-off-by: Julian Andres Klode -Reviewed-by: Daniel Kiper ---- - grub-core/kern/efi/sb.c | 39 ++++++++++++++++++++++++++++++++++++--- - include/grub/verify.h | 1 + - 2 files changed, 37 insertions(+), 3 deletions(-) - -diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c -index c52ec62..89c4bb3 100644 ---- a/grub-core/kern/efi/sb.c -+++ b/grub-core/kern/efi/sb.c -@@ -119,10 +119,11 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)), - void **context __attribute__ ((unused)), - enum grub_verify_flags *flags) - { -- *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; -+ *flags = GRUB_VERIFY_FLAGS_NONE; - - switch (type & GRUB_FILE_TYPE_MASK) - { -+ /* Files we check. */ - case GRUB_FILE_TYPE_LINUX_KERNEL: - case GRUB_FILE_TYPE_MULTIBOOT_KERNEL: - case GRUB_FILE_TYPE_BSD_KERNEL: -@@ -130,11 +131,43 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)), - case GRUB_FILE_TYPE_PLAN9_KERNEL: - case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE: - *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK; -+ return GRUB_ERR_NONE; - -- /* Fall through. */ -+ /* Files that do not affect secureboot state. */ -+ case GRUB_FILE_TYPE_NONE: -+ case GRUB_FILE_TYPE_LOOPBACK: -+ case GRUB_FILE_TYPE_LINUX_INITRD: -+ case GRUB_FILE_TYPE_OPENBSD_RAMDISK: -+ case GRUB_FILE_TYPE_XNU_RAMDISK: -+ case GRUB_FILE_TYPE_SIGNATURE: -+ case GRUB_FILE_TYPE_PUBLIC_KEY: -+ case GRUB_FILE_TYPE_PUBLIC_KEY_TRUST: -+ case GRUB_FILE_TYPE_PRINT_BLOCKLIST: -+ case GRUB_FILE_TYPE_TESTLOAD: -+ case GRUB_FILE_TYPE_GET_SIZE: -+ case GRUB_FILE_TYPE_FONT: -+ case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY: -+ case GRUB_FILE_TYPE_CAT: -+ case GRUB_FILE_TYPE_HEXCAT: -+ case GRUB_FILE_TYPE_CMP: -+ case GRUB_FILE_TYPE_HASHLIST: -+ case GRUB_FILE_TYPE_TO_HASH: -+ case GRUB_FILE_TYPE_KEYBOARD_LAYOUT: -+ case GRUB_FILE_TYPE_PIXMAP: -+ case GRUB_FILE_TYPE_GRUB_MODULE_LIST: -+ case GRUB_FILE_TYPE_CONFIG: -+ case GRUB_FILE_TYPE_THEME: -+ case GRUB_FILE_TYPE_GETTEXT_CATALOG: -+ case GRUB_FILE_TYPE_FS_SEARCH: -+ case GRUB_FILE_TYPE_LOADENV: -+ case GRUB_FILE_TYPE_SAVEENV: -+ case GRUB_FILE_TYPE_VERIFY_SIGNATURE: -+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; -+ return GRUB_ERR_NONE; - -+ /* Other files. */ - default: -- return GRUB_ERR_NONE; -+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by secure boot policy")); - } - } - -diff --git a/include/grub/verify.h b/include/grub/verify.h -index cd129c3..672ae16 100644 ---- a/include/grub/verify.h -+++ b/include/grub/verify.h -@@ -24,6 +24,7 @@ - - enum grub_verify_flags - { -+ GRUB_VERIFY_FLAGS_NONE = 0, - GRUB_VERIFY_FLAGS_SKIP_VERIFICATION = 1, - GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2, - /* Defer verification to another authority. */ --- -cgit v1.1 - diff --git a/backport-kern-file-Do-not-leak-device_name-on-error-in.patch b/backport-kern-file-Do-not-leak-device_name-on-error-in.patch deleted file mode 100644 index 3c82587..0000000 --- a/backport-kern-file-Do-not-leak-device_name-on-error-in.patch +++ /dev/null @@ -1,43 +0,0 @@ -From f1ce0e15e70ea1aafcfa26ad93e7585f65783c6f Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 25 Jun 2021 02:19:05 +1000 -Subject: kern/file: Do not leak device_name on error in grub_file_open() - -If we have an error in grub_file_open() before we free device_name, we -will leak it. - -Free device_name in the error path and null out the pointer in the good -path once we free it there. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=f1ce0e15e70ea1aafcfa26ad93e7585f65783c6f -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/kern/file.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c -index df24c1f..8d48fd5 100644 ---- a/grub-core/kern/file.c -+++ b/grub-core/kern/file.c -@@ -79,6 +79,7 @@ grub_file_open (const char *name, enum grub_file_type type) - - device = grub_device_open (device_name); - grub_free (device_name); -+ device_name = NULL; - if (! device) - goto fail; - -@@ -131,6 +132,7 @@ grub_file_open (const char *name, enum grub_file_type type) - return file; - - fail: -+ grub_free (device_name); - if (device) - grub_device_close (device); - --- -cgit v1.1 - diff --git a/backport-kern-file-Fix-error-handling-in-grub_file_open.patch b/backport-kern-file-Fix-error-handling-in-grub_file_open.patch deleted file mode 100644 index fba00f9..0000000 --- a/backport-kern-file-Fix-error-handling-in-grub_file_open.patch +++ /dev/null @@ -1,41 +0,0 @@ -From e375394fb9233fb1da13f7fb38e38d8aa83d1443 Mon Sep 17 00:00:00 2001 -From: Steve McIntyre -Date: Tue, 6 Dec 2022 01:45:11 +0000 -Subject: kern/file: Fix error handling in grub_file_open() - -grub_file_open() calls grub_file_get_device_name(), but doesn't check -the return. Instead, it checks if grub_errno is set. - -However, nothing initialises grub_errno here when grub_file_open() -starts. This means that trying to open one file that doesn't exist and -then trying to open another file that does will (incorrectly) also -fail to open that second file. - -Let's fix that. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=e375394fb9233fb1da13f7fb38e38d8aa83d1443 -Conflict:NA - -Signed-off-by: Steve McIntyre -Reviewed-by: Daniel Kiper ---- - grub-core/kern/file.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c -index ed69fc0..70b3c62 100644 ---- a/grub-core/kern/file.c -+++ b/grub-core/kern/file.c -@@ -66,6 +66,9 @@ grub_file_open (const char *name, enum grub_file_type type) - const char *file_name; - grub_file_filter_id_t filter; - -+ /* Reset grub_errno before we start. */ -+ grub_errno = GRUB_ERR_NONE; -+ - grub_dprintf ("file", "Opening `%s' ...\n", name); - - device_name = grub_file_get_device_name (name); --- -2.19.1 - diff --git a/backport-kern-fs-Fix-possible-integer-overflow-in-i386-pc-mode-with-large.patch b/backport-kern-fs-Fix-possible-integer-overflow-in-i386-pc-mode-with-large.patch deleted file mode 100644 index 4f2e793..0000000 --- a/backport-kern-fs-Fix-possible-integer-overflow-in-i386-pc-mode-with-large.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 1a241e050652472efa62b2b36ad2fa7f82427b83 Mon Sep 17 00:00:00 2001 -From: Maxim Fomin -Date: Wed, 28 Dec 2022 17:40:06 +0000 -Subject: kern/fs: Fix possible integer overflow in i386-pc mode with large - partitions - -The i386-pc mode supports MBR partition scheme where maximum partition -size is 2 TiB. In case of large partitions left shift expression with -unsigned long int "length" object may cause integer overflow making -calculated partition size less than true value. This issue is fixed by -increasing the size of "length" integer type. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=1a241e050652472efa62b2b36ad2fa7f82427b83 -Conflict:NA - -Signed-off-by: Maxim Fomin -Reviewed-by: Daniel Kiper ---- - grub-core/kern/fs.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c -index b950829..7ad0aaf 100644 ---- a/grub-core/kern/fs.c -+++ b/grub-core/kern/fs.c -@@ -130,7 +130,7 @@ grub_fs_probe (grub_device_t device) - struct grub_fs_block - { - grub_disk_addr_t offset; -- unsigned long length; -+ grub_disk_addr_t length; - }; - - static grub_err_t --- -cgit v1.1 - diff --git a/backport-kern-fs-The-grub_fs_probe-should-dprint-errors.patch b/backport-kern-fs-The-grub_fs_probe-should-dprint-errors.patch deleted file mode 100644 index 99c8f77..0000000 --- a/backport-kern-fs-The-grub_fs_probe-should-dprint-errors.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 92005be6d82b275e32bd74d1aabc45461e70db0d Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Fri, 15 Jul 2022 16:13:01 -0400 -Subject: kern/fs: The grub_fs_probe() should dprint errors from filesystems - -When filesystem detection fails, all that's currently debug-logged is -a series of messages like: - - grub-core/kern/fs.c:56:fs: Detecting ntfs... - grub-core/kern/fs.c:76:fs: ntfs detection failed. - -repeated for each filesystem. Any messages provided to grub_error() by -the filesystem are lost, and one has to break out gdb to figure out what -went wrong. - -With this change, one instead sees: - - grub-core/kern/fs.c:56:fs: Detecting fat... - grub-core/osdep/hostdisk.c:357:hostdisk: reusing open device - `/path/to/device' - grub-core/kern/fs.c:77:fs: error: invalid modification timestamp for /. - grub-core/kern/fs.c:79:fs: fat detection failed. - -in the debug prints. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=92005be6d82b275e32bd74d1aabc45461e70db0d -Conflict:NA - -Signed-off-by: Robbie Harwood -Reviewed-by: Daniel Kiper ---- - grub-core/kern/fs.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c -index e0d7e16..b950829 100644 ---- a/grub-core/kern/fs.c -+++ b/grub-core/kern/fs.c -@@ -75,6 +75,8 @@ grub_fs_probe (grub_device_t device) - return p; - - grub_error_push (); -+ /* The grub_error_push() does not touch grub_errmsg. */ -+ grub_dprintf ("fs", _("error: %s.\n"), grub_errmsg); - grub_dprintf ("fs", "%s detection failed.\n", p->name); - grub_error_pop (); - --- -cgit v1.1 diff --git a/backport-kern-rescue_parser-Ensure-that-parser-allocated-memory-is-not-leaked.patch b/backport-kern-rescue_parser-Ensure-that-parser-allocated-memory-is-not-leaked.patch deleted file mode 100644 index d3ef8cf..0000000 --- a/backport-kern-rescue_parser-Ensure-that-parser-allocated-memory-is-not-leaked.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 62f0489aff002a44a72d390b42fc571e91378838 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Wed, 16 Mar 2022 17:25:05 +0000 -Subject: kern/rescue_parser: Ensure that parser allocated memory is not leaked - -While it would appear unlikely that the memory allocated in *argv in -grub_parser_split_cmdline() would be leaked, we should try ensure that -it doesn't leak by calling grub_free() before we return from -grub_rescue_parse_line(). - -To avoid a possible double-free, grub_parser_split_cmdline() is being -changed to assign *argv = NULL when we've called grub_free() in the fail -section. - -Fixes: CID 96680 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=62f0489aff002a44a72d390b42fc571e91378838 - ---- - grub-core/kern/parser.c | 2 ++ - grub-core/kern/rescue_parser.c | 10 ++++++++-- - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c -index 6ab7aa4..9b7b31a 100644 ---- a/grub-core/kern/parser.c -+++ b/grub-core/kern/parser.c -@@ -298,6 +298,8 @@ grub_parser_split_cmdline (const char *cmdline, - - fail: - grub_free (*argv); -+ *argv = NULL; -+ *argc = 0; - goto out; - } - -diff --git a/grub-core/kern/rescue_parser.c b/grub-core/kern/rescue_parser.c -index 6338366..799641a 100644 ---- a/grub-core/kern/rescue_parser.c -+++ b/grub-core/kern/rescue_parser.c -@@ -36,10 +36,16 @@ grub_rescue_parse_line (char *line, - - if (grub_parser_split_cmdline (line, getline, getline_data, &n, &args) - || n < 0) -- return grub_errno; -+ { -+ grub_free(args); -+ return grub_errno; -+ } - - if (n == 0) -- return GRUB_ERR_NONE; -+ { -+ grub_free(args); -+ return GRUB_ERR_NONE; -+ } - - /* In case of an assignment set the environment accordingly - instead of calling a function. */ --- -cgit v1.1 - diff --git a/backport-lib-relocator-Fix-OOB-write-when-initializing-lo-freebytes.patch b/backport-lib-relocator-Fix-OOB-write-when-initializing-lo-freebytes.patch deleted file mode 100644 index 9c78d1d..0000000 --- a/backport-lib-relocator-Fix-OOB-write-when-initializing-lo-freebytes.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 9dbfbcd660470c3b951d15af0f6ce5a423185ad2 Mon Sep 17 00:00:00 2001 -From: Daniel Kiper -Date: Fri, 23 Jun 2023 00:02:24 +0200 -Subject: lib/relocator: Fix OOB write when initializing lo->freebytes[] - -Fixes: CID 96636 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=9dbfbcd660470c3b951d15af0f6ce5a423185ad2 -Conflict:NA - -Signed-off-by: Daniel Kiper -Reviewed-by: Vladimir Serbinenko ---- - grub-core/lib/relocator.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c -index 568fc0b..e0478ae 100644 ---- a/grub-core/lib/relocator.c -+++ b/grub-core/lib/relocator.c -@@ -881,9 +881,11 @@ malloc_in_range (struct grub_relocator *rel, - offend = GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; - lo->freebytes[offstart / 8] - &= ((1 << (8 - (start % 8))) - 1); -- grub_memset (lo->freebytes + (offstart + 7) / 8, 0, -- offend / 8 - (offstart + 7) / 8); -- lo->freebytes[offend / 8] &= ~((1 << (offend % 8)) - 1); -+ if (offend / 8 > (offstart + 7) / 8) -+ grub_memset (lo->freebytes + (offstart + 7) / 8, 0, -+ offend / 8 - (offstart + 7) / 8); -+ if (offend < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT) -+ lo->freebytes[offend / 8] &= ~((1 << (offend % 8)) - 1); - } - break; - #endif --- -cgit v1.1 - diff --git a/backport-lib-relocator-Initialize-local-relocator-subchunk-struct-to.patch b/backport-lib-relocator-Initialize-local-relocator-subchunk-struct-to.patch deleted file mode 100644 index 5b63cab..0000000 --- a/backport-lib-relocator-Initialize-local-relocator-subchunk-struct-to.patch +++ /dev/null @@ -1,40 +0,0 @@ -From f7f453e0bf1043d89587638ffd24b8c34631b8eb Mon Sep 17 00:00:00 2001 -From: Ross Philipson -Date: Thu, 14 Jul 2022 09:41:28 -0400 -Subject: lib/relocator: Initialize local relocator subchunk struct to all - zeros - -The way the code is written the tofree variable would never be passed to -the free_subchunk() function uninitialized. Coverity cannot determine -this and flags the situation as "Using uninitialized value...". The fix -is just to initialize the local struct. - -Fixes: CID 314016 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=f7f453e0bf1043d89587638ffd24b8c34631b8eb -Conflict:NA - -Signed-off-by: Ross Philipson -Reviewed-by: Darren Kenny -Tested-by: Alec Brown -Reviewed-by: Daniel Kiper ---- - grub-core/lib/relocator.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c -index 68ef128..bfcc70d 100644 ---- a/grub-core/lib/relocator.c -+++ b/grub-core/lib/relocator.c -@@ -989,7 +989,7 @@ malloc_in_range (struct grub_relocator *rel, - if (j != 0 && events[j - 1].pos != events[j].pos) - { - grub_addr_t alloc_start, alloc_end; -- struct grub_relocator_subchunk tofree; -+ struct grub_relocator_subchunk tofree = {0}; - struct grub_relocator_subchunk *curschu = &tofree; - if (!oom) - curschu = &res->subchunks[cural]; --- -cgit v1.1 - diff --git a/backport-loader-arm64-linux-Remove-magic-number-header-field-.patch b/backport-loader-arm64-linux-Remove-magic-number-header-field-.patch deleted file mode 100644 index 4eb7c84..0000000 --- a/backport-loader-arm64-linux-Remove-magic-number-header-field-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 69edb31205602c29293a8c6e67363bba2a4a1e66 Mon Sep 17 00:00:00 2001 -From: Ard Biesheuvel -Date: Thu, 11 Aug 2022 16:51:57 +0200 -Subject: loader/arm64/linux: Remove magic number header field check - -The "ARM\x64" magic number in the file header identifies an image as one -that implements the bare metal boot protocol, allowing the loader to -simply move the file to a suitably aligned address in memory, with -sufficient headroom for the trailing .bss segment (the required memory -size is described in the header as well). - -Note of this matters for GRUB, as it only supports EFI boot. EFI does -not care about this magic number, and nor should GRUB: this prevents us -from booting other PE linux images, such as the generic EFI zboot -decompressor, which is a pure PE/COFF image, and does not implement the -bare metal boot protocol. - -So drop the magic number check. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=69edb31205602c29293a8c6e67363bba2a4a1e66 -Conflict:NA - -Signed-off-by: Ard Biesheuvel -Reviewed-by: Daniel Kiper ---- - grub-core/loader/arm64/linux.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index d2af47c..c6db843 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -55,9 +55,6 @@ static grub_addr_t initrd_end; - grub_err_t - grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) - { -- if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE) -- return grub_error(GRUB_ERR_BAD_OS, "invalid magic number"); -- - if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled")); --- -2.19.1 - diff --git a/backport-loader-efi-chainloader-Simplify-the-loader-state.patch b/backport-loader-efi-chainloader-Simplify-the-loader-state.patch deleted file mode 100644 index f8f5ce7..0000000 --- a/backport-loader-efi-chainloader-Simplify-the-loader-state.patch +++ /dev/null @@ -1,336 +0,0 @@ -From 1469983ebb9674753ad333d37087fb8cb20e1dce Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Fri, 29 Apr 2022 21:13:08 +0100 -Subject: loader/efi/chainloader: Simplify the loader state - -When not using the shim lock protocol, the chainloader command retains -the source buffer and device path passed to LoadImage, requiring the -unload hook passed to grub_loader_set to free them. It isn't required -to retain this state though - they aren't required by StartImage or -anything else in the boot hook, so clean them up before -grub_cmd_chainloader finishes. - -This also wraps the loader state when using the shim lock protocol -inside a struct. - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Chris Coulson -(cherry picked from commit fa39862933b3be1553a580a3a5c28073257d8046) -[rharwood: fix unitialized handle and double-frees of file/dev] -Signed-off-by: Robbie Harwood ---- - grub-core/loader/efi/chainloader.c | 160 +++++++++++++++++++++++-------------- - 1 file changed, 102 insertions(+), 58 deletions(-) - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index d3bf02ed8a..3342492ff1 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -48,38 +48,21 @@ GRUB_MOD_LICENSE ("GPLv3+"); - - static grub_dl_t my_mod; - --static grub_efi_physical_address_t address; --static grub_efi_uintn_t pages; --static grub_ssize_t fsize; --static grub_efi_device_path_t *file_path; - static grub_efi_handle_t image_handle; --static grub_efi_char16_t *cmdline; --static grub_ssize_t cmdline_len; --static grub_efi_handle_t dev_handle; - --static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table); -+struct grub_secureboot_chainloader_context { -+ grub_efi_physical_address_t address; -+ grub_efi_uintn_t pages; -+ grub_ssize_t fsize; -+ grub_efi_device_path_t *file_path; -+ grub_efi_char16_t *cmdline; -+ grub_ssize_t cmdline_len; -+ grub_efi_handle_t dev_handle; -+}; -+static struct grub_secureboot_chainloader_context *sb_context; - - static grub_err_t --grub_chainloader_unload (void) --{ -- grub_efi_boot_services_t *b; -- -- b = grub_efi_system_table->boot_services; -- efi_call_1 (b->unload_image, image_handle); -- grub_efi_free_pages (address, pages); -- -- grub_free (file_path); -- grub_free (cmdline); -- cmdline = 0; -- file_path = 0; -- dev_handle = 0; -- -- grub_dl_unref (my_mod); -- return GRUB_ERR_NONE; --} -- --static grub_err_t --grub_chainloader_boot (void) -+grub_start_image (grub_efi_handle_t handle) - { - grub_efi_boot_services_t *b; - grub_efi_status_t status; -@@ -87,7 +70,7 @@ grub_chainloader_boot (void) - grub_efi_char16_t *exit_data = NULL; - - b = grub_efi_system_table->boot_services; -- status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data); -+ status = efi_call_3 (b->start_image, handle, &exit_data_size, &exit_data); - if (status != GRUB_EFI_SUCCESS) - { - if (exit_data) -@@ -111,11 +94,37 @@ grub_chainloader_boot (void) - if (exit_data) - grub_efi_free_pool (exit_data); - -- grub_loader_unset (); -- - return grub_errno; - } - -+static grub_err_t -+grub_chainloader_unload (void) -+{ -+ grub_efi_loaded_image_t *loaded_image; -+ grub_efi_boot_services_t *b; -+ -+ loaded_image = grub_efi_get_loaded_image (image_handle); -+ if (loaded_image != NULL) -+ grub_free (loaded_image->load_options); -+ -+ b = grub_efi_system_table->boot_services; -+ efi_call_1 (b->unload_image, image_handle); -+ -+ grub_dl_unref (my_mod); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_chainloader_boot (void) -+{ -+ grub_err_t err; -+ -+ err = grub_start_image (image_handle); -+ -+ grub_loader_unset (); -+ return err; -+} -+ - static grub_err_t - copy_file_path (grub_efi_file_path_device_path_t *fp, - const char *str, grub_efi_uint16_t len) -@@ -150,7 +159,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) - char *dir_start; - char *dir_end; - grub_size_t size; -- grub_efi_device_path_t *d; -+ grub_efi_device_path_t *d, *file_path; - - dir_start = grub_strchr (filename, ')'); - if (! dir_start) -@@ -526,10 +535,12 @@ grub_efi_get_media_file_path (grub_efi_device_path_t *dp) - } - - static grub_efi_boolean_t --handle_image (void *data, grub_efi_uint32_t datasize) -+handle_image (struct grub_secureboot_chainloader_context *load_context) - { - grub_efi_loaded_image_t *li, li_bak; - grub_efi_status_t efi_status; -+ void *data = (void *)(unsigned long)load_context->address; -+ grub_efi_uint32_t datasize = load_context->fsize; - void *buffer = NULL; - char *buffer_aligned = NULL; - grub_efi_uint32_t i; -@@ -540,6 +551,7 @@ handle_image (void *data, grub_efi_uint32_t datasize) - grub_uint32_t buffer_size; - int found_entry_point = 0; - int rc; -+ grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table); - - rc = read_header (data, datasize, &context); - if (rc < 0) -@@ -797,10 +809,10 @@ handle_image (void *data, grub_efi_uint32_t datasize) - grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t)); - li->image_base = buffer_aligned; - li->image_size = context.image_size; -- li->load_options = cmdline; -- li->load_options_size = cmdline_len; -- li->file_path = grub_efi_get_media_file_path (file_path); -- li->device_handle = dev_handle; -+ li->load_options = load_context->cmdline; -+ li->load_options_size = load_context->cmdline_len; -+ li->file_path = grub_efi_get_media_file_path (load_context->file_path); -+ li->device_handle = load_context->dev_handle; - if (!li->file_path) - { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found"); -@@ -829,19 +841,22 @@ error_exit: - static grub_err_t - grub_secureboot_chainloader_unload (void) - { -- grub_efi_free_pages (address, pages); -- grub_free (file_path); -- grub_free (cmdline); -- cmdline = 0; -- file_path = 0; -- dev_handle = 0; -+ grub_efi_free_pages (sb_context->address, sb_context->pages); -+ grub_free (sb_context->file_path); -+ grub_free (sb_context->cmdline); -+ grub_free (sb_context); -+ -+ sb_context = 0; - - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; - } - - static grub_err_t --grub_load_image(void *boot_image) -+grub_load_image(grub_efi_device_path_t *file_path, void *boot_image, -+ grub_efi_uintn_t image_size, grub_efi_handle_t dev_handle, -+ grub_efi_char16_t *cmdline, grub_ssize_t cmdline_len, -+ grub_efi_handle_t *image_handle_out) - { - grub_efi_boot_services_t *b; - grub_efi_status_t status; -@@ -850,7 +865,7 @@ grub_load_image(void *boot_image) - b = grub_efi_system_table->boot_services; - - status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, -- boot_image, fsize, &image_handle); -+ boot_image, image_size, image_handle_out); - if (status != GRUB_EFI_SUCCESS) - { - if (status == GRUB_EFI_OUT_OF_RESOURCES) -@@ -863,7 +878,7 @@ grub_load_image(void *boot_image) - /* LoadImage does not set a device handler when the image is - loaded from memory, so it is necessary to set it explicitly here. - This is a mess. */ -- loaded_image = grub_efi_get_loaded_image (image_handle); -+ loaded_image = grub_efi_get_loaded_image (*image_handle_out); - if (! loaded_image) - { - grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); -@@ -885,20 +900,25 @@ grub_secureboot_chainloader_boot (void) - { - grub_efi_boot_services_t *b; - int rc; -+ grub_efi_handle_t handle = 0; - -- rc = handle_image ((void *)(unsigned long)address, fsize); -+ rc = handle_image (sb_context); - if (rc == 0) - { - /* We weren't able to attempt to execute the image, so fall back - * to LoadImage / StartImage. - */ -- rc = grub_load_image((void *)(unsigned long)address); -+ rc = grub_load_image(sb_context->file_path, -+ (void *)(unsigned long)sb_context->address, -+ sb_context->fsize, sb_context->dev_handle, -+ sb_context->cmdline, sb_context->cmdline_len, -+ &handle); - if (rc == 0) -- grub_chainloader_boot (); -+ grub_start_image (handle); - } - - b = grub_efi_system_table->boot_services; -- efi_call_1 (b->unload_image, image_handle); -+ efi_call_1 (b->unload_image, handle); - - grub_loader_unset (); - return grub_errno; -@@ -913,9 +933,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_efi_boot_services_t *b; - grub_device_t dev = 0; - grub_device_t orig_dev = 0; -- grub_efi_device_path_t *dp = 0; -+ grub_efi_device_path_t *dp = 0, *file_path = 0; - char *filename; - void *boot_image = 0; -+ grub_efi_physical_address_t address = 0; -+ grub_ssize_t fsize; -+ grub_efi_uintn_t pages = 0; -+ grub_efi_char16_t *cmdline = 0; -+ grub_ssize_t cmdline_len = 0; -+ grub_efi_handle_t dev_handle = 0; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -@@ -923,12 +949,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - - grub_dl_ref (my_mod); - -- /* Initialize some global variables. */ -- address = 0; -- image_handle = 0; -- file_path = 0; -- dev_handle = 0; -- - b = grub_efi_system_table->boot_services; - - if (argc > 1) -@@ -1093,17 +1113,35 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - - if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { -+ sb_context = grub_malloc (sizeof (*sb_context)); -+ if (sb_context == NULL) -+ goto fail; -+ sb_context->address = address; -+ sb_context->fsize = fsize; -+ sb_context->pages = pages; -+ sb_context->file_path = file_path; -+ sb_context->cmdline = cmdline; -+ sb_context->cmdline_len = cmdline_len; -+ sb_context->dev_handle = dev_handle; -+ - grub_file_close (file); - grub_device_close (dev); -+ - grub_loader_set (grub_secureboot_chainloader_boot, - grub_secureboot_chainloader_unload, 0); - return 0; - } - else - { -- grub_load_image(boot_image); -+ grub_load_image(file_path, boot_image, fsize, dev_handle, cmdline, -+ cmdline_len, &image_handle); - grub_file_close (file); - grub_device_close (dev); -+ -+ /* We're finished with the source image buffer and file path now */ -+ efi_call_2 (b->free_pages, address, pages); -+ grub_free (file_path); -+ - grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); - - return 0; -@@ -1130,6 +1168,12 @@ fail: - if (cmdline) - grub_free (cmdline); - -+ if (image_handle != 0) -+ { -+ efi_call_1 (b->unload_image, image_handle); -+ image_handle = 0; -+ } -+ - grub_dl_unref (my_mod); - - return grub_errno; --- -2.19.1 - diff --git a/backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch b/backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch deleted file mode 100644 index 46c016d..0000000 --- a/backport-loader-efi-chainloader-Use-grub_loader_set_ex.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 04c86e0bb7b58fc2f913f798cdb18934933e532d Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Fri, 29 Apr 2022 21:30:56 +0100 -Subject: [PATCH] loader/efi/chainloader: Use grub_loader_set_ex - -This ports the EFI chainloader to use grub_loader_set_ex() in order to fix -a use-after-free bug that occurs when grub_cmd_chainloader() is executed -more than once before a boot attempt is performed. - -Fixes: CVE-2022-28736 - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Chris Coulson -(cherry picked from commit 4b7f0402b7cb0f67a93be736f2b75b818d7f44c9) -[rharwood: context sludge from other change] -Signed-off-by: Robbie Harwood ---- - grub-core/loader/efi/chainloader.c | 38 ++++++++++++++++++++++---------------- - 1 file changed, 22 insertions(+), 16 deletions(-) - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 3342492ff1..fb874f1855 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -48,8 +48,6 @@ GRUB_MOD_LICENSE ("GPLv3+"); - - static grub_dl_t my_mod; - --static grub_efi_handle_t image_handle; -- - struct grub_secureboot_chainloader_context { - grub_efi_physical_address_t address; - grub_efi_uintn_t pages; -@@ -59,7 +57,6 @@ struct grub_secureboot_chainloader_context { - grub_ssize_t cmdline_len; - grub_efi_handle_t dev_handle; - }; --static struct grub_secureboot_chainloader_context *sb_context; - - static grub_err_t - grub_start_image (grub_efi_handle_t handle) -@@ -98,11 +95,14 @@ grub_start_image (grub_efi_handle_t handle) - } - - static grub_err_t --grub_chainloader_unload (void) -+grub_chainloader_unload (void *context) - { -+ grub_efi_handle_t image_handle; - grub_efi_loaded_image_t *loaded_image; - grub_efi_boot_services_t *b; - -+ image_handle = (grub_efi_handle_t) context; -+ - loaded_image = grub_efi_get_loaded_image (image_handle); - if (loaded_image != NULL) - grub_free (loaded_image->load_options); -@@ -115,10 +115,12 @@ grub_chainloader_unload (void) - } - - static grub_err_t --grub_chainloader_boot (void) -+grub_chainloader_boot (void *context) - { -+ grub_efi_handle_t image_handle; - grub_err_t err; - -+ image_handle = (grub_efi_handle_t) context; - err = grub_start_image (image_handle); - - grub_loader_unset (); -@@ -839,15 +841,17 @@ error_exit: - } - - static grub_err_t --grub_secureboot_chainloader_unload (void) -+grub_secureboot_chainloader_unload (void *context) - { -+ struct grub_secureboot_chainloader_context *sb_context; -+ -+ sb_context = (struct grub_secureboot_chainloader_context *) context; -+ - grub_efi_free_pages (sb_context->address, sb_context->pages); - grub_free (sb_context->file_path); - grub_free (sb_context->cmdline); - grub_free (sb_context); - -- sb_context = 0; -- - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; - } -@@ -896,12 +900,15 @@ grub_load_image(grub_efi_device_path_t *file_path, void *boot_image, - } - - static grub_err_t --grub_secureboot_chainloader_boot (void) -+grub_secureboot_chainloader_boot (void *context) - { -+ struct grub_secureboot_chainloader_context *sb_context; - grub_efi_boot_services_t *b; - int rc; - grub_efi_handle_t handle = 0; - -+ sb_context = (struct grub_secureboot_chainloader_context *) context; -+ - rc = handle_image (sb_context); - if (rc == 0) - { -@@ -942,6 +949,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_efi_char16_t *cmdline = 0; - grub_ssize_t cmdline_len = 0; - grub_efi_handle_t dev_handle = 0; -+ grub_efi_handle_t image_handle = 0; -+ struct grub_secureboot_chainloader_context *sb_context = 0; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -@@ -1127,8 +1136,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_file_close (file); - grub_device_close (dev); - -- grub_loader_set (grub_secureboot_chainloader_boot, -- grub_secureboot_chainloader_unload, 0); -+ grub_loader_set_ex (grub_secureboot_chainloader_boot, -+ grub_secureboot_chainloader_unload, sb_context, 0); - return 0; - } - else -@@ -1142,7 +1151,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - efi_call_2 (b->free_pages, address, pages); - grub_free (file_path); - -- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); -+ grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0); - - return 0; - } -@@ -1169,10 +1178,7 @@ fail: - grub_free (cmdline); - - if (image_handle != 0) -- { -- efi_call_1 (b->unload_image, image_handle); -- image_handle = 0; -- } -+ efi_call_1 (b->unload_image, image_handle); - - grub_dl_unref (my_mod); - --- -2.19.1 - diff --git a/backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch b/backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch deleted file mode 100644 index 939335c..0000000 --- a/backport-loader-efi-chainloader-grub_load_and_start_image-doe.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Thu, 28 Apr 2022 21:53:36 +0100 -Subject: [PATCH] loader/efi/chainloader: grub_load_and_start_image doesn't - load and start - -grub_load_and_start_image only loads an image - it still requires the -caller to start it. This renames it to grub_load_image. - -It's called from 2 places: -- grub_cmd_chainloader when not using the shim protocol. -- grub_secureboot_chainloader_boot if handle_image returns an error. -In this case, the image is loaded and then nothing else happens which -seems strange. I assume the intention is that it falls back to LoadImage -and StartImage if handle_image fails, so I've made it do that. - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Chris Coulson -(cherry picked from commit b4d70820a65c00561045856b7b8355461a9545f6) ---- - grub-core/loader/efi/chainloader.c | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 644cd2e56f..d3bf02ed8a 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -841,7 +841,7 @@ grub_secureboot_chainloader_unload (void) - } - - static grub_err_t --grub_load_and_start_image(void *boot_image) -+grub_load_image(void *boot_image) - { - grub_efi_boot_services_t *b; - grub_efi_status_t status; -@@ -883,13 +883,23 @@ grub_load_and_start_image(void *boot_image) - static grub_err_t - grub_secureboot_chainloader_boot (void) - { -+ grub_efi_boot_services_t *b; - int rc; -+ - rc = handle_image ((void *)(unsigned long)address, fsize); - if (rc == 0) - { -- grub_load_and_start_image((void *)(unsigned long)address); -+ /* We weren't able to attempt to execute the image, so fall back -+ * to LoadImage / StartImage. -+ */ -+ rc = grub_load_image((void *)(unsigned long)address); -+ if (rc == 0) -+ grub_chainloader_boot (); - } - -+ b = grub_efi_system_table->boot_services; -+ efi_call_1 (b->unload_image, image_handle); -+ - grub_loader_unset (); - return grub_errno; - } -@@ -1091,7 +1101,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - } - else - { -- grub_load_and_start_image(boot_image); -+ grub_load_image(boot_image); - grub_file_close (file); - grub_device_close (dev); - grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); diff --git a/backport-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch b/backport-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch deleted file mode 100644 index af58eab..0000000 --- a/backport-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Mon, 2 May 2022 14:39:31 +0200 -Subject: [PATCH] loader/i386/efi/linux: Avoid a use-after-free in the linuxefi - loader - -In some error paths in grub_cmd_linux, the pointer to lh may be -dereferenced after the buffer it points to has been freed. There aren't -any security implications from this because nothing else uses the -allocator after the buffer is freed and before the pointer is -dereferenced, but fix it anyway. - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Chris Coulson -(cherry picked from commit 8224f5a71af94bec8697de17e7e579792db9f9e2) ---- - grub-core/loader/i386/efi/linux.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 941df6400b..27bc2aa161 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -465,9 +465,6 @@ fail: - if (file) - grub_file_close (file); - -- if (kernel) -- grub_free (kernel); -- - if (grub_errno != GRUB_ERR_NONE) - { - grub_dl_unref (my_mod); -@@ -483,6 +480,8 @@ fail: - kernel_free (params, sizeof(*params)); - } - -+ grub_free (kernel); -+ - return grub_errno; - } - diff --git a/backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch b/backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch deleted file mode 100644 index ae6eeb7..0000000 --- a/backport-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Tue, 3 May 2022 09:47:35 +0200 -Subject: [PATCH] loader/i386/efi/linux: Fix a memory leak in the initrd - command - -Subsequent invocations of the initrd command result in the previous -initrd being leaked, so fix that. - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Chris Coulson -(cherry picked from commit d98af31ce1e31bb22163960d53f5eb28c66582a0) ---- - grub-core/loader/i386/efi/linux.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index e3c2d6fe0b..9e5c11ac69 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -209,6 +209,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) - grub_uint8_t *ptr; - struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data; - struct linux_kernel_params *params; -+ void *initrd_mem = 0; - - if (argc == 0) - { -@@ -241,19 +242,19 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) - } - } - -- context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); -- if (context->initrd_mem == NULL) -+ initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); -+ if (initrd_mem == NULL) - goto fail; -- grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem); -+ grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); - - params->ramdisk_size = LOW_U32(size); -- params->ramdisk_image = LOW_U32(context->initrd_mem); -+ params->ramdisk_image = LOW_U32(initrd_mem); - #if defined(__x86_64__) - params->ext_ramdisk_size = HIGH_U32(size); -- params->ext_ramdisk_image = HIGH_U32(context->initrd_mem); -+ params->ext_ramdisk_image = HIGH_U32(initrd_mem); - #endif - -- ptr = context->initrd_mem; -+ ptr = initrd_mem; - - for (i = 0; i < nfiles; i++) - { -@@ -270,6 +271,9 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) - ptr += ALIGN_UP_OVERHEAD (cursize, 4); - } - -+ kernel_free(context->initrd_mem, params->ramdisk_size); -+ -+ context->initrd_mem = initrd_mem; - params->ramdisk_size = size; - - fail: -@@ -277,9 +281,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) - grub_file_close (files[i]); - grub_free (files); - -- if (context->initrd_mem && grub_errno) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem, -- BYTES_TO_PAGES(size)); -+ if (initrd_mem && grub_errno) -+ kernel_free (initrd_mem, size); - - return grub_errno; - } - diff --git a/backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch b/backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch deleted file mode 100644 index 171f900..0000000 --- a/backport-loader-i386-efi-linux-Use-grub_loader_set_ex.patch +++ /dev/null @@ -1,299 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Mon, 2 May 2022 17:04:23 +0200 -Subject: [PATCH] loader/i386/efi/linux: Use grub_loader_set_ex - -This ports the linuxefi loader to use grub_loader_set_ex in order to fix -a use-after-fre bug that occurs when grub_cmd_linux is executed more than -once before a boot attempt is performed. - -This is more complicated than for the chainloader command, as the initrd -command needs access to the loader state. To solve this, the linuxefi -module registers a dummy initrd command at startup that returns an error. -The linuxefi command then registers a proper initrd command with a higher -priority that is passed the loader state. - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Chris Coulson -(cherry picked from commit 7cf736436b4c934df5ddfa6f44b46a7e07d99fdc) -[rharwood/pjones: set kernel_size in context] -Signed-off-by: Robbie Harwood ---- - grub-core/loader/i386/efi/linux.c | 146 +++++++++++++++++++++++--------------- - 1 file changed, 87 insertions(+), 59 deletions(-) - -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 27bc2aa161..e3c2d6fe0b 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -34,13 +34,19 @@ - GRUB_MOD_LICENSE ("GPLv3+"); - - static grub_dl_t my_mod; --static int loaded; --static void *kernel_mem; --static grub_uint64_t kernel_size; --static void *initrd_mem; --static grub_uint32_t handover_offset; --struct linux_kernel_params *params; --static char *linux_cmdline; -+ -+static grub_command_t cmd_linux, cmd_initrd; -+static grub_command_t cmd_linuxefi, cmd_initrdefi; -+ -+struct grub_linuxefi_context { -+ void *kernel_mem; -+ grub_uint64_t kernel_size; -+ grub_uint32_t handover_offset; -+ struct linux_kernel_params *params; -+ char *cmdline; -+ -+ void *initrd_mem; -+}; - - #define MIN(a, b) \ - ({ typeof (a) _a = (a); \ -@@ -123,25 +129,32 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) - } - - static grub_err_t --grub_linuxefi_boot (void) -+grub_linuxefi_boot (void *data) - { -+ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data; -+ - asm volatile ("cli"); - -- return grub_efi_linux_boot ((char *)kernel_mem, -- handover_offset, -- params); -+ return grub_efi_linux_boot ((char *)context->kernel_mem, -+ context->handover_offset, -+ context->params); - } - - static grub_err_t --grub_linuxefi_unload (void) -+grub_linuxefi_unload (void *data) - { -+ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data; -+ struct linux_kernel_params *params = context->params; -+ - grub_dl_unref (my_mod); -- loaded = 0; - -- kernel_free(initrd_mem, params->ramdisk_size); -- kernel_free(linux_cmdline, params->cmdline_size + 1); -- kernel_free(kernel_mem, kernel_size); -- kernel_free(params, sizeof(*params)); -+ kernel_free (context->initrd_mem, params->ramdisk_size); -+ kernel_free (context->cmdline, params->cmdline_size + 1); -+ kernel_free (context->kernel_mem, context->kernel_size); -+ kernel_free (params, sizeof(*params)); -+ cmd_initrd->data = 0; -+ cmd_initrdefi->data = 0; -+ grub_free (context); - - return GRUB_ERR_NONE; - } -@@ -188,13 +201,14 @@ read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) - #define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull)) - - static grub_err_t --grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), -- int argc, char *argv[]) -+grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[]) - { - grub_file_t *files = 0; - int i, nfiles = 0; - grub_size_t size = 0; - grub_uint8_t *ptr; -+ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data; -+ struct linux_kernel_params *params; - - if (argc == 0) - { -@@ -202,12 +216,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- if (!loaded) -+ if (!context) - { - grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); - goto fail; - } - -+ params = context->params; -+ - files = grub_calloc (argc, sizeof (files[0])); - if (!files) - goto fail; -@@ -225,19 +241,19 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - } - } - -- initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); -- if (initrd_mem == NULL) -+ context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); -+ if (context->initrd_mem == NULL) - goto fail; -- grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); -+ grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem); - - params->ramdisk_size = LOW_U32(size); -- params->ramdisk_image = LOW_U32(initrd_mem); -+ params->ramdisk_image = LOW_U32(context->initrd_mem); - #if defined(__x86_64__) - params->ext_ramdisk_size = HIGH_U32(size); -- params->ext_ramdisk_image = HIGH_U32(initrd_mem); -+ params->ext_ramdisk_image = HIGH_U32(context->initrd_mem); - #endif - -- ptr = initrd_mem; -+ ptr = context->initrd_mem; - - for (i = 0; i < nfiles; i++) - { -@@ -261,8 +277,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - grub_file_close (files[i]); - grub_free (files); - -- if (initrd_mem && grub_errno) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, -+ if (context->initrd_mem && grub_errno) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem, - BYTES_TO_PAGES(size)); - - return grub_errno; -@@ -277,6 +293,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_ssize_t start, filelen; - void *kernel = NULL; - int setup_header_end_offset; -+ void *kernel_mem = 0; -+ grub_uint64_t kernel_size = 0; -+ grub_uint32_t handover_offset; -+ struct linux_kernel_params *params = 0; -+ char *cmdline = 0; -+ struct grub_linuxefi_context *context = 0; - - grub_dl_ref (my_mod); - -@@ -390,27 +412,27 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_dprintf ("linux", "new lh is at %p\n", lh); - - grub_dprintf ("linux", "setting up cmdline\n"); -- linux_cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline")); -- if (!linux_cmdline) -+ cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline")); -+ if (!cmdline) - goto fail; -- grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline); -+ grub_dprintf ("linux", "cmdline = %p\n", cmdline); - -- grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); -+ grub_memcpy (cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, -- linux_cmdline + sizeof (LINUX_IMAGE) - 1, -+ cmdline + sizeof (LINUX_IMAGE) - 1, - lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1), - GRUB_VERIFY_KERNEL_CMDLINE); - -- grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); -+ grub_dprintf ("linux", "cmdline:%s\n", cmdline); - grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n", -- LOW_U32(linux_cmdline)); -- lh->cmd_line_ptr = LOW_U32(linux_cmdline); -+ LOW_U32(cmdline)); -+ lh->cmd_line_ptr = LOW_U32(cmdline); - #if defined(__x86_64__) -- if ((grub_efi_uintn_t)linux_cmdline > 0xffffffffull) -+ if ((grub_efi_uintn_t)cmdline > 0xffffffffull) - { - grub_dprintf ("linux", "setting params->ext_cmd_line_ptr to 0x%08x\n", -- HIGH_U32(linux_cmdline)); -- params->ext_cmd_line_ptr = HIGH_U32(linux_cmdline); -+ HIGH_U32(cmdline)); -+ params->ext_cmd_line_ptr = HIGH_U32(cmdline); - } - #endif - -@@ -435,16 +457,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; - max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS; -- kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel")); -+ kernel_size = lh->init_size; -+ kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel")); - restore_addresses(); - if (!kernel_mem) - goto fail; - grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); - -- grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); -- -- loaded = 1; -- - grub_dprintf ("linux", "setting lh->code32_start to 0x%08x\n", - LOW_U32(kernel_mem)); - lh->code32_start = LOW_U32(kernel_mem); -@@ -461,33 +480,42 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - "setting lh->ext_loader_{type,ver} = {0x%02x,0x%02x}\n", - params->ext_loader_type, params->ext_loader_ver); - -+ context = grub_zalloc (sizeof (*context)); -+ if (!context) -+ goto fail; -+ context->kernel_mem = kernel_mem; -+ context->kernel_size = kernel_size; -+ context->handover_offset = handover_offset; -+ context->params = params; -+ context->cmdline = cmdline; -+ -+ grub_loader_set_ex (grub_linuxefi_boot, grub_linuxefi_unload, context, 0); -+ -+ cmd_initrd->data = context; -+ cmd_initrdefi->data = context; -+ -+ grub_file_close (file); -+ grub_free (kernel); -+ return 0; -+ - fail: - if (file) - grub_file_close (file); - -- if (grub_errno != GRUB_ERR_NONE) -- { -- grub_dl_unref (my_mod); -- loaded = 0; -- } -+ grub_dl_unref (my_mod); - -- if (!loaded) -- { -- if (lh) -- kernel_free (linux_cmdline, lh->cmdline_size + 1); -+ if (lh) -+ kernel_free (cmdline, lh->cmdline_size + 1); - -- kernel_free (kernel_mem, kernel_size); -- kernel_free (params, sizeof(*params)); -- } -+ kernel_free (kernel_mem, kernel_size); -+ kernel_free (params, sizeof(*params)); - -+ grub_free (context); - grub_free (kernel); - - return grub_errno; - } - --static grub_command_t cmd_linux, cmd_initrd; --static grub_command_t cmd_linuxefi, cmd_initrdefi; -- - GRUB_MOD_INIT(linux) - { - cmd_linux = diff --git a/backport-loader-i386-pc-linux-Fix-uninitialized-scalar-variable.patch b/backport-loader-i386-pc-linux-Fix-uninitialized-scalar-variable.patch deleted file mode 100644 index 1c0a737..0000000 --- a/backport-loader-i386-pc-linux-Fix-uninitialized-scalar-variable.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 261e4511ce335cc3784cbbe6c99fd35a81efa059 Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Mon, 21 Mar 2022 02:28:57 -0400 -Subject: loader/i386/pc/linux: Fix uninitialized scalar variable - -In the function grub_linux16_boot(), struct grub_relocator16_state state is -called but isn't being initialized. This results in the members grub_uint32_t -ebx, grub_uint32_t edx, grub_uint32_t esi, and grub_uint32_t ebp being filled -with junk data from the stack since none of them are being set to any values. -We can prevent this by setting state to {0}. - -Fixes: CID 375028 - -Signed-off-by: Alec Brown -Reviewed-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=261e4511ce335cc3784cbbe6c99fd35a81efa059 - ---- - grub-core/loader/i386/pc/linux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c -index b670b65..7b89d43 100644 ---- a/grub-core/loader/i386/pc/linux.c -+++ b/grub-core/loader/i386/pc/linux.c -@@ -55,7 +55,7 @@ static grub_err_t - grub_linux16_boot (void) - { - grub_uint16_t segment; -- struct grub_relocator16_state state; -+ struct grub_relocator16_state state = {0}; - - segment = grub_linux_real_target >> 4; - state.gs = state.fs = state.es = state.ds = state.ss = segment; --- -cgit v1.1 - diff --git a/backport-loader-linux-Ensure-the-newc-pathname-is-NULL-termin.patch b/backport-loader-linux-Ensure-the-newc-pathname-is-NULL-termin.patch deleted file mode 100644 index 6612272..0000000 --- a/backport-loader-linux-Ensure-the-newc-pathname-is-NULL-termin.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 544fd63f0f7a6b1e270ec88c4ece2c3e76b206f5 Mon Sep 17 00:00:00 2001 -From: Gary Lin -Date: Fri, 25 Nov 2022 15:37:35 +0800 -Subject: [PATCH] loader/linux: Ensure the newc pathname is NULL-terminated - -Per "man 5 cpio", the namesize in the cpio header includes the trailing -NUL byte of the pathname and the pathname is followed by NUL bytes, but -the current implementation ignores the trailing NUL byte when making -the newc header. Although make_header() tries to pad the pathname string, -the padding won't happen when strlen(name) + sizeof(struct newc_head) -is a multiple of 4, and the non-NULL-terminated pathname may lead to -unexpected results. - -Assume that a file is created with 'echo -n aaaa > /boot/test12' and -loaded by grub2: - - linux /boot/vmlinuz - initrd newc:test12:/boot/test12 /boot/initrd - -The initrd command eventually invoked grub_initrd_load() and sent -'t''e''s''t''1''2' to make_header() to generate the header: - -00000070 30 37 30 37 30 31 33 30 31 43 41 30 44 45 30 30 |070701301CA0DE00| -00000080 30 30 38 31 41 34 30 30 30 30 30 33 45 38 30 30 |0081A4000003E800| -00000090 30 30 30 30 36 34 30 30 30 30 30 30 30 31 36 33 |0000640000000163| -000000a0 37 36 45 34 35 32 30 30 30 30 30 30 30 34 30 30 |76E4520000000400| -000000b0 30 30 30 30 30 38 30 30 30 30 30 30 31 33 30 30 |0000080000001300| -000000c0 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| -000000d0 30 30 30 30 30 36 30 30 30 30 30 30 30 30 74 65 |00000600000000te| - ^namesize -000000e0 73 74 31 32 61 61 61 61 30 37 30 37 30 31 30 30 |st12aaaa07070100| - ^^ end of the pathname - -Since strlen("test12") + sizeof(struct newc_head) is 116 = 29 * 4, -make_header() didn't pad the pathname, and the file content followed -"test12" immediately. This violates the cpio format and may trigger such -error during linux boot: - - Initramfs unpacking failed: ZSTD-compressed data is trunc - -To avoid the potential problems, this commit counts the trailing NUL byte -in when calling make_header() and adjusts the initrd size accordingly. - -Now the header becomes - -00000070 30 37 30 37 30 31 33 30 31 43 41 30 44 45 30 30 |070701301CA0DE00| -00000080 30 30 38 31 41 34 30 30 30 30 30 33 45 38 30 30 |0081A4000003E800| -00000090 30 30 30 30 36 34 30 30 30 30 30 30 30 31 36 33 |0000640000000163| -000000a0 37 36 45 34 35 32 30 30 30 30 30 30 30 34 30 30 |76E4520000000400| -000000b0 30 30 30 30 30 38 30 30 30 30 30 30 31 33 30 30 |0000080000001300| -000000c0 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 |0000000000000000| -000000d0 30 30 30 30 30 37 30 30 30 30 30 30 30 30 74 65 |00000700000000te| - ^namesize -000000e0 73 74 31 32 00 00 00 00 61 61 61 61 30 37 30 37 |st12....aaaa0707| - ^^ end of the pathname - -Besides the trailing NUL byte, make_header() pads 3 more NUL bytes, and -the user can safely read the pathname without a further check. - -To conform to the cpio format, the headers for "TRAILER!!!" are also -adjusted to include the trailing NUL byte, not ignore it. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=544fd63f0f7a6b1e270ec88c4ece2c3e76b206f5 -Conflict:NA - -Signed-off-by: Gary Lin -Reviewed-by: Daniel Kiper ---- - grub-core/loader/linux.c | 27 +++++++++++++++++++-------- - 1 file changed, 19 insertions(+), 8 deletions(-) - -diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c -index 830360172..3948302d2 100644 ---- a/grub-core/loader/linux.c -+++ b/grub-core/loader/linux.c -@@ -127,12 +127,23 @@ insert_dir (const char *name, struct dir **root, - n->name = grub_strndup (cb, ce - cb); - if (ptr) - { -+ /* -+ * Create the substring with the trailing NUL byte -+ * to be included in the cpio header. -+ */ -+ char *tmp_name = grub_strndup (name, ce - name); -+ if (!tmp_name) { -+ grub_free (n->name); -+ grub_free (n); -+ return grub_errno; -+ } - grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce); -- ptr = make_header (ptr, name, ce - name, -+ ptr = make_header (ptr, tmp_name, ce - name + 1, - 040777, 0); -+ grub_free (tmp_name); - } - if (grub_add (*size, -- ALIGN_UP ((ce - (char *) name) -+ ALIGN_UP ((ce - (char *) name + 1) - + sizeof (struct newc_head), 4), - size)) - { -@@ -191,7 +202,7 @@ grub_initrd_init (int argc, char *argv[], - grub_initrd_close (initrd_ctx); - return grub_errno; - } -- name_len = grub_strlen (initrd_ctx->components[i].newc_name); -+ name_len = grub_strlen (initrd_ctx->components[i].newc_name) + 1; - if (grub_add (initrd_ctx->size, - ALIGN_UP (sizeof (struct newc_head) + name_len, 4), - &initrd_ctx->size) || -@@ -205,7 +216,7 @@ grub_initrd_init (int argc, char *argv[], - { - if (grub_add (initrd_ctx->size, - ALIGN_UP (sizeof (struct newc_head) -- + sizeof ("TRAILER!!!") - 1, 4), -+ + sizeof ("TRAILER!!!"), 4), - &initrd_ctx->size)) - goto overflow; - free_dir (root); -@@ -233,7 +244,7 @@ grub_initrd_init (int argc, char *argv[], - initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); - if (grub_add (initrd_ctx->size, - ALIGN_UP (sizeof (struct newc_head) -- + sizeof ("TRAILER!!!") - 1, 4), -+ + sizeof ("TRAILER!!!"), 4), - &initrd_ctx->size)) - goto overflow; - free_dir (root); -@@ -297,14 +308,14 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, - } - ptr += dir_size; - ptr = make_header (ptr, initrd_ctx->components[i].newc_name, -- grub_strlen (initrd_ctx->components[i].newc_name), -+ grub_strlen (initrd_ctx->components[i].newc_name) + 1, - 0100777, - initrd_ctx->components[i].size); - newc = 1; - } - else if (newc) - { -- ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, -+ ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), - 0, 0); - free_dir (root); - root = 0; -@@ -327,7 +338,7 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, - { - grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); - ptr += ALIGN_UP_OVERHEAD (cursize, 4); -- ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0); -+ ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!"), 0, 0); - } - free_dir (root); - root = 0; --- -2.28.0.windows.1 - diff --git a/backport-loader-multiboot_elfxx-Fix-memory-leak.patch b/backport-loader-multiboot_elfxx-Fix-memory-leak.patch deleted file mode 100644 index 4a7fb04..0000000 --- a/backport-loader-multiboot_elfxx-Fix-memory-leak.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 113142939172bda9759d4d2e5a053911821d2faf Mon Sep 17 00:00:00 2001 -From: "t.feng" -Date: Thu, 10 Nov 2022 15:01:15 +0800 -Subject: loader/multiboot_elfxx: Fix memory leak - -The commit eb33e61b3 (multiboot: fix memory leak) did not fix all -issues. Fix all of them right now. - -Fixes: eb33e61b3 (multiboot: fix memory leak) - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=113142939172bda9759d4d2e5a053911821d2faf -Conflict:NA - -Signed-off-by: t.feng -Reviewed-by: Daniel Kiper ---- - grub-core/loader/multiboot_elfxx.c | 23 ++++++++++++++--------- - 1 file changed, 14 insertions(+), 9 deletions(-) - -diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c -index 87f6e31..57330a0 100644 ---- a/grub-core/loader/multiboot_elfxx.c -+++ b/grub-core/loader/multiboot_elfxx.c -@@ -220,10 +220,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) - return grub_errno; - - if (grub_file_seek (mld->file, ehdr->e_shoff) == (grub_off_t) -1) -- { -- grub_free (shdr); -- return grub_errno; -- } -+ goto fail; - - if (grub_file_read (mld->file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize) - != (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize) -@@ -231,7 +228,7 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - mld->filename); -- return grub_errno; -+ goto fail; - } - - for (shdrptr = shdr, i = 0; i < ehdr->e_shnum; -@@ -242,7 +239,10 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) - grub_addr_t target; - - if (mld->mbi_ver >= 2 && (sh->sh_type == SHT_REL || sh->sh_type == SHT_RELA)) -- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet"); -+ { -+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet"); -+ goto fail; -+ } - - /* This section is a loaded section, - so we don't care. */ -@@ -261,13 +261,14 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) - if (err) - { - grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i); -- return err; -+ grub_errno = err; -+ goto fail; - } - src = get_virtual_current_address (ch); - target = get_physical_target_address (ch); - - if (grub_file_seek (mld->file, sh->sh_offset) == (grub_off_t) -1) -- return grub_errno; -+ goto fail; - - if (grub_file_read (mld->file, src, sh->sh_size) - != (grub_ssize_t) sh->sh_size) -@@ -275,12 +276,16 @@ CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld) - if (!grub_errno) - grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), - mld->filename); -- return grub_errno; -+ goto fail; - } - sh->sh_addr = target; - } - GRUB_MULTIBOOT (add_elfsyms) (ehdr->e_shnum, ehdr->e_shentsize, - ehdr->e_shstrndx, shdr); -+ return GRUB_ERR_NONE; -+ -+fail: -+ grub_free (shdr); - } - - #undef phdr --- -2.19.1 - diff --git a/backport-misc-Add-cast-in-grub_strncasecmp-to-drop-sign-when-.patch b/backport-misc-Add-cast-in-grub_strncasecmp-to-drop-sign-when-.patch deleted file mode 100644 index 63f1ec1..0000000 --- a/backport-misc-Add-cast-in-grub_strncasecmp-to-drop-sign-when-.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 13fb5af10c835c32862e6c861fc655101e2917c7 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Thu, 11 Aug 2022 12:48:42 -0500 -Subject: misc: Add cast in grub_strncasecmp() to drop sign when calling - grub_tolower() - -Note this cast was fixed in grub_strcasecmp() in commit ce41ab7aab -(* grub-core/kern/misc.c (grub_strcmp): Use unsigned comparison as per -common usage and preffered in several parts of code.), but this commit -omitted fixing it in grub_strncasecmp(). - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=13fb5af10c835c32862e6c861fc655101e2917c7 -Conflict:NA - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper ---- - include/grub/misc.h | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/include/grub/misc.h b/include/grub/misc.h -index cf84aec..6c89a9e 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -240,7 +240,8 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) - - while (*s1 && *s2 && --n) - { -- if (grub_tolower (*s1) != grub_tolower (*s2)) -+ if (grub_tolower ((grub_uint8_t) *s1) -+ != grub_tolower ((grub_uint8_t) *s2)) - break; - - s1++; --- -2.19.1 - diff --git a/backport-misc-Make-grub_min-and-grub_max-more-resilient.patch b/backport-misc-Make-grub_min-and-grub_max-more-resilient.patch deleted file mode 100644 index fd8af70..0000000 --- a/backport-misc-Make-grub_min-and-grub_max-more-resilient.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 21 Mar 2022 16:06:10 -0400 -Subject: [PATCH] misc: Make grub_min() and grub_max() more resilient. - -grub_min(a,b) and grub_max(a,b) use a relatively naive implementation -which leads to several problems: -- they evaluate their parameters more than once -- the naive way to address this, to declare temporary variables in a - statement-expression, isn't resilient against nested uses, because - MIN(a,MIN(b,c)) results in the temporary variables being declared in - two nested scopes, which may result in a build warning depending on - your build options. - -This patch changes our implementation to use a statement-expression -inside a helper macro, and creates the symbols for the temporary -variables with __COUNTER__ (A GNU C cpp extension) and token pasting to -create uniquely named internal variables. - -Reference:https://src.fedoraproject.org/rpms/grub2/c/f0ad2aaa267a5d99b47f5c5770a55de0a702fdf0?branch=rawhide -Conflict:NA - -Signed-off-by: Peter Jones ---- - grub-core/loader/multiboot_elfxx.c | 4 +--- - include/grub/misc.h | 25 +++++++++++++++++++++++-- - 2 files changed, 24 insertions(+), 5 deletions(-) - -diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c -index f2318e0d16..87f6e31aa6 100644 ---- a/grub-core/loader/multiboot_elfxx.c -+++ b/grub-core/loader/multiboot_elfxx.c -@@ -35,9 +35,7 @@ - #endif - - #include -- --#define CONCAT(a,b) CONCAT_(a, b) --#define CONCAT_(a,b) a ## b -+#include - - #pragma GCC diagnostic ignored "-Wcast-align" - -diff --git a/include/grub/misc.h b/include/grub/misc.h -index 6c4aa85ac5..cf84aec1db 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -35,6 +35,14 @@ - #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) - #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } - -+#ifndef CONCAT_ -+#define CONCAT_(a, b) a ## b -+#endif -+ -+#ifndef CONCAT -+#define CONCAT(a, b) CONCAT_(a, b) -+#endif -+ - #define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) - - void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); -@@ -498,8 +506,21 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file, - #define grub_boot_time(...) - #endif - --#define grub_max(a, b) (((a) > (b)) ? (a) : (b)) --#define grub_min(a, b) (((a) < (b)) ? (a) : (b)) -+#define _grub_min(a, b, _a, _b) \ -+ ({ typeof (a) _a = (a); \ -+ typeof (b) _b = (b); \ -+ _a < _b ? _a : _b; }) -+#define grub_min(a, b) _grub_min(a, b, \ -+ CONCAT(_a_,__COUNTER__), \ -+ CONCAT(_b_,__COUNTER__)) -+ -+#define _grub_max(a, b, _a, _b) \ -+ ({ typeof (a) _a = (a); \ -+ typeof (b) _b = (b); \ -+ _a > _b ? _a : _b; }) -+#define grub_max(a, b) _grub_max(a, b, \ -+ CONCAT(_a_,__COUNTER__), \ -+ CONCAT(_b_,__COUNTER__)) - - #define grub_log2ull(n) (GRUB_TYPE_BITS (grub_uint64_t) - __builtin_clzll (n) - 1) - diff --git a/backport-mm-Temporarily-disable-grub_mm_debug-while-calling-grub_vprintf-in-grub_printf.patch b/backport-mm-Temporarily-disable-grub_mm_debug-while-calling-grub_vprintf-in-grub_printf.patch deleted file mode 100644 index 12f2026..0000000 --- a/backport-mm-Temporarily-disable-grub_mm_debug-while-calling-grub_vprintf-in-grub_printf.patch +++ /dev/null @@ -1,59 +0,0 @@ -From a4430355a3237fc756480349e9167667b0e89476 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Tue, 15 Feb 2022 12:36:43 -0600 -Subject: mm: Temporarily disable grub_mm_debug while calling grub_vprintf() in - grub_printf() - -To prevent infinite recursion when grub_mm_debug is on, disable it when -calling grub_vprintf(). One such call loop is: - grub_vprintf() -> parse_printf_args() -> parse_printf_arg_fmt() -> - grub_debug_calloc() -> grub_printf() -> grub_vprintf(). - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=a4430355a3237fc756480349e9167667b0e89476 - ---- - grub-core/kern/misc.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index de40f56..18bde5d 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -113,10 +113,30 @@ grub_printf (const char *fmt, ...) - va_list ap; - int ret; - -+#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) -+ /* -+ * To prevent infinite recursion when grub_mm_debug is on, disable it -+ * when calling grub_vprintf(). One such call loop is: -+ * grub_vprintf() -> parse_printf_args() -> parse_printf_arg_fmt() -> -+ * grub_debug_calloc() -> grub_printf() -> grub_vprintf(). -+ */ -+ int grub_mm_debug_save = 0; -+ -+ if (grub_mm_debug) -+ { -+ grub_mm_debug_save = grub_mm_debug; -+ grub_mm_debug = 0; -+ } -+#endif -+ - va_start (ap, fmt); - ret = grub_vprintf (fmt, ap); - va_end (ap); - -+#if defined(MM_DEBUG) && !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) -+ grub_mm_debug = grub_mm_debug_save; -+#endif -+ - return ret; - } - --- -cgit v1.1 - diff --git a/backport-net-Check-against-nb-tail-in-grub_netbuff_pull.patch b/backport-net-Check-against-nb-tail-in-grub_netbuff_pull.patch deleted file mode 100644 index 11796f0..0000000 --- a/backport-net-Check-against-nb-tail-in-grub_netbuff_pull.patch +++ /dev/null @@ -1,64 +0,0 @@ -From e976dc27f88968bc768224fd8102a508a3a39383 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Sat, 5 Mar 2022 00:39:04 +1100 -Subject: net: Check against nb->tail in grub_netbuff_pull() - -GRUB netbuff structure members track 2 different things: the extent of memory -allocated for the packet, and the extent of memory currently being worked on. - -This works out in the structure as follows: - - nb->head: beginning of the allocation - nb->data: beginning of the working data - nb->tail: end of the working data - nb->end: end of the allocation - -The head and end pointers are set in grub_netbuff_alloc() and do not change. -The data and tail pointers are initialised to point at start of the -allocation (that is, head == data == tail initially), and are then -manipulated by grub_netbuff_*() functions. Key functions are as follows: - - - grub_netbuff_put(): "put" more data into the packet - advance nb->tail - - grub_netbuff_unput(): trim the tail of the packet - retract nb->tail - - grub_netbuff_pull(): "consume" some packet data - advance nb->data - - grub_netbuff_reserve(): reserve space for future headers - advance nb->data and nb->tail - - grub_netbuff_push(): "un-consume" data to allow headers to be written - retract nb->data - -Each of those functions does some form of error checking. For example, -grub_netbuff_put() does not allow nb->tail to exceed nb->end, and -grub_netbuff_push() does not allow nb->data to be before nb->head. - -However, grub_netbuff_pull()'s error checking is a bit weird. It advances nb->data -and checks that it does not exceed nb->end. That allows you to get into the -situation where nb->data > nb->tail, which should not be. - -Make grub_netbuff_pull() check against both nb->tail and nb->end. In theory just -checking against ->tail should be sufficient but the extra check should be -cheap and seems like good defensive practice. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=e976dc27f88968bc768224fd8102a508a3a39383 - ---- - grub-core/net/netbuff.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c -index dbeeefe..72e5296 100644 ---- a/grub-core/net/netbuff.c -+++ b/grub-core/net/netbuff.c -@@ -54,7 +54,7 @@ grub_err_t - grub_netbuff_pull (struct grub_net_buff *nb, grub_size_t len) - { - nb->data += len; -- if (nb->data > nb->end) -+ if (nb->data > nb->end || nb->data > nb->tail) - return grub_error (GRUB_ERR_BUG, - "pull out of the packet range."); - return GRUB_ERR_NONE; --- -cgit v1.1 - diff --git a/backport-net-arp-Fix-uninitialized-scalar-variable.patch b/backport-net-arp-Fix-uninitialized-scalar-variable.patch deleted file mode 100644 index 627756d..0000000 --- a/backport-net-arp-Fix-uninitialized-scalar-variable.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 6bb551db112a6d7509d5633be103fe3ee1e09f37 Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Mon, 21 Mar 2022 02:28:58 -0400 -Subject: net/arp: Fix uninitialized scalar variable - -In the function grub_net_arp_receive(), grub_net_network_level_address_t -sender_addr and target_addr are being called but aren't being initialized. -In both of these structs, each member is being set to a value except for -grub_dns_option_t option. This results in this member being filled with junk -data from the stack. To prevent this, we can set the option member in both -structs to 0. - -Fixes: CID 375030 - -Signed-off-by: Alec Brown -Reviewed-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict:Context adaptation -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=6bb551db112a6d7509d5633be103fe3ee1e09f37 - ---- - grub-core/net/arp.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c -index 54306e3..1d36743 100644 ---- a/grub-core/net/arp.c -+++ b/grub-core/net/arp.c -@@ -128,6 +128,8 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, - grub_uint8_t pln; - grub_uint8_t arp_packet_len; - grub_uint8_t *tmp_ptr; -+ sender_addr.option = 0; -+ target_addr.option = 0; - - hw_type = card->default_address.type; - hln = card->default_address.len; - --- -cgit v1.1 - diff --git a/backport-net-bootp-Fix-unchecked-return-value.patch b/backport-net-bootp-Fix-unchecked-return-value.patch deleted file mode 100644 index 96c111d..0000000 --- a/backport-net-bootp-Fix-unchecked-return-value.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 4f7d77d7e0740c1b0d69c7a658b5c4986eda0093 Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Fri, 3 Feb 2023 17:18:14 -0500 -Subject: net/bootp: Fix unchecked return value - -In the function send_dhcp_packet(), added an error check for the return -value of grub_netbuff_push(). - -Fixes: CID 404614 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=4f7d77d7e0740c1b0d69c7a658b5c4986eda0093 -Conflict:NA - -Signed-off-by: Alec Brown -Reviewed-by: Daniel Kiper ---- - grub-core/net/bootp.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index 2e3c86e..6b07a4a 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -727,7 +727,9 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) - - grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, pack->hw_len); - -- grub_netbuff_push (nb, sizeof (*udph)); -+ err = grub_netbuff_push (nb, sizeof (*udph)); -+ if (err) -+ goto out; - - udph = (struct udphdr *) nb->data; - udph->src = grub_cpu_to_be16_compile_time (68); --- -2.19.1 - diff --git a/backport-net-bootp-Fix-uninitialized-scalar-variable.patch b/backport-net-bootp-Fix-uninitialized-scalar-variable.patch deleted file mode 100644 index ccee943..0000000 --- a/backport-net-bootp-Fix-uninitialized-scalar-variable.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 23c3cbe1dba4fd0c6dc8156bd628d3162e63408d Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Mon, 21 Mar 2022 02:29:02 -0400 -Subject: net/bootp: Fix uninitialized scalar variable - -In the function grub_net_configure_by_dhcp_ack(), -grub_net_network_level_address_t addr is called but isn't being initialized. -This results in the member grub_dns_option_t option being filled with junk data -from the stack. To prevent this, we can set the option member in addr to 0. - -Fixes: CID 375036 - -Signed-off-by: Alec Brown -Reviewed-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=23c3cbe1dba4fd0c6dc8156bd628d3162e63408d - ---- - grub-core/net/bootp.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index 8dc1479..7d31dba 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -244,6 +244,7 @@ grub_net_configure_by_dhcp_ack (const char *name, - - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - addr.ipv4 = bp->your_ip; -+ addr.option = 0; - - if (device) - *device = 0; --- -cgit v1.1 - diff --git a/backport-net-dns-Dont-read-past-the-end-of-the-string.patch b/backport-net-dns-Dont-read-past-the-end-of-the-string.patch deleted file mode 100644 index 751cc5d..0000000 --- a/backport-net-dns-Dont-read-past-the-end-of-the-string.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 96abf4fb9d829f4a405d5df39bc74bbccbd0e322 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 20 Dec 2021 21:55:43 +1100 -Subject: net/dns: Don't read past the end of the string we're checking against - -I don't really understand what's going on here but fuzzing found -a bug where we read past the end of check_with. That's a C string, -so use grub_strlen() to make sure we don't overread it. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=96abf4fb9d829f4a405d5df39bc74bbccbd0e322 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/dns.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c -index 135faac..17961a9 100644 ---- a/grub-core/net/dns.c -+++ b/grub-core/net/dns.c -@@ -146,11 +146,18 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, - int *length, char *set) - { - const char *readable_ptr = check_with; -+ int readable_len; - const grub_uint8_t *ptr; - char *optr = set; - int bytes_processed = 0; - if (length) - *length = 0; -+ -+ if (readable_ptr != NULL) -+ readable_len = grub_strlen (readable_ptr); -+ else -+ readable_len = 0; -+ - for (ptr = name_at; ptr < tail && bytes_processed < tail - head + 2; ) - { - /* End marker. */ -@@ -172,13 +179,16 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, - ptr = head + (((ptr[0] & 0x3f) << 8) | ptr[1]); - continue; - } -- if (readable_ptr && grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0) -+ if (readable_ptr != NULL && (*ptr > readable_len || grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0)) - return 0; - if (grub_memchr (ptr + 1, 0, *ptr) - || grub_memchr (ptr + 1, '.', *ptr)) - return 0; - if (readable_ptr) -- readable_ptr += *ptr; -+ { -+ readable_ptr += *ptr; -+ readable_len -= *ptr; -+ } - if (readable_ptr && *readable_ptr != '.' && *readable_ptr != 0) - return 0; - bytes_processed += *ptr + 1; -@@ -192,7 +202,10 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, - if (optr) - *optr++ = '.'; - if (readable_ptr && *readable_ptr) -- readable_ptr++; -+ { -+ readable_ptr++; -+ readable_len--; -+ } - ptr += *ptr + 1; - } - return 0; --- -2.19.1 - diff --git a/backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch b/backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch deleted file mode 100644 index 5e9f6db..0000000 --- a/backport-net-dns-Fix-double-free-addresses-on-corrupt-DNS.patch +++ /dev/null @@ -1,61 +0,0 @@ -From c1b7eef9fa4aaefbf7d0507505c3bb2914e1ad6b Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 16 Sep 2021 01:29:54 +1000 -Subject: net/dns: Fix double-free addresses on corrupt DNS response - -grub_net_dns_lookup() takes as inputs a pointer to an array of addresses -("addresses") for the given name, and pointer to a number of addresses -("naddresses"). grub_net_dns_lookup() is responsible for allocating -"addresses", and the caller is responsible for freeing it if -"naddresses" > 0. - -The DNS recv_hook will sometimes set and free the addresses array, -for example if the packet is too short: - - if (ptr + 10 >= nb->tail) - { - if (!*data->naddresses) - grub_free (*data->addresses); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - -Later on the nslookup command code unconditionally frees the "addresses" -array. Normally this is fine: the array is either populated with valid -data or is NULL. But in these sorts of error cases it is neither NULL -nor valid and we get a double-free. - -Only free "addresses" if "naddresses" > 0. - -It looks like the other use of grub_net_dns_lookup() is not affected. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=c1b7eef9fa4aaefbf7d0507505c3bb2914e1ad6b -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/dns.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c -index 27c5f41..841ede5 100644 ---- a/grub-core/net/dns.c -+++ b/grub-core/net/dns.c -@@ -667,9 +667,11 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)), - grub_net_addr_to_str (&addresses[i], buf); - grub_printf ("%s\n", buf); - } -- grub_free (addresses); - if (naddresses) -- return GRUB_ERR_NONE; -+ { -+ grub_free (addresses); -+ return GRUB_ERR_NONE; -+ } - return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found")); - } - --- -cgit v1.1 - diff --git a/backport-net-dns-Fix-lookup-error-when-no-IPv6-is-returned.patch b/backport-net-dns-Fix-lookup-error-when-no-IPv6-is-returned.patch deleted file mode 100644 index c64ec85..0000000 --- a/backport-net-dns-Fix-lookup-error-when-no-IPv6-is-returned.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 1be86fae1587cb8c53c2327971c8fc94fcb3234e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Wed, 3 May 2023 12:21:31 +0200 -Subject: net/dns: Fix lookup error when no IPv6 is returned -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When trying to resolve DNS names into IP addresses, the DNS code fails -from time to time with the following error: --------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- -error: ../../grub-core/net/dns.c:688:no DNS record found. --------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- - -This happens when both IPv4 and IPv6 queries are performed against the -DNS server (e.g. 8.8.8.8) but there is no IP returned for IPv6 query, as -shown below: --------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- -grub> net_del_dns 192.168.122.1 -grub> net_add_dns 8.8.8.8 -grub> net_nslookup ipv4.test-ipv6.com -error: ../../grub-core/net/dns.c:688:no DNS record found. -grub> net_nslookup ipv4.test-ipv6.com -216.218.228.115 --------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- - -The root cause is the code exiting prematurely when the data->addresses -buffer has been allocated in recv_hook(), even if there was no address -returned last time recv_hook() executed. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=1be86fae1587cb8c53c2327971c8fc94fcb3234e -Conflict:NA - -Signed-off-by: Renaud Métrich -Reviewed-by: Daniel Kiper ---- - grub-core/net/dns.c | 22 ++++++---------------- - 1 file changed, 6 insertions(+), 16 deletions(-) - -diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c -index 9760980..fcc09aa 100644 ---- a/grub-core/net/dns.c -+++ b/grub-core/net/dns.c -@@ -261,7 +261,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - /* Code apparently assumed that only one packet is received as response. - We may get multiple responses due to network condition, so check here - and quit early. */ -- if (*data->addresses) -+ if (*data->naddresses) - goto out; - - head = (struct dns_header *) nb->data; -@@ -305,11 +305,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - grub_uint32_t ttl = 0; - grub_uint16_t length; - if (ptr >= nb->tail) -- { -- if (!*data->naddresses) -- grub_free (*data->addresses); -- goto out; -- } -+ goto out; - ignored = !check_name (ptr, nb->data, nb->tail, data->name); - while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0)) - ptr += *ptr + 1; -@@ -317,11 +313,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - ptr++; - ptr++; - if (ptr + 10 >= nb->tail) -- { -- if (!*data->naddresses) -- grub_free (*data->addresses); -- goto out; -- } -+ goto out; - if (*ptr++ != 0) - ignored = 1; - class = *ptr++; -@@ -337,11 +329,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - length = *ptr++ << 8; - length |= *ptr++; - if (ptr + length > nb->tail) -- { -- if (!*data->naddresses) -- grub_free (*data->addresses); -- goto out; -- } -+ goto out; - if (!ignored) - { - if (ttl_all > ttl) -@@ -428,6 +416,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - out: - grub_netbuff_free (nb); - grub_free (redirect_save); -+ if (!*data->naddresses) -+ grub_free (*data->addresses); - return GRUB_ERR_NONE; - } - --- -cgit v1.1 diff --git a/backport-net-dns-Fix-removal-of-DNS-server.patch b/backport-net-dns-Fix-removal-of-DNS-server.patch deleted file mode 100644 index 182a3cc..0000000 --- a/backport-net-dns-Fix-removal-of-DNS-server.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f301a9356b6338e983eae38debe69bbd3a417b1a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Fri, 28 Apr 2023 13:05:37 +0200 -Subject: net/dns: Fix removal of DNS server -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When deleting the DNS server, we get the following error message: --------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- -grub> net_del_dns 192.168.122.1 -error: ../../grub-core/net/dns.c:646:no DNS reply received. --------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- - -This happens because the implementation is broken, it does a "add" -internally instead of a "delete". - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=f301a9356b6338e983eae38debe69bbd3a417b1a -Conflict:NA - -Signed-off-by: Renaud Métrich -Reviewed-by: Daniel Kiper ---- - grub-core/net/dns.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c -index afa3894..e51682d 100644 ---- a/grub-core/net/dns.c -+++ b/grub-core/net/dns.c -@@ -765,11 +765,14 @@ grub_cmd_del_dns (struct grub_command *cmd __attribute__ ((unused)), - - if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); -- err = grub_net_resolve_address (args[1], &server); -+ -+ err = grub_net_resolve_address (args[0], &server); - if (err) - return err; - -- return grub_net_add_dns_server (&server); -+ grub_net_remove_dns_server (&server); -+ -+ return GRUB_ERR_NONE; - } - - static grub_command_t cmd, cmd_add, cmd_del, cmd_list; --- -cgit v1.1 diff --git a/backport-net-dns-Simplify-error-handling-of-recv_hook-function.patch b/backport-net-dns-Simplify-error-handling-of-recv_hook-function.patch deleted file mode 100644 index ad693a1..0000000 --- a/backport-net-dns-Simplify-error-handling-of-recv_hook-function.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 6c0edcdc27568bb7ae9e5bd89ebc7b8c137f6bc0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Wed, 3 May 2023 12:21:29 +0200 -Subject: net/dns: Simplify error handling of recv_hook() function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/grub-core/net/dns.c?id=6c0edcdc27568bb7ae9e5bd89ebc7b8c137f6bc0 -Conflict:NA - -Signed-off-by: Renaud Métrich -Reviewed-by: Daniel Kiper ---- - grub-core/net/dns.c | 50 +++++++++++++++------------------------------ - 1 file changed, 16 insertions(+), 34 deletions(-) - -diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c -index e9edf5d..0aba533 100644 ---- a/grub-core/net/dns.c -+++ b/grub-core/net/dns.c -@@ -262,42 +262,26 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - We may get multiple responses due to network condition, so check here - and quit early. */ - if (*data->addresses) -- { -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -- } -+ goto out; - - head = (struct dns_header *) nb->data; - ptr = (grub_uint8_t *) (head + 1); - if (ptr >= nb->tail) -- { -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -- } -- -+ goto out; -+ - if (head->id != data->id) -- { -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -- } -+ goto out; - if (!(head->flags & FLAGS_RESPONSE) || (head->flags & FLAGS_OPCODE)) -- { -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -- } -+ goto out; - if (head->ra_z_r_code & ERRCODE_MASK) - { - data->dns_err = 1; -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -+ goto out; - } - for (i = 0; i < grub_be_to_cpu16 (head->qdcount); i++) - { - if (ptr >= nb->tail) -- { -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -- } -+ goto out; - while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0)) - ptr += *ptr + 1; - if (ptr < nb->tail && (*ptr & 0xc0)) -@@ -310,8 +294,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - if (!*data->addresses) - { - grub_errno = GRUB_ERR_NONE; -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -+ goto out; - } - reparse_ptr = ptr; - reparse: -@@ -325,7 +308,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - { - if (!*data->naddresses) - grub_free (*data->addresses); -- return GRUB_ERR_NONE; -+ goto out; - } - ignored = !check_name (ptr, nb->data, nb->tail, data->name); - while (ptr < nb->tail && !((*ptr & 0xc0) || *ptr == 0)) -@@ -337,8 +320,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - { - if (!*data->naddresses) - grub_free (*data->addresses); -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -+ goto out; - } - if (*ptr++ != 0) - ignored = 1; -@@ -358,8 +340,7 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - { - if (!*data->naddresses) - grub_free (*data->addresses); -- grub_netbuff_free (nb); -- return GRUB_ERR_NONE; -+ goto out; - } - if (!ignored) - { -@@ -400,15 +381,14 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - if (!data->name) - { - data->dns_err = 1; -- grub_errno = 0; -- return GRUB_ERR_NONE; -+ grub_errno = GRUB_ERR_NONE; -+ goto out; - } - grub_dprintf ("dns", "CNAME %s\n", data->name); - if (grub_strcmp (redirect_save, data->name) == 0) - { - data->dns_err = 1; -- grub_free (redirect_save); -- return GRUB_ERR_NONE; -+ goto out; - } - goto reparse; - } -@@ -440,6 +420,8 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)), - *data->naddresses - * sizeof (dns_cache[h].addresses[0])); - } -+ -+ out: - grub_netbuff_free (nb); - grub_free (redirect_save); - return GRUB_ERR_NONE; --- -2.19.1 - diff --git a/backport-net-http-Do-not-tear-down-socket-if-its-already.patch b/backport-net-http-Do-not-tear-down-socket-if-its-already.patch deleted file mode 100644 index bae7cc5..0000000 --- a/backport-net-http-Do-not-tear-down-socket-if-its-already.patch +++ /dev/null @@ -1,46 +0,0 @@ -From dad94fffe14be476df5f34a8e5a90ea62a41fe12 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 1 Mar 2022 23:14:15 +1100 -Subject: net/http: Do not tear down socket if it's already been torn down - -It's possible for data->sock to get torn down in tcp error handling. -If we unconditionally tear it down again we will end up doing writes -to an offset of the NULL pointer when we go to tear it down again. - -Detect if it has been torn down and don't do it again. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=dad94fffe14be476df5f34a8e5a90ea62a41fe12 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/http.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index 8d6c62c..f8d7bf0 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -445,7 +445,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - return err; - } - -- for (i = 0; !data->headers_recv && i < 100; i++) -+ for (i = 0; data->sock && !data->headers_recv && i < 100; i++) - { - grub_net_tcp_retransmit (); - grub_net_poll_cards (300, &data->headers_recv); -@@ -453,7 +453,8 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - - if (!data->headers_recv) - { -- grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); -+ if (data->sock) -+ grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - if (data->err) - { - char *str = data->errmsg; --- -cgit v1.1 - diff --git a/backport-net-http-Error-out-on-headers-with-LF-without-CR.patch b/backport-net-http-Error-out-on-headers-with-LF-without-CR.patch deleted file mode 100644 index 15fee8a..0000000 --- a/backport-net-http-Error-out-on-headers-with-LF-without-CR.patch +++ /dev/null @@ -1,53 +0,0 @@ -From b26b4c08e7119281ff30d0fb4a6169bd2afa8fe4 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 8 Mar 2022 19:04:40 +1100 -Subject: net/http: Error out on headers with LF without CR - -In a similar vein to the previous patch, parse_line() would write -a NUL byte past the end of the buffer if there was an HTTP header -with a LF rather than a CRLF. - -RFC-2616 says: - - Many HTTP/1.1 header field values consist of words separated by LWS - or special characters. These special characters MUST be in a quoted - string to be used within a parameter value (as defined in section 3.6). - -We don't support quoted sections or continuation lines, etc. - -If we see an LF that's not part of a CRLF, bail out. - -Fixes: CVE-2022-28734 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=b26b4c08e7119281ff30d0fb4a6169bd2afa8fe4 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/http.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index 33a0a28..9291a13 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -68,7 +68,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) - char *end = ptr + len; - while (end > ptr && *(end - 1) == '\r') - end--; -+ -+ /* LF without CR. */ -+ if (end == ptr + len) -+ { -+ data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR")); -+ return GRUB_ERR_NONE; -+ } - *end = 0; -+ - /* Trailing CRLF. */ - if (data->in_chunk_len == 1) - { --- -cgit v1.1 - diff --git a/backport-net-http-Fix-OOB-write-for-split-http-headers.patch b/backport-net-http-Fix-OOB-write-for-split-http-headers.patch deleted file mode 100644 index d9c7ff8..0000000 --- a/backport-net-http-Fix-OOB-write-for-split-http-headers.patch +++ /dev/null @@ -1,51 +0,0 @@ -From ec6bfd3237394c1c7dbf2fd73417173318d22f4b Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 8 Mar 2022 18:17:03 +1100 -Subject: net/http: Fix OOB write for split http headers - -GRUB has special code for handling an http header that is split -across two packets. - -The code tracks the end of line by looking for a "\n" byte. The -code for split headers has always advanced the pointer just past the -end of the line, whereas the code that handles unsplit headers does -not advance the pointer. This extra advance causes the length to be -one greater, which breaks an assumption in parse_line(), leading to -it writing a NUL byte one byte past the end of the buffer where we -reconstruct the line from the two packets. - -It's conceivable that an attacker controlled set of packets could -cause this to zero out the first byte of the "next" pointer of the -grub_mm_region structure following the current_line buffer. - -Do not advance the pointer in the split header case. - -Fixes: CVE-2022-28734 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=ec6bfd3237394c1c7dbf2fd73417173318d22f4b -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/http.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index f8d7bf0..33a0a28 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -190,9 +190,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), - int have_line = 1; - char *t; - ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data); -- if (ptr) -- ptr++; -- else -+ if (ptr == NULL) - { - have_line = 0; - ptr = (char *) nb->tail; --- -cgit v1.1 - diff --git a/backport-net-ip-Do-IP-fragment-maths-safely.patch b/backport-net-ip-Do-IP-fragment-maths-safely.patch deleted file mode 100644 index a9367c5..0000000 --- a/backport-net-ip-Do-IP-fragment-maths-safely.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 3e4817538de828319ba6d59ced2fbb9b5ca13287 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 20 Dec 2021 19:41:21 +1100 -Subject: net/ip: Do IP fragment maths safely - -We can receive packets with invalid IP fragmentation information. This -can lead to rsm->total_len underflowing and becoming very large. - -Then, in grub_netbuff_alloc(), we add to this very large number, which can -cause it to overflow and wrap back around to a small positive number. -The allocation then succeeds, but the resulting buffer is too small and -subsequent operations can write past the end of the buffer. - -Catch the underflow here. - -Fixes: CVE-2022-28733 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=3e4817538de828319ba6d59ced2fbb9b5ca13287 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/ip.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c -index e3d62e9..3c3d0be 100644 ---- a/grub-core/net/ip.c -+++ b/grub-core/net/ip.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - - struct iphdr { -@@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, - { - rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) - + (nb->tail - nb->data)); -- rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t)); -+ -+ if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t), -+ &rsm->total_len)) -+ { -+ grub_dprintf ("net", "IP reassembly size underflow\n"); -+ return GRUB_ERR_NONE; -+ } -+ - rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len); - if (!rsm->asm_netbuff) - { --- -cgit v1.1 - diff --git a/backport-net-net-Fix-uninitialized-scalar-variable.patch b/backport-net-net-Fix-uninitialized-scalar-variable.patch deleted file mode 100644 index e1f2acf..0000000 --- a/backport-net-net-Fix-uninitialized-scalar-variable.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 8e9e0d4643020b340839b7f428f7b9ca6a2129d8 Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Mon, 21 Mar 2022 02:29:00 -0400 -Subject: net/net: Fix uninitialized scalar variable - -In the function grub_net_ipv6_get_link_local(), grub_net_network_level_address_t -addr is called but isn't being initialized. This results in the member -grub_dns_option_t option being filled with junk data from the stack. We can -prevent this by setting the option member in addr to 0. - -Fixes: CID 375033 - -Signed-off-by: Alec Brown -Reviewed-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=8e9e0d4643020b340839b7f428f7b9ca6a2129d8 - ---- - grub-core/net/net.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 11b3987..681f914 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -292,6 +292,7 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card, - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; - addr.ipv6[0] = grub_cpu_to_be64_compile_time (0xfe80ULL << 48); - addr.ipv6[1] = grub_net_ipv6_get_id (hwaddr); -+ addr.option = 0; - - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { --- -cgit v1.1 - diff --git a/backport-net-netbuff-Block-overly-large-netbuff-allocs.patch b/backport-net-netbuff-Block-overly-large-netbuff-allocs.patch deleted file mode 100644 index 54a644f..0000000 --- a/backport-net-netbuff-Block-overly-large-netbuff-allocs.patch +++ /dev/null @@ -1,58 +0,0 @@ -From f407e34f3871a4c402bbd516e7c28ea193cef1b7 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 8 Mar 2022 23:47:46 +1100 -Subject: net/netbuff: Block overly large netbuff allocs - -A netbuff shouldn't be too huge. It's bounded by MTU and TCP segment -reassembly. If we are asked to create one that is unreasonably big, refuse. - -This is a hardening measure: if we hit this code, there's a bug somewhere -else that we should catch and fix. - -This commit: - - stops the bug propagating any further. - - provides a spot to instrument in e.g. fuzzing to try to catch these bugs. - -I have put instrumentation (e.g. __builtin_trap() to force a crash) here and -have not been able to find any more crashes. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=f407e34f3871a4c402bbd516e7c28ea193cef1b7 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/netbuff.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c -index 72e5296..8da327b 100644 ---- a/grub-core/net/netbuff.c -+++ b/grub-core/net/netbuff.c -@@ -79,10 +79,23 @@ grub_netbuff_alloc (grub_size_t len) - - COMPILE_TIME_ASSERT (NETBUFF_ALIGN % sizeof (grub_properly_aligned_t) == 0); - -+ /* -+ * The largest size of a TCP packet is 64 KiB, and everything else -+ * should be a lot smaller - most MTUs are 1500 or less. Cap data -+ * size at 64 KiB + a buffer. -+ */ -+ if (len > 0xffffUL + 0x1000UL) -+ { -+ grub_error (GRUB_ERR_BUG, -+ "attempted to allocate a packet that is too big"); -+ return NULL; -+ } -+ - if (len < NETBUFFMINLEN) - len = NETBUFFMINLEN; - - len = ALIGN_UP (len, NETBUFF_ALIGN); -+ - #ifdef GRUB_MACHINE_EMU - data = grub_malloc (len + sizeof (*nb)); - #else --- -cgit v1.1 - diff --git a/backport-net-tftp-Avoid-a-trivial-UAF.patch b/backport-net-tftp-Avoid-a-trivial-UAF.patch deleted file mode 100644 index 9a303e9..0000000 --- a/backport-net-tftp-Avoid-a-trivial-UAF.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 8f287c3e13da2bf82049e2e464eca7ca4fef0a85 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 18 Jan 2022 14:29:20 +1100 -Subject: net/tftp: Avoid a trivial UAF - -Under tftp errors, we print a tftp error message from the tftp header. -However, the tftph pointer is a pointer inside nb, the netbuff. Previously, -we were freeing the nb and then dereferencing it. Don't do that, use it -and then free it later. - -This isn't really _bad_ per se, especially as we're single-threaded, but -it trips up fuzzers. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=8f287c3e13da2bf82049e2e464eca7ca4fef0a85 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/tftp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index ee305e1..7dbd305 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -251,9 +251,9 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), - return GRUB_ERR_NONE; - case TFTP_ERROR: - data->have_oack = 1; -- grub_netbuff_free (nb); - grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg); - grub_error_save (&data->save_err); -+ grub_netbuff_free (nb); - return GRUB_ERR_NONE; - default: - grub_netbuff_free (nb); --- -cgit v1.1 - diff --git a/backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch b/backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch deleted file mode 100644 index ea144ae..0000000 --- a/backport-net-tftp-Prevent-a-UAF-and-double-free-from.patch +++ /dev/null @@ -1,117 +0,0 @@ -From ee9652031491326736714a988fbbaeab8ef9255c Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 20 Sep 2021 01:12:24 +1000 -Subject: net/tftp: Prevent a UAF and double-free from a failed seek - -A malicious tftp server can cause UAFs and a double free. - -An attempt to read from a network file is handled by grub_net_fs_read(). If -the read is at an offset other than the current offset, grub_net_seek_real() -is invoked. - -In grub_net_seek_real(), if a backwards seek cannot be satisfied from the -currently received packets, and the underlying transport does not provide -a seek method, then grub_net_seek_real() will close and reopen the network -protocol layer. - -For tftp, the ->close() call goes to tftp_close() and frees the tftp_data_t -file->data. The file->data pointer is not nulled out after the free. - -If the ->open() call fails, the file->data will not be reallocated and will -continue point to a freed memory block. This could happen from a server -refusing to send the requisite ack to the new tftp request, for example. - -The seek and the read will then fail, but the grub_file continues to exist: -the failed seek does not necessarily cause the entire file to be thrown -away (e.g. where the file is checked to see if it is gzipped/lzio/xz/etc., -a read failure is interpreted as a decompressor passing on the file, not as -an invalidation of the entire grub_file_t structure). - -This means subsequent attempts to read or seek the file will use the old -file->data after free. Eventually, the file will be close()d again and -file->data will be freed again. - -Mark a net_fs file that doesn't reopen as broken. Do not permit read() or -close() on a broken file (seek is not exposed directly to the file API - -it is only called as part of read, so this blocks seeks as well). - -As an additional defence, null out the ->data pointer if tftp_open() fails. -That would have lead to a simple null pointer dereference rather than -a mess of UAFs. - -This may affect other protocols, I haven't checked. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=ee9652031491326736714a988fbbaeab8ef9255c -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/net/net.c | 11 +++++++++-- - grub-core/net/tftp.c | 1 + - include/grub/net.h | 1 + - 3 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 2b67715..9f09f8e 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -1521,7 +1521,8 @@ grub_net_fs_close (grub_file_t file) - grub_netbuff_free (file->device->net->packs.first->nb); - grub_net_remove_packet (file->device->net->packs.first); - } -- file->device->net->protocol->close (file); -+ if (!file->device->net->broken) -+ file->device->net->protocol->close (file); - grub_free (file->device->net->name); - return GRUB_ERR_NONE; - } -@@ -1744,7 +1745,10 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) - file->device->net->stall = 0; - err = file->device->net->protocol->open (file, file->device->net->name); - if (err) -- return err; -+ { -+ file->device->net->broken = 1; -+ return err; -+ } - grub_net_fs_read_real (file, NULL, offset); - return grub_errno; - } -@@ -1753,6 +1757,9 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) - static grub_ssize_t - grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) - { -+ if (file->device->net->broken) -+ return -1; -+ - if (file->offset != file->device->net->offset) - { - grub_err_t err; -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index ebbafe7..ee305e1 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -400,6 +400,7 @@ tftp_open (struct grub_file *file, const char *filename) - { - grub_net_udp_close (data->sock); - grub_free (data); -+ file->data = NULL; - return grub_errno; - } - -diff --git a/include/grub/net.h b/include/grub/net.h -index db21e79..a64a04c 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -276,6 +276,7 @@ typedef struct grub_net - grub_fs_t fs; - int eof; - int stall; -+ int broken; - } *grub_net_t; - - extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); --- -cgit v1.1 - diff --git a/backport-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch b/backport-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch deleted file mode 100644 index 7a4bf3c..0000000 --- a/backport-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 1514678888595ef41a968a0c69b7ff769edd1e9c Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 28 Oct 2022 21:31:39 +0800 -Subject: [PATCH 13/13] normal/charset: Fix an integer overflow in - grub_unicode_aglomerate_comb() - -The out->ncomb is a bit-field of 8 bits. So, the max possible value is 255. -However, code in grub_unicode_aglomerate_comb() doesn't check for an -overflow when incrementing out->ncomb. If out->ncomb is already 255, -after incrementing it will get 0 instead of 256, and cause illegal -memory access in subsequent processing. - -This patch introduces GRUB_UNICODE_NCOMB_MAX to represent the max -acceptable value of ncomb. The code now checks for this limit and -ignores additional combining characters when limit is reached. - -Reported-by: Daniel Axtens -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper ---- - grub-core/normal/charset.c | 3 +++ - include/grub/unicode.h | 2 ++ - 2 files changed, 5 insertions(+) - -diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c -index 000e687bd..4f6647116 100644 ---- a/grub-core/normal/charset.c -+++ b/grub-core/normal/charset.c -@@ -472,6 +472,9 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, - if (!haveout) - continue; - -+ if (out->ncomb == GRUB_UNICODE_NCOMB_MAX) -+ continue; -+ - if (comb_type == GRUB_UNICODE_COMB_MC - || comb_type == GRUB_UNICODE_COMB_ME - || comb_type == GRUB_UNICODE_COMB_MN) -diff --git a/include/grub/unicode.h b/include/grub/unicode.h -index 71a4d1a54..9360b0b97 100644 ---- a/include/grub/unicode.h -+++ b/include/grub/unicode.h -@@ -147,7 +147,9 @@ struct grub_unicode_glyph - grub_uint8_t bidi_level:6; /* minimum: 6 */ - enum grub_bidi_type bidi_type:5; /* minimum: :5 */ - -+#define GRUB_UNICODE_NCOMB_MAX ((1 << 8) - 1) - unsigned ncomb:8; -+ - /* Hint by unicode subsystem how wide this character usually is. - Real width is determined by font. Set only in UTF-8 stream. */ - int estimated_width:8; --- -2.27.0 - diff --git a/backport-normal-charset-Fix-array-out-of-bounds-formatting.patch b/backport-normal-charset-Fix-array-out-of-bounds-formatting.patch deleted file mode 100644 index 1f010c4..0000000 --- a/backport-normal-charset-Fix-array-out-of-bounds-formatting.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 830a9628b2c9e1b6388af624aaf4a80818ed6be0 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 13 Jul 2021 13:24:38 +1000 -Subject: normal/charset: Fix array out-of-bounds formatting unicode for - display - -In some cases attempting to display arbitrary binary strings leads -to ASAN splats reading the widthspec array out of bounds. - -Check the index. If it would be out of bounds, return a width of 1. -I don't know if that's strictly correct, but we're not really expecting -great display of arbitrary binary data, and it's certainly not worse than -an OOB read. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=830a9628b2c9e1b6388af624aaf4a80818ed6be0 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/normal/charset.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c -index 7778f1a..000e687 100644 ---- a/grub-core/normal/charset.c -+++ b/grub-core/normal/charset.c -@@ -395,6 +395,8 @@ grub_unicode_estimate_width (const struct grub_unicode_glyph *c) - { - if (grub_unicode_get_comb_type (c->base)) - return 0; -+ if (((unsigned long) (c->base >> 3)) >= ARRAY_SIZE (widthspec)) -+ return 1; - if (widthspec[c->base >> 3] & (1 << (c->base & 7))) - return 2; - else --- -cgit v1.1 - diff --git a/backport-normal-cmdline-Fix-two-related-integer-underflows.patch b/backport-normal-cmdline-Fix-two-related-integer-underflows.patch deleted file mode 100644 index f86b2b4..0000000 --- a/backport-normal-cmdline-Fix-two-related-integer-underflows.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 77afd25f8065bfbf5cc7848855006cd5260aeb9f Mon Sep 17 00:00:00 2001 -From: Ryan Cohen -Date: Sat, 26 Nov 2022 17:22:52 -0500 -Subject: [PATCH] normal/cmdline: Fix two related integer underflows - -An unchecked decrement operation in cl_print() would cause a few -integers to underflow. Where an output terminal's state is stored in -cl_term, the values cl_term->ystart and cl_term->pos.y both underflow. - -This can be replicated with the following steps: - -1. Get to the GRUB command line -2. Hold down the "d" key (or any key that enters a visible character) - until it fills the entire row -3. Press "HOME" and then press "CTRL-k". This will clear every - character entered in step 2 -4. Continuously press "CTRL-y" until the terminal scrolls the original - prompt ("grub> ") passed the terminal's top row. Now, no prompt - should be visible. This step causes cl_term->ystart to underflow -5. Press "HOME" and then "d" (or any visible character). This can have - different visual effects for different systems, but it will always - cause cl_term->pos.y to underflow - -On BIOS systems, these underflows cause the output terminal to -completely stop displaying anything. Characters can still be -entered and commands can be run, but nothing will display on the -terminal. From here, you can only get the display working by running -a command to switch the current output terminal to a different type: - -terminal_output - -On UEFI systems, these replication steps do not break the output -terminal. Until you press "ENTER", the cursor stops responding to input, -but you can press "ENTER" after step 5 and the command line will -work properly again. This patch is mostly important for BIOS systems -where the output terminal is rendered unusable after the underflows -occur. - -This patch adds two checks, one for each variable. It ensures that -cl_term->ystart does not decrement passed 0. It also ensures that -cl_term->pos.y does not get set passed the terminal's bottom row. - -When the previously listed replication steps are followed with this -patch, the terminal's cursor will be set to the top row and the command -line is still usable, even on BIOS systems. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=77afd25f8065bfbf5cc7848855006cd5260aeb9f -Conflict:NA - -Signed-off-by: Ryan Cohen -Reviewed-by: Daniel Kiper ---- - grub-core/normal/cmdline.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c -index 61f098244..9c6d9ade9 100644 ---- a/grub-core/normal/cmdline.c -+++ b/grub-core/normal/cmdline.c -@@ -219,6 +219,8 @@ cl_set_pos (struct cmdline_term *cl_term, grub_size_t lpos) - cl_term->pos.x = (cl_term->prompt_len + lpos) % cl_term->width; - cl_term->pos.y = cl_term->ystart - + (cl_term->prompt_len + lpos) / cl_term->width; -+ if (cl_term->pos.y >= cl_term->height) -+ cl_term->pos.y = cl_term->height - 1; - grub_term_gotoxy (cl_term->term, cl_term->pos); - } - -@@ -248,7 +250,10 @@ cl_print (struct cmdline_term *cl_term, grub_uint32_t c, - { - cl_term->pos.x = 0; - if (cl_term->pos.y >= (unsigned) (cl_term->height - 1)) -- cl_term->ystart--; -+ { -+ if (cl_term->ystart > 0) -+ cl_term->ystart--; -+ } - else - cl_term->pos.y++; - grub_putcode ('\n', cl_term->term); --- -2.28.0.windows.1 - diff --git a/backport-osdep-linux-Fix-md-array-device-enumeration.patch b/backport-osdep-linux-Fix-md-array-device-enumeration.patch deleted file mode 100644 index c833cb5..0000000 --- a/backport-osdep-linux-Fix-md-array-device-enumeration.patch +++ /dev/null @@ -1,91 +0,0 @@ -From c39f27cd678d61e8e84c1386695a33575c9ded44 Mon Sep 17 00:00:00 2001 -From: Kees Cook -Date: Thu, 7 Oct 2021 16:33:16 -0700 -Subject: osdep/linux: Fix md array device enumeration - -GET_ARRAY_INFO's info.nr_disks does not map to GET_DISK_INFO's -disk.number, which is an internal kernel index. If an array has had drives -added, removed, etc., there may be gaps in GET_DISK_INFO's results. But -since the consumer of devicelist cannot tolerate gaps (it expects to walk -a NULL-terminated list of device name strings), the devicelist index (j) -must be tracked separately from the disk.number index (i). - -As part of this, since GRUB wants to only examine active (i.e. present -and non-failed) disks, the count of remaining disks (remaining) must be -tracked separately from the devicelist index (j). - -Additionally, drop a line with empty spaces only. - -Fixes: 49de079bbe1c (... (grub_util_raid_getmembers): Handle "removed" disks) -Fixes: 2b00217369ac (... Added support for RAID and LVM) -Fixes: https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1912043 -Fixes: https://savannah.gnu.org/bugs/index.php?59887 - -Signed-off-by: Kees Cook -Reviewed-by: Petr Vorel -Reviewed-by: Daniel Kiper - -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=c39f27cd678d61e8e84c1386695a33575c9ded44 - ---- - grub-core/osdep/linux/getroot.c | 24 +++++++++++++++++------- - 1 file changed, 17 insertions(+), 7 deletions(-) - -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index cd58858..df422c6 100644 ---- a/grub-core/osdep/linux/getroot.c -+++ b/grub-core/osdep/linux/getroot.c -@@ -130,10 +130,20 @@ struct mountinfo_entry - char fstype[ESCAPED_PATH_MAX + 1], device[ESCAPED_PATH_MAX + 1]; - }; - -+/* -+ * GET_DISK_INFO nr_disks (total count) does not map to disk.number, -+ * which is an internal kernel index. Instead, do what mdadm does -+ * and keep scanning until we find enough valid disks. The limit is -+ * copied from there, which notes that it is sufficiently high given -+ * that the on-disk metadata for v1.x can only support 1920. -+ */ -+#define MD_MAX_DISKS 4096 -+ - static char ** - grub_util_raid_getmembers (const char *name, int bootable) - { - int fd, ret, i, j; -+ int remaining; - char **devicelist; - mdu_version_t version; - mdu_array_info_t info; -@@ -165,22 +175,22 @@ grub_util_raid_getmembers (const char *name, int bootable) - - devicelist = xcalloc (info.nr_disks + 1, sizeof (char *)); - -- for (i = 0, j = 0; j < info.nr_disks; i++) -+ remaining = info.nr_disks; -+ for (i = 0, j = 0; i < MD_MAX_DISKS && remaining > 0; i++) - { - disk.number = i; - ret = ioctl (fd, GET_DISK_INFO, &disk); - if (ret != 0) - grub_util_error (_("ioctl GET_DISK_INFO error: %s"), strerror (errno)); -- -+ -+ /* Skip: MD_DISK_REMOVED slots don't contribute to "remaining" count. */ - if (disk.state & (1 << MD_DISK_REMOVED)) - continue; -+ remaining--; - -+ /* Only record disks that are actively participating in the array. */ - if (disk.state & (1 << MD_DISK_ACTIVE)) -- devicelist[j] = grub_find_device (NULL, -- makedev (disk.major, disk.minor)); -- else -- devicelist[j] = NULL; -- j++; -+ devicelist[j++] = grub_find_device (NULL, makedev (disk.major, disk.minor)); - } - - devicelist[j] = NULL; --- -cgit v1.1 diff --git a/backport-osdep-linux-hostdisk-Modify-sector-by-sysfs-as-disk-sector.patch b/backport-osdep-linux-hostdisk-Modify-sector-by-sysfs-as-disk-sector.patch deleted file mode 100644 index a6c696c..0000000 --- a/backport-osdep-linux-hostdisk-Modify-sector-by-sysfs-as-disk-sector.patch +++ /dev/null @@ -1,75 +0,0 @@ -From f7564844f82b57078d601befadc438b5bc1fa01b Mon Sep 17 00:00:00 2001 -From: Mukesh Kumar Chaurasiya -Date: Thu, 9 Feb 2023 13:09:16 +0530 -Subject: osdep/linux/hostdisk: Modify sector by sysfs as disk sector - -The disk sector size provided by sysfs file system considers the sector -size of 512 irrespective of disk sector size, thus causing the read by -the GRUB to an incorrect offset from what was originally intended. - -Considering the 512 sector size of sysfs data the actual sector needs to -be modified corresponding to disk sector size. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=f7564844f82b57078d601befadc438b5bc1fa01b -Conflict:NA - -Signed-off-by: Mukesh Kumar Chaurasiya -Reviewed-by: Daniel Kiper ---- - grub-core/osdep/linux/hostdisk.c | 7 ++++--- - include/grub/disk.h | 7 +++++++ - 2 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c -index 07058f6..7e24ae6 100644 ---- a/grub-core/osdep/linux/hostdisk.c -+++ b/grub-core/osdep/linux/hostdisk.c -@@ -198,7 +198,8 @@ have_devfs (void) - #pragma GCC diagnostic ignored "-Wformat-nonliteral" - - static int --grub_hostdisk_linux_find_partition (char *dev, grub_disk_addr_t sector) -+grub_hostdisk_linux_find_partition (const grub_disk_t disk, char *dev, -+ grub_disk_addr_t sector) - { - size_t len = strlen (dev); - const char *format; -@@ -263,7 +264,7 @@ grub_hostdisk_linux_find_partition (char *dev, grub_disk_addr_t sector) - if (fstat (fd, &st) < 0 - || !grub_util_device_is_mapped_stat (&st) - || !grub_util_get_dm_node_linear_info (st.st_rdev, 0, 0, &start)) -- start = grub_util_find_partition_start_os (real_dev); -+ start = grub_disk_to_native_sector (disk, grub_util_find_partition_start_os (real_dev)); - /* We don't care about errors here. */ - grub_errno = GRUB_ERR_NONE; - -@@ -344,7 +345,7 @@ grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int f - && strncmp (dev, "/dev/", 5) == 0) - { - if (sector >= part_start) -- is_partition = grub_hostdisk_linux_find_partition (dev, part_start); -+ is_partition = grub_hostdisk_linux_find_partition (disk, dev, part_start); - else - *max = part_start - sector; - } -diff --git a/include/grub/disk.h b/include/grub/disk.h -index 25c141e..071b2f7 100644 ---- a/include/grub/disk.h -+++ b/include/grub/disk.h -@@ -208,6 +208,13 @@ grub_disk_from_native_sector (grub_disk_t disk, grub_disk_addr_t sector) - return sector << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); - } - -+/* Convert from GRUB native disk sized sector to disk sized sector. */ -+static inline grub_disk_addr_t -+grub_disk_to_native_sector (grub_disk_t disk, grub_disk_addr_t sector) -+{ -+ return sector >> (disk->log_sector_size - GRUB_DISK_SECTOR_BITS); -+} -+ - /* This is called from the memory manager. */ - void grub_disk_cache_invalidate_all (void); - --- -cgit v1.1 - diff --git a/backport-term-i386-pc-vga_text-Prevent-out-of-bounds-writes-t.patch b/backport-term-i386-pc-vga_text-Prevent-out-of-bounds-writes-t.patch deleted file mode 100644 index 93b53f9..0000000 --- a/backport-term-i386-pc-vga_text-Prevent-out-of-bounds-writes-t.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 108a3865f43330b581d35b9cf6ecb1e0a1da5d49 Mon Sep 17 00:00:00 2001 -From: Ryan Cohen -Date: Sat, 26 Nov 2022 17:22:51 -0500 -Subject: [PATCH] term/i386/pc/vga_text: Prevent out-of-bounds writes to VGA - text buffer - -Coordinates passed to screen_write_char() did not have any checks to -ensure they are not out-of-bounds. This adds an if statement to prevent -out-of-bounds writes to the VGA text buffer. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=108a3865f43330b581d35b9cf6ecb1e0a1da5d49 -Conflict:NA - -Signed-off-by: Ryan Cohen -Reviewed-by: Daniel Kiper ---- - grub-core/term/i386/pc/vga_text.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c -index 669d06fad..b88fa9d2e 100644 ---- a/grub-core/term/i386/pc/vga_text.c -+++ b/grub-core/term/i386/pc/vga_text.c -@@ -63,7 +63,8 @@ static grub_uint8_t cur_color = 0x7; - static void - screen_write_char (int x, int y, short c) - { -- VGA_TEXT_SCREEN[y * COLS + x] = grub_cpu_to_le16 (c); -+ if (x < COLS && y < ROWS && x >= 0 && y >= 0) -+ VGA_TEXT_SCREEN[y * COLS + x] = grub_cpu_to_le16 (c); - } - - static short --- -2.28.0.windows.1 - diff --git a/backport-tests-Disable-blkid-cache-usage.patch b/backport-tests-Disable-blkid-cache-usage.patch deleted file mode 100644 index 6765b3b..0000000 --- a/backport-tests-Disable-blkid-cache-usage.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 8cdf18bb505a6920b59384e222005b0ec2b4211f Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Sat, 9 Apr 2022 02:44:46 +0000 -Subject: [PATCH] tests: Disable blkid cache usage - -Using the blkid cache can cause issues when running many file system tests -in parallel. We do not need it, as its only there to improve performance, -and using the cache does not provide significant performance improvements. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=e883cc6a282891783902daf2d564a5b5c7a6a5aa -Conflict:NA - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper - ---- - tests/util/grub-fs-tester.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in -index bfc425e..e6a493c 100644 ---- a/tests/util/grub-fs-tester.in -+++ b/tests/util/grub-fs-tester.in -@@ -1,6 +1,7 @@ - #!@BUILD_SHEBANG@ - - set -e -+export BLKID_FILE=/dev/null - - fs="$1" - --- -2.27.0 - diff --git a/backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch b/backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch deleted file mode 100644 index 1019dda..0000000 --- a/backport-util-grub-fstest-Fix-resource-leaks-in-cmd_cmp.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 53f08de12bfdd10207a8e6a062c9778f5ab6df87 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 26 Oct 2021 15:02:37 +0000 -Subject: util/grub-fstest: Fix resource leaks in cmd_cmp() - -In the function cmd_cmp() within the while loop, srcnew and destnew are -being allocated but are never freed either before leaving scope or in -the recursive calls being made to cmd_cmp(). - -Fixes: CID 314032 -Fixes: CID 314045 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=53f08de12bfdd10207a8e6a062c9778f5ab6df87 - ---- - util/grub-fstest.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/util/grub-fstest.c b/util/grub-fstest.c -index 8386564..486f1dc 100644 ---- a/util/grub-fstest.c -+++ b/util/grub-fstest.c -@@ -300,9 +300,15 @@ cmd_cmp (char *src, char *dest) - strcpy (ptr, entry->d_name); - - if (grub_util_is_special_file (destnew)) -- continue; -+ { -+ free (srcnew); -+ free (destnew); -+ continue; -+ } - - cmd_cmp (srcnew, destnew); -+ free (srcnew); -+ free (destnew); - } - grub_util_fd_closedir (dir); - return; --- -cgit v1.1 diff --git a/backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch b/backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch deleted file mode 100644 index b73aa5d..0000000 --- a/backport-util-grub-install-common-Fix-memory-leak-in-copy_all.patch +++ /dev/null @@ -1,38 +0,0 @@ -From e07fcea291ac8aa430db6e57d6e8e08894127fe2 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 26 Oct 2021 15:02:35 +0000 -Subject: util/grub-install-common: Fix memory leak in copy_all() - -The copy_all() function skips a section of code using continue, but -fails to free the memory in srcf first, leaking it. - -Fixes: CID 314026 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=e07fcea291ac8aa430db6e57d6e8e08894127fe2 - ---- - util/grub-install-common.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index 4e212e6..fe77e39 100644 ---- a/util/grub-install-common.c -+++ b/util/grub-install-common.c -@@ -754,7 +754,10 @@ copy_all (const char *srcd, - srcf = grub_util_path_concat (2, srcd, de->d_name); - if (grub_util_is_special_file (srcf) - || grub_util_is_directory (srcf)) -- continue; -+ { -+ free (srcf); -+ continue; -+ } - dstf = grub_util_path_concat (2, dstd, de->d_name); - grub_install_compress_file (srcf, dstf, 1); - free (srcf); --- -cgit v1.1 diff --git a/backport-util-grub-install-common-Fix-the-key-of.patch b/backport-util-grub-install-common-Fix-the-key-of.patch deleted file mode 100644 index b250a97..0000000 --- a/backport-util-grub-install-common-Fix-the-key-of.patch +++ /dev/null @@ -1,43 +0,0 @@ -From a6eba8f1276e58d94b4134b2488768349c8f37dc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?=C3=81kos=20Nagy?= -Date: Fri, 5 May 2023 14:04:28 +0200 -Subject: util/grub-install-common: Fix the key of the --core-compress option -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit f23bc6510 (Transform -C option to grub-mkstandalone to ---core-compress available in all grub-install flavours.) declared -a new long option for specifying the compression method to use for -the core image. - -However, the option key has not been replaced in the parser function, -it still expects the old one formerly used by grub-mkstandalone. -Because of this the option is not recognized by any of the utils for -which it is listed as supported. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=a6eba8f1276e58d94b4134b2488768349c8f37dc -Conflict:NA - -Signed-off-by: Ákos Nagy -Reviewed-by: Daniel Kiper ---- - util/grub-install-common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index 57ac445..52a29d1 100644 ---- a/util/grub-install-common.c -+++ b/util/grub-install-common.c -@@ -472,7 +472,7 @@ grub_install_parse (int key, char *arg) - const char *end; - switch (key) - { -- case 'C': -+ case GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS: - if (grub_strcmp (arg, "xz") == 0) - { - #ifdef HAVE_LIBLZMA --- -cgit v1.1 - diff --git a/backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch b/backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch deleted file mode 100644 index 8af7f93..0000000 --- a/backport-util-grub-mkfont-Fix-memory-leak-in-write_font_pf2.patch +++ /dev/null @@ -1,35 +0,0 @@ -From b1fae9c1ba1f3ba4c9b4d39ad6eaedf9d77af7ed Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 26 Oct 2021 15:02:38 +0000 -Subject: util/grub-mkfont: Fix memory leak in write_font_pf2() - -In the function write_font_pf2() memory is allocated for font_name to -construct a new name, but it is not released before returning from the -function, leaking the allocated memory. - -Fixes: CID 314015 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=b1fae9c1ba1f3ba4c9b4d39ad6eaedf9d77af7ed - ---- - util/grub-mkfont.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c -index 0fe45a6..fdfd70d 100644 ---- a/util/grub-mkfont.c -+++ b/util/grub-mkfont.c -@@ -928,6 +928,7 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) - file, output_file); - } - -+ free (font_name); - fclose (file); - } - --- -cgit v1.1 diff --git a/backport-util-grub-mkfont-Fix-resource-leaks.patch b/backport-util-grub-mkfont-Fix-resource-leaks.patch deleted file mode 100644 index a5a2d62..0000000 --- a/backport-util-grub-mkfont-Fix-resource-leaks.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 78baa77c01f88662d980be38250344f7379b6655 Mon Sep 17 00:00:00 2001 -From: Qiumiao Zhang -Date: Mon, 1 Aug 2022 16:31:02 +0800 -Subject: util/grub-mkfont: Fix resource leaks - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=78baa77c01f88662d980be38250344f7379b6655 -Conflict:NA - -Signed-off-by: Qiumiao Zhang -Reviewed-by: Daniel Kiper ---- - util/grub-mkfont.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c -index bb6982d..f63890c 100644 ---- a/util/grub-mkfont.c -+++ b/util/grub-mkfont.c -@@ -656,6 +656,7 @@ add_font (struct grub_font_info *font_info, FT_Face face, int nocut) - } - } - } -+ free (gsub); - } - - if (font_info->num_range) -@@ -1279,11 +1280,15 @@ main (int argc, char *argv[]) - if (font_verbosity > 1) - print_glyphs (&arguments.font_info); - -+ free (arguments.font_info.glyphs_sorted); -+ - { - size_t i; - for (i = 0; i < arguments.nfiles; i++) - free (arguments.files[i]); - } - -+ free (arguments.files); -+ - return 0; - } --- -2.19.1 - diff --git a/backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch b/backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch deleted file mode 100644 index 84094e8..0000000 --- a/backport-util-grub-mkrescue-Fix-memory-leak-in-write_part.patch +++ /dev/null @@ -1,34 +0,0 @@ -From eff17a6b2d563fe9a0917e048776ed9ce2da4b80 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 26 Oct 2021 15:02:36 +0000 -Subject: util/grub-mkrescue: Fix memory leak in write_part() - -In the function write_part(), the value of inname is not used beyond -the grub_util_fopen() call, so it should be freed to avoid leakage. - -Fixes: CID 314028 - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper - -Conflict: NA -Reference: https://git.savannah.gnu.org/cgit/grub.git/commit?id=eff17a6b2d563fe9a0917e048776ed9ce2da4b80 - ---- - util/grub-mkrescue.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c -index fb4dcc6..59c48b1 100644 ---- a/util/grub-mkrescue.c -+++ b/util/grub-mkrescue.c -@@ -229,6 +229,7 @@ write_part (FILE *f, const char *srcdir) - char *inname = grub_util_path_concat (2, srcdir, "partmap.lst"); - char buf[260]; - in = grub_util_fopen (inname, "rb"); -+ free (inname); - if (!in) - return; - while (fgets (buf, 256, in)) --- -cgit v1.1 diff --git a/backport-util-grub-mount-Fix-memory-leak-in-fuse_getattr.patch b/backport-util-grub-mount-Fix-memory-leak-in-fuse_getattr.patch deleted file mode 100644 index d92e820..0000000 --- a/backport-util-grub-mount-Fix-memory-leak-in-fuse_getattr.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 3077b39baef99afe534b582b9024bba877786e40 Mon Sep 17 00:00:00 2001 -From: Qiumiao Zhang -Date: Tue, 25 Jul 2023 11:18:59 +0800 -Subject: util/grub-mount: Fix memory leak in fuse_getattr() - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=3077b39baef99afe534b582b9024bba877786e40 -Conflict:NA - -Signed-off-by: Qiumiao Zhang -Reviewed-by: Daniel Kiper ---- - util/grub-mount.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/util/grub-mount.c b/util/grub-mount.c -index 1c35b6a..c69889d 100644 ---- a/util/grub-mount.c -+++ b/util/grub-mount.c -@@ -198,6 +198,7 @@ fuse_getattr (const char *path, struct stat *st, - (fs->fs_dir) (dev, path2, fuse_getattr_find_file, &ctx); - - grub_free (path2); -+ free (pathname); - if (!ctx.file_exists) - { - grub_errno = GRUB_ERR_NONE; --- -cgit v1.1 - diff --git a/backport-util-resolve-Do-not-read-past-the-end-of-the-array-in-read_dep_list.patch b/backport-util-resolve-Do-not-read-past-the-end-of-the-array-in-read_dep_list.patch deleted file mode 100644 index 57c292b..0000000 --- a/backport-util-resolve-Do-not-read-past-the-end-of-the-array-in-read_dep_list.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ddf47bdb042ab0ea52bc713b5f80cc48543f0469 Mon Sep 17 00:00:00 2001 -From: Glenn Washburn -Date: Wed, 12 Jan 2022 20:55:00 -0600 -Subject: util/resolve: Do not read past the end of the array in - read_dep_list() - -If the last non-NULL byte of "buf" is not a white-space character (such as -when a read line is longer than the size of "buf"), then "p" will eventually -point to the byte after the last byte in "buf". After which "p" will be -dereferenced in the while conditional leading to an out of bounds read. Make -sure that "p" is inside "buf" before dereferencing it. - -Signed-off-by: Glenn Washburn -Reviewed-by: Daniel Kiper - -Conflict:NA -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit?id=ddf47bdb042ab0ea52bc713b5f80cc48543f0469 - ---- - util/resolve.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/resolve.c b/util/resolve.c -index 3e887d2..5e9afa1 100644 ---- a/util/resolve.c -+++ b/util/resolve.c -@@ -102,7 +102,7 @@ read_dep_list (FILE *fp) - dep_list = dep; - - /* Add dependencies. */ -- while (*p) -+ while (p < (buf + sizeof (buf)) && *p) - { - struct mod_list *mod; - char *name; --- -cgit v1.1 - diff --git a/backport-video-readers-Add-artificial-limit-to-image-dimensio.patch b/backport-video-readers-Add-artificial-limit-to-image-dimensio.patch deleted file mode 100644 index 6fe4e5a..0000000 --- a/backport-video-readers-Add-artificial-limit-to-image-dimensio.patch +++ /dev/null @@ -1,109 +0,0 @@ -From a85714545fe57a86d14ee231a4cd312158101d43 Mon Sep 17 00:00:00 2001 -From: Alec Brown -Date: Wed, 26 Oct 2022 20:16:44 -0400 -Subject: [PATCH] video/readers: Add artificial limit to image dimensions - -In grub-core/video/readers/jpeg.c, the height and width of a JPEG image don't -have an upper limit for how big the JPEG image can be. In Coverity, this is -getting flagged as an untrusted loop bound. This issue can also seen in PNG and -TGA format images as well but Coverity isn't flagging it. To prevent this, the -constant IMAGE_HW_MAX_PX is being added to include/grub/bitmap.h, which has -a value of 16384, to act as an artificial limit and restrict the height and -width of images. This value was picked as it is double the current max -resolution size, which is 8K. - -Fixes: CID 292450 - -Signed-off-by: Alec Brown -Reviewed-by: Darren Kenny -Reviewed-by: Daniel Kiper ---- - docs/grub.texi | 3 ++- - grub-core/video/readers/jpeg.c | 6 +++++- - grub-core/video/readers/png.c | 6 +++++- - grub-core/video/readers/tga.c | 7 +++++++ - include/grub/bitmap.h | 2 ++ - 5 files changed, 21 insertions(+), 3 deletions(-) - -diff --git a/docs/grub.texi b/docs/grub.texi -index 0dbbdc374..2d6cd8358 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -1515,7 +1515,8 @@ resolution. @xref{gfxmode}. - Set a background image for use with the @samp{gfxterm} graphical terminal. - The value of this option must be a file readable by GRUB at boot time, and - it must end with @file{.png}, @file{.tga}, @file{.jpg}, or @file{.jpeg}. --The image will be scaled if necessary to fit the screen. -+The image will be scaled if necessary to fit the screen. Image height and -+width will be restricted by an artificial limit of 16384. - - @item GRUB_THEME - Set a theme for use with the @samp{gfxterm} graphical terminal. -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 09596fbf5..ae634fd41 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -346,7 +346,11 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) - data->image_height = grub_jpeg_get_word (data); - data->image_width = grub_jpeg_get_word (data); - -- if ((!data->image_height) || (!data->image_width)) -+ grub_dprintf ("jpeg", "image height: %d\n", data->image_height); -+ grub_dprintf ("jpeg", "image width: %d\n", data->image_width); -+ -+ if ((!data->image_height) || (!data->image_width) || -+ (data->image_height > IMAGE_HW_MAX_PX) || (data->image_width > IMAGE_HW_MAX_PX)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid image size"); - - cc = grub_jpeg_get_byte (data); -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index 7f2ba7849..3163e97bf 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -264,7 +264,11 @@ grub_png_decode_image_header (struct grub_png_data *data) - data->image_width = grub_png_get_dword (data); - data->image_height = grub_png_get_dword (data); - -- if ((!data->image_height) || (!data->image_width)) -+ grub_dprintf ("png", "image height: %d\n", data->image_height); -+ grub_dprintf ("png", "image width: %d\n", data->image_width); -+ -+ if ((!data->image_height) || (!data->image_width) || -+ (data->image_height > IMAGE_HW_MAX_PX) || (data->image_width > IMAGE_HW_MAX_PX)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size"); - - color_bits = grub_png_get_byte (data); -diff --git a/grub-core/video/readers/tga.c b/grub-core/video/readers/tga.c -index a9ec3a1b6..9c35bf29d 100644 ---- a/grub-core/video/readers/tga.c -+++ b/grub-core/video/readers/tga.c -@@ -340,6 +340,13 @@ grub_video_reader_tga (struct grub_video_bitmap **bitmap, - data.image_width = grub_le_to_cpu16 (data.hdr.image_width); - data.image_height = grub_le_to_cpu16 (data.hdr.image_height); - -+ grub_dprintf ("tga", "image height: %d\n", data.image_height); -+ grub_dprintf ("tga", "image width: %d\n", data.image_width); -+ -+ /* Check image height and width are within restrictions. */ -+ if ((data.image_height > IMAGE_HW_MAX_PX) || (data.image_width > IMAGE_HW_MAX_PX)) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "tga: invalid image size"); -+ - /* Check that bitmap encoding is supported. */ - switch (data.hdr.image_type) - { -diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h -index 5728f8ca3..149d37bfe 100644 ---- a/include/grub/bitmap.h -+++ b/include/grub/bitmap.h -@@ -24,6 +24,8 @@ - #include - #include - -+#define IMAGE_HW_MAX_PX 16384 -+ - struct grub_video_bitmap - { - /* Bitmap format description. */ --- -2.27.0 - diff --git a/backport-video-readers-jpeg-Abort-sooner-if-a-read.patch b/backport-video-readers-jpeg-Abort-sooner-if-a-read.patch deleted file mode 100644 index 501d56f..0000000 --- a/backport-video-readers-jpeg-Abort-sooner-if-a-read.patch +++ /dev/null @@ -1,260 +0,0 @@ -From d5caac8ab79d068ad9a41030c772d03a4d4fbd7b Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 28 Jun 2021 14:16:14 +1000 -Subject: video/readers/jpeg: Abort sooner if a read operation fails - -Fuzzing revealed some inputs that were taking a long time, potentially -forever, because they did not bail quickly upon encountering an I/O error. - -Try to catch I/O errors sooner and bail out. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=d5caac8ab79d068ad9a41030c772d03a4d4fbd7b -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/jpeg.c | 86 ++++++++++++++++++++++++++++++++++-------- - 1 file changed, 70 insertions(+), 16 deletions(-) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index c47ffd6..806c56c 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -109,9 +109,17 @@ static grub_uint8_t - grub_jpeg_get_byte (struct grub_jpeg_data *data) - { - grub_uint8_t r; -+ grub_ssize_t bytes_read; - - r = 0; -- grub_file_read (data->file, &r, 1); -+ bytes_read = grub_file_read (data->file, &r, 1); -+ -+ if (bytes_read != 1) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: unexpected end of data"); -+ return 0; -+ } - - return r; - } -@@ -120,9 +128,17 @@ static grub_uint16_t - grub_jpeg_get_word (struct grub_jpeg_data *data) - { - grub_uint16_t r; -+ grub_ssize_t bytes_read; - - r = 0; -- grub_file_read (data->file, &r, sizeof (grub_uint16_t)); -+ bytes_read = grub_file_read (data->file, &r, sizeof (grub_uint16_t)); -+ -+ if (bytes_read != sizeof (grub_uint16_t)) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: unexpected end of data"); -+ return 0; -+ } - - return grub_be_to_cpu16 (r); - } -@@ -135,6 +151,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data) - if (data->bit_mask == 0) - { - data->bit_save = grub_jpeg_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: file read error"); -+ return 0; -+ } - if (data->bit_save == JPEG_ESC_CHAR) - { - if (grub_jpeg_get_byte (data) != 0) -@@ -143,6 +164,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data) - "jpeg: invalid 0xFF in data stream"); - return 0; - } -+ if (grub_errno != GRUB_ERR_NONE) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: file read error"); -+ return 0; -+ } - } - data->bit_mask = 0x80; - } -@@ -161,7 +187,7 @@ grub_jpeg_get_number (struct grub_jpeg_data *data, int num) - return 0; - - msb = value = grub_jpeg_get_bit (data); -- for (i = 1; i < num; i++) -+ for (i = 1; i < num && grub_errno == GRUB_ERR_NONE; i++) - value = (value << 1) + (grub_jpeg_get_bit (data) != 0); - if (!msb) - value += 1 - (1 << num); -@@ -208,6 +234,8 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) - while (data->file->offset + sizeof (count) + 1 <= next_marker) - { - id = grub_jpeg_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - ac = (id >> 4) & 1; - id &= 0xF; - if (id > 1) -@@ -258,6 +286,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) - - next_marker = data->file->offset; - next_marker += grub_jpeg_get_word (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if (next_marker > data->file->size) - { -@@ -269,6 +299,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) - <= next_marker) - { - id = grub_jpeg_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - if (id >= 0x10) /* Upper 4-bit is precision. */ - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: only 8-bit precision is supported"); -@@ -300,6 +332,9 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) - next_marker = data->file->offset; - next_marker += grub_jpeg_get_word (data); - -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ - if (grub_jpeg_get_byte (data) != 8) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: only 8-bit precision is supported"); -@@ -325,6 +360,8 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index"); - - ss = grub_jpeg_get_byte (data); /* Sampling factor. */ -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - if (!id) - { - grub_uint8_t vs, hs; -@@ -504,7 +541,7 @@ grub_jpeg_idct_transform (jpeg_data_unit_t du) - } - } - --static void -+static grub_err_t - grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - { - int h1, h2, qt; -@@ -519,6 +556,9 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - data->dc_value[id] += - grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1)); - -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ - du[0] = data->dc_value[id] * (int) data->quan_table[qt][0]; - pos = 1; - while (pos < ARRAY_SIZE (data->quan_table[qt])) -@@ -533,11 +573,13 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - num >>= 4; - pos += num; - -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ - if (pos >= ARRAY_SIZE (jpeg_zigzag_order)) - { -- grub_error (GRUB_ERR_BAD_FILE_TYPE, -- "jpeg: invalid position in zigzag order!?"); -- return; -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: invalid position in zigzag order!?"); - } - - du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos]; -@@ -545,6 +587,7 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - } - - grub_jpeg_idct_transform (du); -+ return GRUB_ERR_NONE; - } - - static void -@@ -603,7 +646,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - data_offset += grub_jpeg_get_word (data); - - cc = grub_jpeg_get_byte (data); -- -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - if (cc != 3 && cc != 1) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: component count must be 1 or 3"); -@@ -616,7 +660,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - id = grub_jpeg_get_byte (data) - 1; - if ((id < 0) || (id >= 3)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index"); -- -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - ht = grub_jpeg_get_byte (data); - data->comp_index[id][1] = (ht >> 4); - data->comp_index[id][2] = (ht & 0xF) + 2; -@@ -624,11 +669,14 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - if ((data->comp_index[id][1] < 0) || (data->comp_index[id][1] > 3) || - (data->comp_index[id][2] < 0) || (data->comp_index[id][2] > 3)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid hufftable index"); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - } - - grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */ - grub_jpeg_get_word (data); -- -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - if (data->file->offset != data_offset) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos"); - -@@ -646,6 +694,7 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - { - unsigned c1, vb, hb, nr1, nc1; - int rst = data->dri; -+ grub_err_t err = GRUB_ERR_NONE; - - vb = 8 << data->log_vs; - hb = 8 << data->log_hs; -@@ -666,17 +715,22 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - - for (r2 = 0; r2 < (1U << data->log_vs); r2++) - for (c2 = 0; c2 < (1U << data->log_hs); c2++) -- grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]); -+ { -+ err = grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ } - - if (data->color_components >= 3) - { -- grub_jpeg_decode_du (data, 1, data->cbdu); -- grub_jpeg_decode_du (data, 2, data->crdu); -+ err = grub_jpeg_decode_du (data, 1, data->cbdu); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ err = grub_jpeg_decode_du (data, 2, data->crdu); -+ if (err != GRUB_ERR_NONE) -+ return err; - } - -- if (grub_errno) -- return grub_errno; -- - nr2 = (data->r1 == nr1 - 1) ? (data->image_height - data->r1 * vb) : vb; - nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb; - --- -cgit v1.1 - diff --git a/backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch b/backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch deleted file mode 100644 index 6d260fe..0000000 --- a/backport-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 22a3f97d39f6a10b08ad7fd1cc47c4dcd10413f6 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 7 Jul 2021 15:38:19 +1000 -Subject: video/readers/jpeg: Block int underflow -> wild pointer write - -Certain 1 px wide images caused a wild pointer write in -grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(), -we have the following loop: - -for (; data->r1 < nr1 && (!data->dri || rst); - data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3) - -We did not check if vb * width >= hb * nc1. - -On a 64-bit platform, if that turns out to be negative, it will underflow, -be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so -we see data->bitmap_ptr jump, e.g.: - -0x6180_0000_0480 to -0x6181_0000_0498 - ^ - ~--- carry has occurred and this pointer is now far away from - any object. - -On a 32-bit platform, it will decrement the pointer, creating a pointer -that won't crash but will overwrite random data. - -Catch the underflow and error out. - -Fixes: CVE-2021-3697 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=22a3f97d39f6a10b08ad7fd1cc47c4dcd10413f6 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/jpeg.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 579bbe8..09596fb 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -699,6 +700,7 @@ static grub_err_t - grub_jpeg_decode_data (struct grub_jpeg_data *data) - { - unsigned c1, vb, hb, nr1, nc1; -+ unsigned stride_a, stride_b, stride; - int rst = data->dri; - grub_err_t err = GRUB_ERR_NONE; - -@@ -711,8 +713,14 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: attempted to decode data before start of stream"); - -+ if (grub_mul(vb, data->image_width, &stride_a) || -+ grub_mul(hb, nc1, &stride_b) || -+ grub_sub(stride_a, stride_b, &stride)) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: cannot decode image with these dimensions"); -+ - for (; data->r1 < nr1 && (!data->dri || rst); -- data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3) -+ data->r1++, data->bitmap_ptr += stride * 3) - for (c1 = 0; c1 < nc1 && (!data->dri || rst); - c1++, rst--, data->bitmap_ptr += hb * 3) - { --- -cgit v1.1 - diff --git a/backport-video-readers-jpeg-Do-not-reallocate-a-given.patch b/backport-video-readers-jpeg-Do-not-reallocate-a-given.patch deleted file mode 100644 index fc862b3..0000000 --- a/backport-video-readers-jpeg-Do-not-reallocate-a-given.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 768ef2199e0265cf455b154f1a80a612f02274c8 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 28 Jun 2021 14:16:58 +1000 -Subject: video/readers/jpeg: Do not reallocate a given huff table - -Fix a memory leak where an invalid file could cause us to reallocate -memory for a huffman table we had already allocated memory for. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=768ef2199e0265cf455b154f1a80a612f02274c8 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/jpeg.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 806c56c..2284a6c 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -251,6 +251,9 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) - n += count[i]; - - id += ac * 2; -+ if (data->huff_value[id] != NULL) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: attempt to reallocate huffman table"); - data->huff_value[id] = grub_malloc (n); - if (grub_errno) - return grub_errno; --- -cgit v1.1 - diff --git a/backport-video-readers-jpeg-Refuse-to-handle-multiple.patch b/backport-video-readers-jpeg-Refuse-to-handle-multiple.patch deleted file mode 100644 index 3b3f381..0000000 --- a/backport-video-readers-jpeg-Refuse-to-handle-multiple.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 166a4d61448f74745afe1dac2f2cfb85d04909bf Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 28 Jun 2021 14:25:17 +1000 -Subject: video/readers/jpeg: Refuse to handle multiple start of streams - -An invalid file could contain multiple start of stream blocks, which -would cause us to reallocate and leak our bitmap. Refuse to handle -multiple start of streams. - -Additionally, fix a grub_error() call formatting. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=166a4d61448f74745afe1dac2f2cfb85d04909bf -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/jpeg.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 2284a6c..579bbe8 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -683,6 +683,9 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - if (data->file->offset != data_offset) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos"); - -+ if (*data->bitmap) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: too many start of scan blocks"); -+ - if (grub_video_bitmap_create (data->bitmap, data->image_width, - data->image_height, - GRUB_VIDEO_BLIT_FORMAT_RGB_888)) -@@ -705,8 +708,8 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - nc1 = (data->image_width + hb - 1) >> (3 + data->log_hs); - - if (data->bitmap_ptr == NULL) -- return grub_error(GRUB_ERR_BAD_FILE_TYPE, -- "jpeg: attempted to decode data before start of stream"); -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: attempted to decode data before start of stream"); - - for (; data->r1 < nr1 && (!data->dri || rst); - data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3) --- -cgit v1.1 - diff --git a/backport-video-readers-png-Abort-sooner-if-a-read.patch b/backport-video-readers-png-Abort-sooner-if-a-read.patch deleted file mode 100644 index 049d292..0000000 --- a/backport-video-readers-png-Abort-sooner-if-a-read.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 5bff31cdb6b93d738f850834e6291df1d0b136fa Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 14:02:55 +1000 -Subject: video/readers/png: Abort sooner if a read operation fails - -Fuzzing revealed some inputs that were taking a long time, potentially -forever, because they did not bail quickly upon encountering an I/O error. - -Try to catch I/O errors sooner and bail out. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=5bff31cdb6b93d738f850834e6291df1d0b136fa -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/png.c | 55 ++++++++++++++++++++++++++++++++++++------- - 1 file changed, 47 insertions(+), 8 deletions(-) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index 54dfedf..d715c46 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -142,6 +142,7 @@ static grub_uint8_t - grub_png_get_byte (struct grub_png_data *data) - { - grub_uint8_t r; -+ grub_ssize_t bytes_read = 0; - - if ((data->inside_idat) && (data->idat_remain == 0)) - { -@@ -175,7 +176,14 @@ grub_png_get_byte (struct grub_png_data *data) - } - - r = 0; -- grub_file_read (data->file, &r, 1); -+ bytes_read = grub_file_read (data->file, &r, 1); -+ -+ if (bytes_read != 1) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: unexpected end of data"); -+ return 0; -+ } - - if (data->inside_idat) - data->idat_remain--; -@@ -231,15 +239,16 @@ grub_png_decode_image_palette (struct grub_png_data *data, - if (len == 0) - return GRUB_ERR_NONE; - -- for (i = 0; 3 * i < len && i < 256; i++) -+ grub_errno = GRUB_ERR_NONE; -+ for (i = 0; 3 * i < len && i < 256 && grub_errno == GRUB_ERR_NONE; i++) - for (j = 0; j < 3; j++) - data->palette[i][j] = grub_png_get_byte (data); -- for (i *= 3; i < len; i++) -+ for (i *= 3; i < len && grub_errno == GRUB_ERR_NONE; i++) - grub_png_get_byte (data); - - grub_png_get_dword (data); - -- return GRUB_ERR_NONE; -+ return grub_errno; - } - - static grub_err_t -@@ -256,9 +265,13 @@ grub_png_decode_image_header (struct grub_png_data *data) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size"); - - color_bits = grub_png_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - data->is_16bit = (color_bits == 16); - - color_type = grub_png_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - /* According to PNG spec, no other types are valid. */ - if ((color_type & ~(PNG_COLOR_MASK_ALPHA | PNG_COLOR_MASK_COLOR)) -@@ -340,14 +353,20 @@ grub_png_decode_image_header (struct grub_png_data *data) - if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "png: compression method not supported"); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "png: filter method not supported"); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if (grub_png_get_byte (data) != PNG_INTERLACE_NONE) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "png: interlace method not supported"); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - /* Skip crc checksum. */ - grub_png_get_dword (data); -@@ -449,7 +468,7 @@ grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht) - int code, i; - - code = 0; -- for (i = 0; i < ht->max_length; i++) -+ for (i = 0; i < ht->max_length && grub_errno == GRUB_ERR_NONE; i++) - { - code = (code << 1) + grub_png_get_bits (data, 1); - if (code < ht->maxval[i]) -@@ -504,8 +523,14 @@ grub_png_init_dynamic_block (struct grub_png_data *data) - grub_uint8_t lens[DEFLATE_HCLEN_MAX]; - - nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) || - (nb > DEFLATE_HCLEN_MAX)) -@@ -533,7 +558,7 @@ grub_png_init_dynamic_block (struct grub_png_data *data) - data->dist_offset); - - prev = 0; -- for (i = 0; i < nl + nd; i++) -+ for (i = 0; i < nl + nd && grub_errno == GRUB_ERR_NONE; i++) - { - int n, code; - struct huff_table *ht; -@@ -721,17 +746,21 @@ grub_png_read_dynamic_block (struct grub_png_data *data) - len = cplens[n]; - if (cplext[n]) - len += grub_png_get_bits (data, cplext[n]); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - n = grub_png_get_huff_code (data, &data->dist_table); - dist = cpdist[n]; - if (cpdext[n]) - dist += grub_png_get_bits (data, cpdext[n]); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - pos = data->wp - dist; - if (pos < 0) - pos += WSIZE; - -- while (len > 0) -+ while (len > 0 && grub_errno == GRUB_ERR_NONE) - { - data->slide[data->wp] = data->slide[pos]; - grub_png_output_byte (data, data->slide[data->wp]); -@@ -759,7 +788,11 @@ grub_png_decode_image_data (struct grub_png_data *data) - int final; - - cmf = grub_png_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - flg = grub_png_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if ((cmf & 0xF) != Z_DEFLATED) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, -@@ -774,7 +807,11 @@ grub_png_decode_image_data (struct grub_png_data *data) - int block_type; - - final = grub_png_get_bits (data, 1); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - block_type = grub_png_get_bits (data, 2); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - switch (block_type) - { -@@ -790,7 +827,7 @@ grub_png_decode_image_data (struct grub_png_data *data) - grub_png_get_byte (data); - grub_png_get_byte (data); - -- for (i = 0; i < len; i++) -+ for (i = 0; i < len && grub_errno == GRUB_ERR_NONE; i++) - grub_png_output_byte (data, grub_png_get_byte (data)); - - break; -@@ -1045,6 +1082,8 @@ grub_png_decode_png (struct grub_png_data *data) - - len = grub_png_get_dword (data); - type = grub_png_get_dword (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ break; - data->next_offset = data->file->offset + len + 4; - - switch (type) --- -cgit v1.1 - diff --git a/backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch b/backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch deleted file mode 100644 index 9f7eae6..0000000 --- a/backport-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 210245129c932dc9e1c2748d9d35524fb95b5042 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 23:25:07 +1000 -Subject: video/readers/png: Avoid heap OOB R/W inserting huff table items - -In fuzzing we observed crashes where a code would attempt to be inserted -into a huffman table before the start, leading to a set of heap OOB reads -and writes as table entries with negative indices were shifted around and -the new code written in. - -Catch the case where we would underflow the array and bail. - -Fixes: CVE-2021-3696 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=210245129c932dc9e1c2748d9d35524fb95b5042 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/png.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index a3161e2..d7ed5aa 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -438,6 +438,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len) - for (i = len; i < ht->max_length; i++) - n += ht->maxval[i]; - -+ if (n > ht->num_values) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: out of range inserting huffman table item"); -+ return; -+ } -+ - for (i = 0; i < n; i++) - ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1]; - --- -cgit v1.1 - diff --git a/backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch b/backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch deleted file mode 100644 index e42c0de..0000000 --- a/backport-video-readers-png-Drop-greyscale-support-to-fix-heap.patch +++ /dev/null @@ -1,174 +0,0 @@ -From e623866d9286410156e8b9d2c82d6253a1b22d08 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 18:51:35 +1000 -Subject: video/readers/png: Drop greyscale support to fix heap out-of-bounds - write - -A 16-bit greyscale PNG without alpha is processed in the following loop: - - for (i = 0; i < (data->image_width * data->image_height); - i++, d1 += 4, d2 += 2) - { - d1[R3] = d2[1]; - d1[G3] = d2[1]; - d1[B3] = d2[1]; - } - -The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration, -but there are only 3 bytes allocated for storage. This means that image -data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes -out of every 4 following the end of the image. - -This has existed since greyscale support was added in 2013 in commit -3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale). - -Saving starfield.png as a 16-bit greyscale image without alpha in the gimp -and attempting to load it causes grub-emu to crash - I don't think this code -has ever worked. - -Delete all PNG greyscale support. - -Fixes: CVE-2021-3695 - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=e623866d9286410156e8b9d2c82d6253a1b22d08 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/png.c | 87 +++-------------------------------- - 1 file changed, 7 insertions(+), 80 deletions(-) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index 8955b8e..ccc2e36 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -100,7 +100,7 @@ struct grub_png_data - - unsigned image_width, image_height; - int bpp, is_16bit; -- int raw_bytes, is_gray, is_alpha, is_palette; -+ int raw_bytes, is_alpha, is_palette; - int row_bytes, color_bits; - grub_uint8_t *image_data; - -@@ -296,13 +296,13 @@ grub_png_decode_image_header (struct grub_png_data *data) - data->bpp = 3; - else - { -- data->is_gray = 1; -- data->bpp = 1; -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: color type not supported"); - } - - if ((color_bits != 8) && (color_bits != 16) - && (color_bits != 4 -- || !(data->is_gray || data->is_palette))) -+ || !data->is_palette)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "png: bit depth must be 8 or 16"); - -@@ -331,7 +331,7 @@ grub_png_decode_image_header (struct grub_png_data *data) - } - - #ifndef GRUB_CPU_WORDS_BIGENDIAN -- if (data->is_16bit || data->is_gray || data->is_palette) -+ if (data->is_16bit || data->is_palette) - #endif - { - data->image_data = grub_calloc (data->image_height, data->row_bytes); -@@ -899,27 +899,8 @@ grub_png_convert_image (struct grub_png_data *data) - int shift; - int mask = (1 << data->color_bits) - 1; - unsigned j; -- if (data->is_gray) -- { -- /* Generic formula is -- (0xff * i) / ((1U << data->color_bits) - 1) -- but for allowed bit depth of 1, 2 and for it's -- equivalent to -- (0xff / ((1U << data->color_bits) - 1)) * i -- Precompute the multipliers to avoid division. -- */ -- -- const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 }; -- for (i = 0; i < (1U << data->color_bits); i++) -- { -- grub_uint8_t col = multipliers[data->color_bits] * i; -- palette[i][0] = col; -- palette[i][1] = col; -- palette[i][2] = col; -- } -- } -- else -- grub_memcpy (palette, data->palette, 3 << data->color_bits); -+ -+ grub_memcpy (palette, data->palette, 3 << data->color_bits); - d1c = d1; - d2c = d2; - for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3, -@@ -957,60 +938,6 @@ grub_png_convert_image (struct grub_png_data *data) - return; - } - -- if (data->is_gray) -- { -- switch (data->bpp) -- { -- case 4: -- /* 16-bit gray with alpha. */ -- for (i = 0; i < (data->image_width * data->image_height); -- i++, d1 += 4, d2 += 4) -- { -- d1[R4] = d2[3]; -- d1[G4] = d2[3]; -- d1[B4] = d2[3]; -- d1[A4] = d2[1]; -- } -- break; -- case 2: -- if (data->is_16bit) -- /* 16-bit gray without alpha. */ -- { -- for (i = 0; i < (data->image_width * data->image_height); -- i++, d1 += 4, d2 += 2) -- { -- d1[R3] = d2[1]; -- d1[G3] = d2[1]; -- d1[B3] = d2[1]; -- } -- } -- else -- /* 8-bit gray with alpha. */ -- { -- for (i = 0; i < (data->image_width * data->image_height); -- i++, d1 += 4, d2 += 2) -- { -- d1[R4] = d2[1]; -- d1[G4] = d2[1]; -- d1[B4] = d2[1]; -- d1[A4] = d2[0]; -- } -- } -- break; -- /* 8-bit gray without alpha. */ -- case 1: -- for (i = 0; i < (data->image_width * data->image_height); -- i++, d1 += 3, d2++) -- { -- d1[R3] = d2[0]; -- d1[G3] = d2[0]; -- d1[B3] = d2[0]; -- } -- break; -- } -- return; -- } -- - { - /* Only copy the upper 8 bit. */ - #ifndef GRUB_CPU_WORDS_BIGENDIAN --- -2.19.1 - diff --git a/backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch b/backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch deleted file mode 100644 index 88d8bff..0000000 --- a/backport-video-readers-png-Refuse-to-handle-multiple-image-headers.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 347880a13c239b4c2811c94c9a7cf78b607332e3 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 14:13:40 +1000 -Subject: video/readers/png: Refuse to handle multiple image headers - -This causes the bitmap to be leaked. Do not permit multiple image headers. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=347880a13c239b4c2811c94c9a7cf78b607332e3 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/png.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index d715c46..35ae553 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -258,6 +258,9 @@ grub_png_decode_image_header (struct grub_png_data *data) - int color_bits; - enum grub_video_blit_format blt; - -+ if (data->image_width || data->image_height) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: two image headers found"); -+ - data->image_width = grub_png_get_dword (data); - data->image_height = grub_png_get_dword (data); - --- -cgit v1.1 - diff --git a/backport-video-readers-png-Sanity-check-some-huffman-codes.patch b/backport-video-readers-png-Sanity-check-some-huffman-codes.patch deleted file mode 100644 index 3961eea..0000000 --- a/backport-video-readers-png-Sanity-check-some-huffman-codes.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 690bee69fae6b4bd911293d6b7e56774e29fdf64 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 19:19:11 +1000 -Subject: video/readers/png: Sanity check some huffman codes - -ASAN picked up two OOB global reads: we weren't checking if some code -values fit within the cplens or cpdext arrays. Check and throw an error -if not. - -Reference:https://git.savannah.gnu.org/cgit/grub.git/commit/?id=690bee69fae6b4bd911293d6b7e56774e29fdf64 -Conflict:NA - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper ---- - grub-core/video/readers/png.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index d7ed5aa..7f2ba78 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -753,6 +753,9 @@ grub_png_read_dynamic_block (struct grub_png_data *data) - int len, dist, pos; - - n -= 257; -+ if (((unsigned int) n) >= ARRAY_SIZE (cplens)) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: invalid huff code"); - len = cplens[n]; - if (cplext[n]) - len += grub_png_get_bits (data, cplext[n]); -@@ -760,6 +763,9 @@ grub_png_read_dynamic_block (struct grub_png_data *data) - return grub_errno; - - n = grub_png_get_huff_code (data, &data->dist_table); -+ if (((unsigned int) n) >= ARRAY_SIZE (cpdist)) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: invalid huff code"); - dist = cpdist[n]; - if (cpdext[n]) - dist += grub_png_get_bits (data, cpdext[n]); --- -cgit v1.1 - diff --git a/disable-some-unsupported-filesystems.patch b/disable-some-unsupported-filesystems.patch deleted file mode 100644 index 5cf489a..0000000 --- a/disable-some-unsupported-filesystems.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 5d3654738c78291a2252eec2fdee9cd4b6c9c2f4 Mon Sep 17 00:00:00 2001 -From: Qiumiao Zhang -Date: Thu, 2 Feb 2023 14:37:52 +0800 -Subject: [PATCH] disable some unsupported filesystems - -Signed-off-by: Qiumiao Zhang ---- - Makefile.util.def | 17 ----------------- - 1 file changed, 17 deletions(-) - -diff --git a/Makefile.util.def b/Makefile.util.def -index b7a6311..de156f9 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -95,9 +95,6 @@ library = { - common = grub-core/video/colors.c; - common = grub-core/unidata.c; - common = grub-core/io/bufio.c; -- common = grub-core/fs/affs.c; -- common = grub-core/fs/afs.c; -- common = grub-core/fs/bfs.c; - common = grub-core/fs/btrfs.c; - common = grub-core/fs/cbfs.c; - common = grub-core/fs/cpio.c; -@@ -113,25 +110,11 @@ library = { - common = grub-core/fs/hfsplus.c; - common = grub-core/fs/hfspluscomp.c; - common = grub-core/fs/iso9660.c; -- common = grub-core/fs/jfs.c; -- common = grub-core/fs/minix.c; -- common = grub-core/fs/minix2.c; -- common = grub-core/fs/minix3.c; -- common = grub-core/fs/minix_be.c; -- common = grub-core/fs/minix2_be.c; -- common = grub-core/fs/minix3_be.c; -- common = grub-core/fs/nilfs2.c; - common = grub-core/fs/ntfs.c; - common = grub-core/fs/ntfscomp.c; -- common = grub-core/fs/reiserfs.c; -- common = grub-core/fs/romfs.c; -- common = grub-core/fs/sfs.c; - common = grub-core/fs/squash4.c; - common = grub-core/fs/tar.c; - common = grub-core/fs/udf.c; -- common = grub-core/fs/ufs2.c; -- common = grub-core/fs/ufs.c; -- common = grub-core/fs/ufs_be.c; - common = grub-core/fs/xfs.c; - common = grub-core/fs/zfs/zfscrypt.c; - common = grub-core/fs/zfs/zfs.c; --- -2.27.0 - diff --git a/fix-compressed-kernel-verification-failed.patch b/fix-compressed-kernel-verification-failed.patch deleted file mode 100644 index e02cf09..0000000 --- a/fix-compressed-kernel-verification-failed.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0a73812b9ba12f8af4909b952751d6d5f4fd2dd2 Mon Sep 17 00:00:00 2001 -From: Qiumiao Zhang -Date: Sat, 23 Jul 2022 19:54:34 +0800 -Subject: [PATCH] fix compressed kernel verification failed - -Signed-off-by: Yusong Gao ---- - include/grub/file.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/grub/file.h b/include/grub/file.h -index 96827a4..b956dbb 100644 ---- a/include/grub/file.h -+++ b/include/grub/file.h -@@ -180,10 +180,10 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); - /* Filters with lower ID are executed first. */ - typedef enum grub_file_filter_id - { -- GRUB_FILE_FILTER_VERIFY, - GRUB_FILE_FILTER_GZIO, - GRUB_FILE_FILTER_XZIO, - GRUB_FILE_FILTER_LZOPIO, -+ GRUB_FILE_FILTER_VERIFY, - GRUB_FILE_FILTER_MAX, - GRUB_FILE_FILTER_COMPRESSION_FIRST = GRUB_FILE_FILTER_GZIO, - GRUB_FILE_FILTER_COMPRESSION_LAST = GRUB_FILE_FILTER_LZOPIO, --- -2.27.0 - diff --git a/fix-setupmode-not-available-in-some-machine.patch b/fix-setupmode-not-available-in-some-machine.patch deleted file mode 100644 index bfa7829..0000000 --- a/fix-setupmode-not-available-in-some-machine.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 4fc72f509627da808b452eb1186282237c449b65 Mon Sep 17 00:00:00 2001 -From: fengtao -Date: Tue, 22 Mar 2022 22:22:22 +0800 -Subject: [PATCH] fix setupmode not available in some machine - -In some machine, there is no setupmode variable, so we should -give setupmode a default vaule: setup_mode = 0 - -if we cannot get setupmode variable, we use setup_mode instead. - ---- - grub-core/kern/efi/sb.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c -index c52ec62..f58fb13 100644 ---- a/grub-core/kern/efi/sb.c -+++ b/grub-core/kern/efi/sb.c -@@ -50,6 +50,7 @@ grub_efi_get_secureboot (void) - grub_uint8_t *moksbstate = NULL; - grub_uint8_t secureboot = GRUB_EFI_SECUREBOOT_MODE_UNKNOWN; - const char *secureboot_str = "UNKNOWN"; -+ grub_uint8_t setup_mode = 0; - - status = grub_efi_get_variable ("SecureBoot", &efi_variable_guid, - &size, (void **) &secboot); -@@ -67,9 +68,16 @@ grub_efi_get_secureboot (void) - &size, (void **) &setupmode); - - if (status != GRUB_EFI_SUCCESS) -- goto out; -+ { -+ grub_dprintf ("efi", "No SetupMode variable\n"); -+ } -+ else -+ { -+ grub_dprintf ("efi", "SetupMode: %d\n", *setupmode); -+ setup_mode = *setupmode; -+ } - -- if ((*secboot == 0) || (*setupmode == 1)) -+ if ((*secboot == 0) || (setup_mode == 1)) - { - secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED; - goto out; --- -2.23.0 - diff --git a/grub-2.06.tar.xz b/grub-2.12.tar.xz similarity index 47% rename from grub-2.06.tar.xz rename to grub-2.12.tar.xz index a6a9c6dcb110f96560af778f89e7f64d67417679..9295544c27d42b29f1401817e4d045d7b4ba421f 100644 GIT binary patch delta 6604458 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 fY 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�ZmyVV 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%0AAR3x!mvO4A*8oVz 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

Y^y-^POubxjvLnev(!s-e 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

Z;&x72S~LqJK=lCco`B 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 z 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 z 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�Z_HN)T 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%0D19@$& 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

o-m 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

USCCQ0Q(2 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

)!i+7N30{(? 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

7SoHsOp4Y-Zo_VdC#j}uBAJ%+vDL#>?=$6OG8Vg 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²q`j<|zQh3zLxstM|U|K|1cM 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%0D;*_so0+33<+6rLAzUSyGrQk)q-s+I_p#=#QlT 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
kMY%Nz}ejgXf20RPJXCC)woWlD$5DK+~>Q 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

rsNwZB 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�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

+?+b^$;7?r*=b)M!!v6eh?0B1f@?u@4{u$EFvL= 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�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 z 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