rhboot / efibootmgr

efibootmgr development tree
GNU General Public License v2.0
514 stars 97 forks source link

efibootmgr does not show inactive bootnum #34

Closed solsticedhiver closed 9 years ago

solsticedhiver commented 9 years ago

I didn't find a forum or an irc chan to ask about this so I fill it as a bug report even though I am not sure it is one. May be it's a feature ?

With efibootmgr 0.11 (ubuntu or archlinux), I can't see any of the inactive bootnum entries that efibootmgr 0.5.x on kali 1.1.0a shows me.

I don't know if it's a bug or a security feature. Or a kali feature ?

One inactive entry is also a duplicate entry. Both inactive entries, refers to an uuid ESP not present. I guess it refers to the ESP on my HDD that I wipe when I installled my SSD and that the EFI firmware disabled automatically. I did not manually deactivate those entries.

$ ls /sys/firmware/efi/efivars | grep ^Boot
Boot0000-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Boot0001-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Boot0004-00000000-0000-0000-0000-000000000000
Boot0004-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Boot0005-00000000-0000-0000-0000-000000000000
Boot0006-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Boot0008-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Boot2001-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
BootCurrent-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
BootOrder-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
BootPrevious-yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
BootPreviousData-yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy

These are the one with 0 above

vathpela commented 9 years ago

Can you show me a) what "efibootmgr -v" actually /does/ show? and b) the output of "strace -o efibootmgr.strace efibootmgr -v"?

Thanks!

solsticedhiver commented 9 years ago

You want those outputs for which version ? the one on ubuntu that does not show some inactive entries or the one from kali that does show inactive entries ?

vathpela commented 9 years ago

Both would be good! But at the least, the one that doesn't show the inactive entries.

solsticedhiver commented 9 years ago

On ubuntu 15.04, efibootmgr 0.11.0

# efibootmgr -v
BootCurrent: 0008
Timeout: 0 seconds
BootOrder: 0002,0008,0006,2001
Boot0000* UEFI Onboard LAN IPv6 ACPI(a0341d0,0)PCI(1c,0)PCI(0,0)MAC(MAC(mmmmmmmmmmmm,0)030d3c000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000RC
Boot0001* UEFI Onboard LAN IPv4 ACPI(a0341d0,0)PCI(1c,0)PCI(0,0)MAC(MAC(mmmmmmmmmmmm,0)RC
Boot0002* ubuntu    HD(1,800,fa000,xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx)File(\EFI\ubuntu\shimx64.efi)
Boot0006* Windows Boot Manager  HD(1,800,fa000,xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx)File(\EFI\Microsoft\Boot\bootmgfw.efi)RC
Boot0008* Linux HD(1,800,fa000,xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx)File(\EFI\ubuntu\shimx64.efi)
Boot2001* EFI USB Device    RC

strace output

execve("/bin/efibootmgr", ["efibootmgr", "-v"], [/* 23 vars */]) = 0
brk(0)                                  = 0xd23000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f36b7ef7000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=144074, ...}) = 0
mmap(NULL, 144074, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f36b7ed3000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libpci.so.3", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P#\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=48352, ...}) = 0
mmap(NULL, 2143408, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f36b7aca000
mprotect(0x7f36b7ad5000, 2093056, PROT_NONE) = 0
mmap(0x7f36b7cd4000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xa000) = 0x7f36b7cd4000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib/x86_64-linux-gnu/libefivar.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@ \0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=63584, ...}) = 0
mmap(NULL, 2159512, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f36b78ba000
mprotect(0x7f36b78c1000, 2093056, PROT_NONE) = 0
mmap(0x7f36b7ac0000, 40960, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f36b7ac0000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\v\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1869392, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f36b7ed2000
mmap(NULL, 3972864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f36b74f0000
mprotect(0x7f36b76b0000, 2097152, PROT_NONE) = 0
mmap(0x7f36b78b0000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7f36b78b0000
mmap(0x7f36b78b6000, 16128, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f36b78b6000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\35\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=108920, ...}) = 0
mmap(NULL, 2203976, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f36b72d5000
mprotect(0x7f36b72ee000, 2097152, PROT_NONE) = 0
mmap(0x7f36b74ee000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19000) = 0x7f36b74ee000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3209\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=105328, ...}) = 0
mmap(NULL, 2210632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f36b70b9000
mprotect(0x7f36b70d0000, 2097152, PROT_NONE) = 0
mmap(0x7f36b72d0000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7f36b72d0000
mmap(0x7f36b72d3000, 6984, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f36b72d3000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\16\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=14592, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f36b7ed1000
mmap(NULL, 2109712, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f36b6eb5000
mprotect(0x7f36b6eb8000, 2093056, PROT_NONE) = 0
mmap(0x7f36b70b7000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f36b70b7000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f36b7ed0000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f36b7ecf000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f36b7ece000
arch_prctl(ARCH_SET_FS, 0x7f36b7ecf700) = 0
mprotect(0x7f36b78b0000, 16384, PROT_READ) = 0
mprotect(0x7f36b70b7000, 4096, PROT_READ) = 0
mprotect(0x7f36b72d0000, 8192, PROT_READ) = 0
mprotect(0x7f36b74ee000, 4096, PROT_READ) = 0
mprotect(0x7f36b7ac0000, 4096, PROT_READ) = 0
mprotect(0x7f36b7cd4000, 4096, PROT_READ) = 0
mprotect(0x60f000, 4096, PROT_READ)     = 0
mprotect(0x7f36b7ef9000, 4096, PROT_READ) = 0
munmap(0x7f36b7ed3000, 144074)          = 0
access("/sys/firmware/efi/efivars/", F_OK) = 0
statfs("/sys/firmware/efi/efivars/", {f_type=0xde5e81e4, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={0, 0}, f_namelen=255, f_frsize=4096}) = 0
openat(AT_FDCWD, "/sys/firmware/efi/efivars/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
brk(0)                                  = 0xd23000
brk(0xd4c000)                           = 0xd4c000
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
getdents(3, /* 68 entries */, 32768)    = 4872
getdents(3, /* 0 entries */, 32768)     = 0
close(3)                                = 0
open("/sys/firmware/efi/efivars/Boot0000-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\7\0\0\0", 4)                  = 4
read(3, "\1\0\0\0}\0U\0E\0F\0I\0 \0O\0n\0b\0o\0a\0r\0d\0 \0"..., 4096) = 177
read(3, "", 3919)                       = 0
close(3)                                = 0
open("/sys/firmware/efi/efivars/Boot0001-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\7\0\0\0", 4)                  = 4
read(3, "\1\0\0\0\\\0U\0E\0F\0I\0 \0O\0n\0b\0o\0a\0r\0d\0 \0"..., 4096) = 144
read(3, "", 3952)                       = 0
close(3)                                = 0
open("/sys/firmware/efi/efivars/Boot0002-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\7\0\0\0", 4)                  = 4
read(3, "\1\0\0\0b\0u\0b\0u\0n\0t\0u\0\0\0\4\1*\0\1\0\0\0\0\10\0\0"..., 4096) = 118
read(3, "", 3978)                       = 0
close(3)                                = 0
open("/sys/firmware/efi/efivars/Boot0006-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\7\0\0\0", 4)                  = 4
read(3, "\1\0\0\0t\0W\0i\0n\0d\0o\0w\0s\0 \0B\0o\0o\0t\0 \0"..., 4096) = 166
read(3, "", 3930)                       = 0
close(3)                                = 0
open("/sys/firmware/efi/efivars/Boot0008-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\7\0\0\0", 4)                  = 4
read(3, "\1\0\0\0b\0L\0i\0n\0u\0x\0\0\0\4\1*\0\1\0\0\0\0\10\0\0\0\0"..., 4096) = 116
read(3, "", 3980)                       = 0
close(3)                                = 0
open("/sys/firmware/efi/efivars/Boot2001-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\7\0\0\0", 4)                  = 4
read(3, "\1\0\0\0\4\0E\0F\0I\0 \0U\0S\0B\0 \0D\0e\0v\0i\0c\0"..., 4096) = 42
read(3, "", 4054)                       = 0
close(3)                                = 0
open("/sys/firmware/efi/efivars/BootNext-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/sys/firmware/efi/efivars/BootCurrent-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\6\0\0\0", 4)                  = 4
read(3, "\10\0", 4096)                  = 2
read(3, "", 4094)                       = 0
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 6), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f36b7ef6000
write(1, "BootCurrent: 0008\n", 18)     = 18
open("/sys/firmware/efi/efivars/Timeout-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\7\0\0\0", 4)                  = 4
read(3, "\0\0", 4096)                   = 2
read(3, "", 4094)                       = 0
close(3)                                = 0
write(1, "Timeout: 0 seconds\n", 19)    = 19
open("/sys/firmware/efi/efivars/BootOrder-yyyyyyyy-yyyy-yyyy-yyyyyyyyyyyy", O_RDONLY) = 3
read(3, "\7\0\0\0", 4)                  = 4
read(3, "\2\0\10\0\6\0\1 ", 4096)       = 8
read(3, "", 4088)                       = 0
close(3)                                = 0
write(1, "BootOrder: 0002,0008,0006,2001\n", 31) = 31
write(1, "Boot0000* UEFI Onboard LAN IPv6\t"..., 210) = 210
write(1, "Boot0001* UEFI Onboard LAN IPv4\t"..., 90) = 90
write(1, "Boot0002* ubuntu\tHD(1,800,fa000,"..., 99) = 99
write(1, "Boot0006* Windows Boot Manager\tH"..., 124) = 124
write(1, "Boot0008* Linux\tHD(1,800,fa000,f"..., 98) = 98
write(1, "Boot2001* EFI USB Device\tRC\n", 28) = 28
exit_group(0)                           = ?
+++ exited with 0 +++

One thing should be noted; it's that whatever I tried to delete that ubuntu entry, it came back because I think the EFI firmware is automatically recreating it.

solsticedhiver commented 9 years ago

What is the RC at then end of some entries in verbose output supposed to mean ? Why do some have it, and some don't ?

A quick look at the code doesn't enlighten me at all.

vathpela commented 9 years ago

(Just to answer the "RC" question, then I'll get back to your real issue.) The "RC" is actually just appended data just like data being put there by BDS when it creates a boot entry, so that it can later identify that it did so. IMHO it's a pretty awful hack that should have been implemented by changing the UEFI Spec to have a "creator" field, but that's not what the authors of the reference BDS chose to do. On some machines there's actually a whole GUID in there. I think there's supposed to be on the machines where you see "RC" but there's a BDS bug where it gets truncated. (BDS == "Boot Display Services", i.e. the firmware boot chooser menu.) I should really just make efibootmgr recognize the various different implementations of that we've seen and show a status character to explain them, or at least write up some documentation in the man page about it.

In 2.5 will hopefully be /somewhat/ better, in that we had the spec changed so firmware "recovery" items that haven't been invoked don't need to be Boot#### variables (they get their own read-only namespace as PlatformRecovery####), and so in general a well-behaved firmware should touch the Boot#### variables less.

vathpela commented 9 years ago

Okay, so, in that strace we're displaying every "Boot####" getdents() is showing us from /sys/firmware/efi/efivars/ - the active vs inactive state is kept in the variable itself, and we don't make that decision until later. So if the "inactive" ones aren't being displayed, it's because the firmware (or something else) is actually deleting them. FWIW there's nothing security sensitive in the GUIDs here - it's just a namespace that allows you separate variables according to "owner" in the firmware. The Boot#### variables are all required to be in the "8be4df61-93ca-11d2-aa0d-00e098032b8c" namespace ("EFI_GLOBAL_VARIABLE"). So if the issue is that there are some boot variables that are literally "Boot####-00000000-0000-0000-0000-000000000000", i.e. the GUID is all zeroes, then the reason we're not showing them is that they're in the wrong namespace, in fact a totally invalid one, and they won't work at all.

As for the Ubuntu entry, as you can see from "RC" not being there, the firmware doesn't appear to be creating it itself. As of shim-0.3 (May of 2013 or so), shim, the first-stage bootloader, supports re-creating missing boot entries if it's been deployed correctly by the OS. I don't know when Ubuntu started supporting this, but in modern versions, they should be installing shim.efi to \EFI\BOOT\BOOTX64.EFI in addition to the copy in \EFI\ubuntu, also have \EFI\BOOT\fallback.efi installed there, and have a \EFI\ubuntu\BOOT.CSV in place. What's going on here is that if the firmware doesn't find any boot entry that works, it runs \EFI\BOOT\BOOTX64.EFI. In this setup, shim checks if fallback.efi is in the same directory as it, and if so it runs that. fallback.efi subsequently iterates \EFI*\ (filtering out the directories "BOOT", ".", and "..") searching for BOOT.CSV, and recreates a boot entry with the data in that file using the bootloader binary in the same directory as the file. I suspect that's probably how the entry is coming back.

vathpela commented 9 years ago

It just occurred to me that what you're seeing is partially the result of what got fixed in 272eeb462072976c58dbf2c3085e5a4c59576a15 , where we didn't always initialize the GUID properly in the case where you were setting the "active" and "inactive" flag only, and so sometimes we re-created the variable with the GUID as 00000000-0000-0000-0000-000000000000 . It should be fixed in more recent versions.

vathpela commented 9 years ago

(You - perfectly reasonably - must have assumed that the zeroes were what made them "inactive". It's not, it's just a bug.)

vathpela commented 9 years ago

With that in mind, I think 0.12 or newer will solve this for you, so I'm going to close this issue out. If I turn out to be wrong, feel free to re-open it or open a new issue if you hit some other problem.

And thanks!