diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-11-05 14:53:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-05 14:53:47 +0100 |
commit | 7f9521d5e12ca9b1bee530dfe2e0218c07f3d7fa (patch) | |
tree | 1cf7fae67f439e39a1301da3caa48dff09c55d55 /src | |
parent | basic/mountpoint-util: detect erofs as a read-only FS (diff) | |
parent | sd-boot: Fix efi_arch checks (diff) | |
download | systemd-7f9521d5e12ca9b1bee530dfe2e0218c07f3d7fa.tar.xz systemd-7f9521d5e12ca9b1bee530dfe2e0218c07f3d7fa.zip |
Merge pull request #21225 from medhefgo/boot-cleanup
Boot cleanup
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/macro.h | 7 | ||||
-rw-r--r-- | src/boot/efi/boot.c | 50 | ||||
-rw-r--r-- | src/boot/efi/cpio.c | 2 | ||||
-rw-r--r-- | src/boot/efi/drivers.c | 2 | ||||
-rw-r--r-- | src/boot/efi/meson.build | 64 | ||||
-rwxr-xr-x | src/boot/efi/no-undefined-symbols.sh | 9 | ||||
-rw-r--r-- | src/boot/efi/pe.c | 14 | ||||
-rw-r--r-- | src/boot/efi/stub.c | 19 | ||||
-rw-r--r-- | src/boot/efi/util.c | 11 | ||||
-rw-r--r-- | src/fundamental/macro-fundamental.h | 7 |
10 files changed, 96 insertions, 89 deletions
diff --git a/src/basic/macro.h b/src/basic/macro.h index 03a0d061b8..aa04039e80 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -328,13 +328,6 @@ static inline int __coverity_check_and_return__(int condition) { ans; \ }) -#define UPDATE_FLAG(orig, flag, b) \ - ((b) ? ((orig) | (flag)) : ((orig) & ~(flag))) -#define SET_FLAG(v, flag, b) \ - (v) = UPDATE_FLAG(v, flag, b) -#define FLAGS_SET(v, flags) \ - ((~(v) & (flags)) == 0) - #define SWAP_TWO(x, y) do { \ typeof(x) _t = (x); \ (x) = (y); \ diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index db0c22d405..296efdd489 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -551,7 +551,7 @@ static EFI_STATUS reboot_into_firmware(void) { UINT64 osind = 0; EFI_STATUS err; - if (!(get_os_indications_supported() & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) + if (!FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) return log_error_status_stall(EFI_UNSUPPORTED, L"Reboot to firmware interface not supported."); (void) efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndications", &osind); @@ -924,7 +924,7 @@ static BOOLEAN menu_run( case KEYPRESS(0, SCAN_F10, 0): /* HP and Lenovo. */ case KEYPRESS(0, SCAN_DELETE, 0): /* Same as F2. */ case KEYPRESS(0, SCAN_ESC, 0): /* HP. */ - if (get_os_indications_supported() & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) { + if (FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) { firmware_setup = TRUE; /* Let's make sure the user really wants to do this. */ status = PoolPrint(L"Press Enter to reboot into firmware interface."); @@ -1590,7 +1590,7 @@ static void config_load_entries( if (f->FileName[0] == '.') continue; - if (f->Attribute & EFI_FILE_DIRECTORY) + if (FLAGS_SET(f->Attribute, EFI_FILE_DIRECTORY)) continue; if (!endswith_no_case(f->FileName, L".conf")) @@ -2026,16 +2026,23 @@ static void config_entry_add_linux( return; for (;;) { + enum { + SECTION_CMDLINE, + SECTION_OSREL, + _SECTION_MAX, + }; + + static const CHAR8* const sections[_SECTION_MAX + 1] = { + [SECTION_CMDLINE] = (const CHAR8 *) ".cmdline", + [SECTION_OSREL] = (const CHAR8 *) ".osrel", + NULL, + }; + _cleanup_freepool_ CHAR16 *os_name_pretty = NULL, *os_name = NULL, *os_id = NULL, *os_version = NULL, *os_version_id = NULL, *os_build_id = NULL, *os_image_version = NULL; _cleanup_freepool_ CHAR8 *content = NULL; - const CHAR8 *sections[] = { - (CHAR8 *)".osrel", - (CHAR8 *)".cmdline", - NULL - }; - UINTN offs[ELEMENTSOF(sections)-1] = {}; - UINTN szs[ELEMENTSOF(sections)-1] = {}; + UINTN offs[_SECTION_MAX] = {}; + UINTN szs[_SECTION_MAX] = {}; CHAR8 *line; UINTN pos = 0; CHAR8 *key, *value; @@ -2046,7 +2053,7 @@ static void config_entry_add_linux( if (f->FileName[0] == '.') continue; - if (f->Attribute & EFI_FILE_DIRECTORY) + if (FLAGS_SET(f->Attribute, EFI_FILE_DIRECTORY)) continue; if (!endswith_no_case(f->FileName, L".efi")) continue; @@ -2054,11 +2061,11 @@ static void config_entry_add_linux( continue; /* look for .osrel and .cmdline sections in the .efi binary */ - err = pe_file_locate_sections(linux_dir, f->FileName, sections, offs, szs); - if (EFI_ERROR(err)) + err = pe_file_locate_sections(linux_dir, f->FileName, (const CHAR8**) sections, offs, szs); + if (EFI_ERROR(err) || szs[SECTION_OSREL] == 0) continue; - err = file_read(linux_dir, f->FileName, offs[0], szs[0], &content, NULL); + err = file_read(linux_dir, f->FileName, offs[SECTION_OSREL], szs[SECTION_OSREL], &content, NULL); if (EFI_ERROR(err)) continue; @@ -2122,21 +2129,24 @@ static void config_entry_add_linux( path, os_image_version ?: (os_version ?: (os_version_id ? : os_build_id))); + config_entry_parse_tries(entry, L"\\EFI\\Linux", f->FileName, L".efi"); + + if (szs[SECTION_CMDLINE] == 0) + continue; + FreePool(content); content = NULL; /* read the embedded cmdline file */ - err = file_read(linux_dir, f->FileName, offs[1], szs[1], &content, NULL); + err = file_read(linux_dir, f->FileName, offs[SECTION_CMDLINE], szs[SECTION_CMDLINE], &content, NULL); if (!EFI_ERROR(err)) { /* chomp the newline */ - if (content[szs[1]-1] == '\n') - content[szs[1]-1] = '\0'; + if (content[szs[SECTION_CMDLINE] - 1] == '\n') + content[szs[SECTION_CMDLINE] - 1] = '\0'; entry->options = stra_to_str(content); } - - config_entry_parse_tries(entry, L"\\EFI\\Linux", f->FileName, L".efi"); } } } @@ -2352,7 +2362,7 @@ static void config_load_all_entries( config_entry_add_loader_auto(config, loaded_image->DeviceHandle, root_dir, loaded_image_path, L"auto-efi-default", '\0', L"EFI Default Loader", NULL); - if (config->auto_firmware && (get_os_indications_supported() & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) + if (config->auto_firmware && FLAGS_SET(get_os_indications_supported(), EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) config_entry_add_call(config, L"auto-reboot-to-firmware-setup", L"Reboot Into Firmware Interface", diff --git a/src/boot/efi/cpio.c b/src/boot/efi/cpio.c index bb7c988031..1818fbedd0 100644 --- a/src/boot/efi/cpio.c +++ b/src/boot/efi/cpio.c @@ -375,7 +375,7 @@ EFI_STATUS pack_cpio( if (dirent->FileName[0] == '.') continue; - if (dirent->Attribute & EFI_FILE_DIRECTORY) + if (FLAGS_SET(dirent->Attribute, EFI_FILE_DIRECTORY)) continue; if (match_suffix && !endswith_no_case(dirent->FileName, match_suffix)) continue; diff --git a/src/boot/efi/drivers.c b/src/boot/efi/drivers.c index 3ae8f0dde7..4bb4dedaa0 100644 --- a/src/boot/efi/drivers.c +++ b/src/boot/efi/drivers.c @@ -103,7 +103,7 @@ EFI_STATUS load_drivers( if (dirent->FileName[0] == '.') continue; - if (dirent->Attribute & EFI_FILE_DIRECTORY) + if (FLAGS_SET(dirent->Attribute, EFI_FILE_DIRECTORY)) continue; if (!endswith_no_case(dirent->FileName, EFI_MACHINE_TYPE_NAME L".efi")) continue; diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index e6bb7d7c6a..40b0ab0dbd 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -45,6 +45,12 @@ stub_sources = ''' cpio.c '''.split() +if efi_arch in ['x86', 'x86_64'] + stub_sources += 'linux_x86.c' +else + stub_sources += 'linux.c' +endif + if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false' efi_cc = get_option('efi-cc') if efi_cc.length() == 0 @@ -197,11 +203,10 @@ if have_gnu_efi compile_args = cc.get_supported_arguments( basic_disabled_warnings + possible_common_cc_flags + [ - '-ffreestanding', '-fno-stack-protector', '-fno-strict-aliasing', '-fpic', - '-fshort-wchar', + '-fwide-exec-charset=UCS2', '-Wall', '-Wextra', '-Wsign-compare', @@ -209,6 +214,8 @@ if have_gnu_efi ) + [ '-nostdlib', '-std=gnu99', + '-ffreestanding', + '-fshort-wchar', '-isystem', efi_incdir, '-isystem', efi_incdir / gnu_efi_path_arch, '-I', fundamental_path, @@ -217,46 +224,52 @@ if have_gnu_efi '-include', efi_config_h, '-include', version_h, ] - if ['ia32', 'x86_64'].contains(efi_arch) - stub_sources += 'linux_x86.c' - else - stub_sources += 'linux.c' - endif + if efi_arch == 'x86_64' compile_args += ['-mno-red-zone', '-mno-sse', '-mno-mmx'] - elif efi_arch == 'ia32' + elif efi_arch == 'x86' compile_args += ['-mno-sse', '-mno-mmx'] elif efi_arch == 'arm' - if cc.has_argument('-mgeneral-regs-only') - compile_args += ['-mgeneral-regs-only'] - endif - - if cc.has_argument('-mfpu=none') - compile_args += ['-mfpu=none'] - endif + compile_args += cc.get_supported_arguments([ + '-mgeneral-regs-only', + '-mfpu=none' + ]) endif - if get_option('werror') == true + + # We are putting the efi_cc command line together ourselves, so make sure to pull any + # relevant compiler flags from meson/CFLAGS as povided by the user or distro. + + if get_option('werror') compile_args += ['-Werror'] endif - if get_option('buildtype') == 'debug' - compile_args += ['-ggdb', '-O0', '-DEFI_DEBUG'] - elif get_option('buildtype') == 'debugoptimized' - compile_args += ['-ggdb', '-Og', '-DEFI_DEBUG'] - else - compile_args += ['-O2'] + if get_option('debug') + compile_args += ['-ggdb', '-DEFI_DEBUG'] + endif + if get_option('optimization') != '0' + compile_args += ['-O' + get_option('optimization')] endif if get_option('b_ndebug') == 'true' or ( get_option('b_ndebug') == 'if-release' and ['plain', 'release'].contains(get_option('buildtype'))) compile_args += ['-DNDEBUG'] endif + foreach arg : get_option('c_args') + if arg in ['-Werror', '-g', '-ggdb', '-O1', '-O2', '-O3', '-Og', '-Os', '-DNDEBUG'] + message('Using "@0@" from c_args for EFI compiler'.format(arg)) + compile_args += arg + endif + endforeach + efi_ldflags = ['-T', efi_lds, '-shared', '-Bsymbolic', '-nostdlib', + '--no-undefined', + '--warn-common', + '--fatal-warnings', '-znocombreloc', '--build-id=sha1', '-L', efi_libdir, @@ -291,7 +304,6 @@ if have_gnu_efi systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(EFI_MACHINE_TYPE_NAME) stub_elf_name = 'linux@0@.elf.stub'.format(EFI_MACHINE_TYPE_NAME) stub_efi_name = 'linux@0@.efi.stub'.format(EFI_MACHINE_TYPE_NAME) - no_undefined_symbols = find_program('no-undefined-symbols.sh') efi_stubs = [] foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects, false], @@ -325,12 +337,6 @@ if have_gnu_efi install_dir : bootlibdir) efi_stubs += [[so, stub]] - - if want_tests != 'false' - test('no-undefined-symbols-' + tuple[0], - no_undefined_symbols, - args : so) - endif endforeach ############################################################ diff --git a/src/boot/efi/no-undefined-symbols.sh b/src/boot/efi/no-undefined-symbols.sh deleted file mode 100755 index 8bdb16accf..0000000000 --- a/src/boot/efi/no-undefined-symbols.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: LGPL-2.1-or-later -set -eu -set -o pipefail - -if nm -D -u "${1:?}" | grep ' U '; then - echo "Undefined symbols detected!" - exit 1 -fi diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c index 6aecfe4526..e87b720dfa 100644 --- a/src/boot/efi/pe.c +++ b/src/boot/efi/pe.c @@ -122,7 +122,8 @@ static inline BOOLEAN verify_pe(const struct PeFileHeader *pe) { return CompareMem(pe->Magic, PE_FILE_MAGIC, STRLEN(PE_FILE_MAGIC)) == 0 && pe->FileHeader.Machine == TARGET_MACHINE_TYPE && pe->FileHeader.NumberOfSections > 0 && - pe->FileHeader.NumberOfSections <= MAX_SECTIONS; + pe->FileHeader.NumberOfSections <= MAX_SECTIONS && + IN_SET(pe->OptionalHeader.Magic, OPTHDR32_MAGIC, OPTHDR64_MAGIC); } static inline UINTN section_table_offset(const struct DosFileHeader *dos, const struct PeFileHeader *pe) { @@ -182,15 +183,8 @@ EFI_STATUS pe_alignment_info( return EFI_LOAD_ERROR; *ret_entry_point_address = pe->OptionalHeader.AddressOfEntryPoint; - - if (pe->OptionalHeader.Magic == OPTHDR32_MAGIC) { - *ret_size_of_image = pe->OptionalHeader.SizeOfImage; - *ret_section_alignment = pe->OptionalHeader.SectionAlignment; - } else if (pe->OptionalHeader.Magic == OPTHDR64_MAGIC) { - *ret_size_of_image = pe->OptionalHeader.SizeOfImage; - *ret_section_alignment = pe->OptionalHeader.SectionAlignment; - } else - return EFI_UNSUPPORTED; + *ret_size_of_image = pe->OptionalHeader.SizeOfImage; + *ret_section_alignment = pe->OptionalHeader.SectionAlignment; return EFI_SUCCESS; } diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 256aa21827..4de23792b5 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -154,7 +154,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { _SECTION_MAX, }; - const CHAR8* const sections[] = { + static const CHAR8* const sections[_SECTION_MAX + 1] = { [SECTION_CMDLINE] = (const CHAR8*) ".cmdline", [SECTION_LINUX] = (const CHAR8*) ".linux", [SECTION_INITRD] = (const CHAR8*) ".initrd", @@ -172,6 +172,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { UINTN addrs[_SECTION_MAX] = {}; UINTN szs[_SECTION_MAX] = {}; CHAR8 *cmdline = NULL; + _cleanup_freepool_ CHAR8 *cmdline_owned = NULL; EFI_STATUS err; InitializeLib(image, sys_table); @@ -187,8 +188,11 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err); err = pe_memory_locate_sections(loaded_image->ImageBase, (const CHAR8**) sections, addrs, szs); - if (EFI_ERROR(err)) + if (EFI_ERROR(err) || szs[SECTION_LINUX] == 0) { + if (!EFI_ERROR(err)) + err = EFI_NOT_FOUND; return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err); + } /* Show splash screen as early as possible */ graphics_splash((const UINT8*) loaded_image->ImageBase + addrs[SECTION_SPLASH], szs[SECTION_SPLASH], NULL); @@ -201,18 +205,13 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { /* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */ if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 && *(CHAR16 *) loaded_image->LoadOptions > 0x1F) { - CHAR16 *options; - CHAR8 *line; - - options = (CHAR16 *)loaded_image->LoadOptions; cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8); - line = AllocatePool(cmdline_len); - if (!line) + cmdline = cmdline_owned = AllocatePool(cmdline_len); + if (!cmdline) return log_oom(); for (UINTN i = 0; i < cmdline_len; i++) - line[i] = options[i]; - cmdline = line; + cmdline[i] = ((CHAR16 *) loaded_image->LoadOptions)[i]; /* Let's measure the passed kernel command line into the TPM. Note that this possibly * duplicates what we already did in the boot menu, if that was already used. However, since diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c index 9128c507c8..4d981ca7e5 100644 --- a/src/boot/efi/util.c +++ b/src/boot/efi/util.c @@ -493,14 +493,21 @@ void log_error_stall(const CHAR16 *fmt, ...) { assert(fmt); + INT32 attr = ST->ConOut->Mode->Attribute; ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK); - Print(L"\n"); + if (ST->ConOut->Mode->CursorColumn > 0) + Print(L"\n"); + va_start(args, fmt); VPrint(fmt, args); va_end(args); + Print(L"\n"); + ST->ConOut->SetAttribute(ST->ConOut, attr); + + /* Give the user a chance to see the message. */ BS->Stall(3 * 1000 * 1000); } @@ -734,7 +741,7 @@ EFI_STATUS open_directory( err = get_file_info_harder(dir, &file_info, NULL); if (EFI_ERROR(err)) return err; - if (!(file_info->Attribute & EFI_FILE_DIRECTORY)) + if (!FLAGS_SET(file_info->Attribute, EFI_FILE_DIRECTORY)) return EFI_LOAD_ERROR; *ret = TAKE_PTR(dir); diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h index ed527adb77..44af0bd0a0 100644 --- a/src/fundamental/macro-fundamental.h +++ b/src/fundamental/macro-fundamental.h @@ -306,3 +306,10 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { (l <= SIZE_MAX - (ali - 1)), /* overflow? */ \ ((l) + (ali) - 1) & ~((ali) - 1), \ VOID_0) + +#define UPDATE_FLAG(orig, flag, b) \ + ((b) ? ((orig) | (flag)) : ((orig) & ~(flag))) +#define SET_FLAG(v, flag, b) \ + (v) = UPDATE_FLAG(v, flag, b) +#define FLAGS_SET(v, flags) \ + ((~(v) & (flags)) == 0) |