sd-boot: added TPM measurements for initrd#6124
Conversation
src/boot/efi/boot.c
Outdated
| #ifdef SD_BOOT_LOG_TPM | ||
| UINTN i, j; | ||
| UINTN length; | ||
| CHAR16* begin, *end; |
There was a problem hiding this comment.
so far we tried to follow the logic that variables should be decalred at the beginning of code blocks only. Also see CODING_STYLE. Hence, please move these variable declarations up, or even better split this addition out into a new function maybe?
src/boot/efi/boot.c
Outdated
| UINTN length; | ||
| CHAR16* begin, *end; | ||
|
|
||
| EFI_FILE* root_dir = LibOpenRoot(entry->device); |
There was a problem hiding this comment.
also, please don't mix function invocations and variable declarations in the same line, also see CODING_STYLE.
src/boot/efi/boot.c
Outdated
|
|
||
| EFI_FILE* root_dir = LibOpenRoot(entry->device); | ||
| if (!root_dir) { | ||
| Print(L"Unable to open root directory: %r ", err); |
There was a problem hiding this comment.
trailing whitespace at the end of the string? is that intended?
src/boot/efi/boot.c
Outdated
| EFI_FILE* root_dir = LibOpenRoot(entry->device); | ||
| if (!root_dir) { | ||
| Print(L"Unable to open root directory: %r ", err); | ||
| uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000); |
There was a problem hiding this comment.
310001000 appears quite arbitary? also, what#s the logic here?
There was a problem hiding this comment.
This is the same statement that is used throughout boot.c, it salls, i.e. waits for 3 seconds to allow the user to read the error message
src/boot/efi/boot.c
Outdated
| begin = &options[i + 7]; | ||
| for (j = i + 7; j < length && options[j] != L' '; j++); | ||
| end = &options[j]; | ||
| UINTN initrd_path_len = (end - begin) * sizeof(CHAR16); |
There was a problem hiding this comment.
no variable declarations in the middle of code blocks. (here and evreywhere else, see above/CODING_STYLE)
src/boot/efi/boot.c
Outdated
| for (i = 0; i < length; i++) { | ||
| if (StrnCmp(L"initrd=", &options[i], 7) == 0) { | ||
| begin = &options[i + 7]; | ||
| for (j = i + 7; j < length && options[j] != L' '; j++); |
There was a problem hiding this comment.
if you write for() loops without body, please place the trailing semicolon in an empty line, to make this clear. i.e.:
for (…)
;Measure all initrds that are passed in the commandline and measure them into the default PCR, before measuring the commandline itself and starting the kernel image.
|
I moved my changes in a separate methods. I originally extended the code that hashed the kernel command line for the TPM. I moved that part too, because it makes sense that code that is related should be in the same method. As before the compilation is conditional on the SD_BOOT_LOG_TPM define. |
|
@haraldh any chance you can have a look? |
|
I don't know. This patch measures a file, which is read from disk and then the buffer is thrown away and not passed to the kernel. |
|
The buffer is thrown away because sd-boot uses the kernel's efi stub to load the initrd and does not pass an allocated memory like in the multiboot protocol. The reason I created this patch primarily for my self is to assure that the initrd was not modified in between boots there is (currently) no possibility for the kernel to actually do this. I do not see how a potential attacker could pass an alternate disk to load a modified file, because an efi executable that was loaded before sd-boot would modify PCR[4] through the LoadImage() call. And modifying the file on the disk would alter the generated hash, (and this is actually what we want, a mechanism to detect modification). A later userspace mechanism obviously has to check the integrity of the boot using PCR[4] for the boot loader and the kernel and PCR[8] for the initrds and the commandline options. Edit:
Should it better be part of sd-efistub? |
Not needed for the efistub, because the whole thing (combined kernel, initrd, cmdline) is measured by the EFI BIOS directly already. |
|
Only if you use a combined efi, it needs support from the OS (using kernel-install). How would intel microcode updates work? these need a seperate initrd which need to be loaded first. (at least this is the case on arch-linux) This patch only works for initrds in the commandline, for combined efi images it would not change a thing, thus only enhancing the experience for users who don't use the combined efi executables. |
|
For fedora the microcode initrd and the real initrd are concatenated. The kernel splits that automatically. So it's only one initrd file. |
|
As I said. It does not make sense to measure something, which you are not using immediately. The kernel efi stub should do the measurement, as it is providing the loaded bytes to the kernel directly. |
|
OK, closing as per @haraldh's comments. Sorry! |
Currently only the efi executable (the linux kernel) is hashed in the TPM PCR[4] using the LoadImage() function of the EFI system. The initrd, which contains code to either unlock or verify the root partition is not hashed in a PCR unless a unified EFI executable is created (systemd efi stub + kernel + initrd in one efi exe)
This patch adds support for hashing all the initrds that are supplied in the sd-boot configfile and append the hash values to the sd-boot TPM PCR hash of the boot options (usually PCR[8])
I thoroughly tested this patch and i have noticed that it has a noticeable performance impact. on my system sd-boot now takes about 250ms to boot, thats about 70ms longer than without this patch.
I'm also not sure if this is the direction the sd-boot developers want to take.