Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 431984 - sys-boot/efibootmgr - arch must match kernel arch to work correctly
Summary: sys-boot/efibootmgr - arch must match kernel arch to work correctly
Status: RESOLVED OBSOLETE
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: [OLD] Core system (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Mike Gilbert
URL:
Whiteboard:
Keywords: PATCH
Depends on:
Blocks:
 
Reported: 2012-08-19 20:13 UTC by Phattanon Duangdara
Modified: 2016-12-31 01:59 UTC (History)
3 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
efibootmgr efivars read/write workaround patch (efibootmgr-sysfs-fix.patch.txt,6.36 KB, patch)
2012-08-19 23:42 UTC, Phattanon Duangdara
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Phattanon Duangdara 2012-08-19 20:13:20 UTC
efibootmgr 32bit build must run on 32bit kernel and 64bit build must run on 64bit kernel.

This raise problems when 32bit userland run on 64bit (x86_64) kernel via chroot environment or 64bit kernel was use to boot 32bit linux system.
(Such as SystemRescueCD)

According to changelog of 5.2.2
commit 0ee8ecc10109b91d0a77098d5596f56780c862d8
Author: Matt Domsch <Matt_Domsch@dell.com>
Date:   Thu Aug 11 17:37:04 2005 +0000

    v0.5.2.2

* Thu Aug 11 2005 Matt Domsch <Matt_Domsch@dell.com>
- applied patch from Rogerio Timmers which adds a new option -@ <file>,
  which takes extra variable parameters from <file>, or - from stdin.
  This lets you pass binary (non-unicode, non-ascii) formatted options to
  your bootloader.
- cleaned up Rogerio's patch some.
- moved definition of _FILE_OFFSET_BITS=64 into Makefile and out of the
  individual .c files.  This fixes a bug reported by Red Flag, where
  variable data was getting incorrectly set with a 32-bit copy of
  efibootmgr on a 32-bit kernel.
- made efi_variable_t.DataSize be an unsigned long to match the kernel.
  This lets a 32-bit copy of efibootmgr run on a 32-bit kernel.  This
  means you've got to have a 32-bit efibootmgr on a 32-bit kernel, and a
  64-bit efibootmgr on a 64-bit kernel, but since efi_status_t is also a
  long, this was really going to be the case anyway.
- valgrind caught the app exiting without freeing some malloc'd
  structures, fix that.
- v0.5.2.2 released for testing

efibootmgr 64bit run on 64bit kernel
xwing ~ # uname -a
Linux xwing 3.5.2-gentoo #10 SMP PREEMPT Sat Aug 18 18:30:49 ICT 2012 x86_64 Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz GenuineIntel GNU/Linux
xwing ~ # file /usr/sbin/efibootmgr
/usr/sbin/efibootmgr: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped
xwing ~ # efibootmgr -v
BootCurrent: 0000
BootOrder: 0000,0001,0002,0003,0004,0005,0006,0007,0008,0009,000A,000B,000C,000D,000E
Boot0000* 0	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)
Boot0001* 1	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)
Boot0002* 2	ACPI(a0341d0,0)PCI(1,1)ATAPI(1,0,0)
Boot0003* 0	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(1,800,ff800,7c1b0800)
Boot0004* 1	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(2,100000,f00000,7c1b0800)
Boot0005* 2	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(3,1000000,8000000,7c1b0800)
Boot0006* 3	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(4,9000000,31386030,7c1b0800)
Boot0007* 4	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(4,9000000,31386030,7c1b0800)HD(1,9000800,4000000,00000000)
Boot0008* 5	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(4,9000000,31386030,7c1b0800)HD(2,d001000,1000000,00000000)
Boot0009* 6	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0)HD(4,9000000,31386030,7c1b0800)HD(3,e001800,2c384800,00000000)
Boot000A* 7	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)HD(1,800,7800,2b5f0a55-a8b0-4af0-8cec-6a629a8efdbc)
Boot000B* 8	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)HD(2,8000,f8000,7200f787-52f7-46df-8ba1-17b86a65cb32)
Boot000C* 9	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)HD(3,100000,f00000,fcc49bcf-b9dd-4305-9ce0-01db1979df67)
Boot000D* 10	ACPI(a0341d0,0)PCI(1,1)ATAPI(0,1,0)HD(4,1000000,850f88f,35e9d7e5-86d4-4156-8b60-8c284e010d4d)
Boot000E* EFI Internal Shell	MM(b,5fa55000,5fea4fff)


efibootmgr 32bit run on 64bit kernel on same machine
weird and different output
xwing doc # uname -a
Linux xwing 3.5.2-gentoo #10 SMP PREEMPT Sat Aug 18 18:30:49 ICT 2012 x86_64 Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz GenuineIntel GNU/Linux
xwing doc # file /usr/sbin/efibootmgr 
/usr/sbin/efibootmgr: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped
xwing doc # efibootmgr -v
BootCurrent: 0000
BootOrder: 0000,0000,0000,0001,0002,0003,0004,0005,0006,0007,0008,0009,000A,000B,000C
Boot0000  
wierd path1e 00 30 00                                     	..0.            
	.0........A....................
Boot0001  
wierd path1e 00 31 00                                     	..1.            
	.1........A....................
Boot0002  
wierd path1e 00 32 00                                     	..2.            
	.2........A....................
Boot0003  
wierd path48 00 30 00                                     	H.0.            
	.0........A......................*........................|..............
Boot0004  
wierd path48 00 31 00                                     	H.1.            
	.1........A......................*........................|..............
Boot0005  
wierd path48 00 32 00                                     	H.2.            
	.2........A......................*........................|..............
Boot0006  
wierd path48 00 33 00                                     	H.3.            
	.3........A......................*.............0`81.......|..............
Boot0007  
wierd path72 00 34 00                                     	r.4.            
	.4........A......................*.............0`81.......|................*.......................................
Boot0008  
wierd path72 00 35 00                                     	r.5.            
	.5........A......................*.............0`81.......|................*.......................................
Boot0009  
wierd path72 00 36 00                                     	r.6.            
	.6........A......................*.............0`81.......|................*..............H8,......................
Boot000A  
wierd path48 00 37 00                                     	H.7.            
	.7........A......................*..............x......U._+...J..jb......
Boot000B  
wierd path48 00 38 00                                     	H.8.            
	.8........A......................*........................r.R.F....je.2..
Boot000C  
wierd path48 00 39 00                                     	H.9.            
	.9........A......................*............................C.....y.g..
Boot000D  
wierd path48 00 31 00                                     	H.1.            
	.1.0........A......................*...............P........5..VA.`.(N..M..
Boot000E  
wierd path30 00 45 00                                     	0.E.            
	.E.F.I. .I.n.t.e.r.n.a.l. .S.h.e.l.l............P._.....O._..........z....@.!U.R.N7


For now seems no easy solution here, because x64_64 build is not possible on 32bit userland, so wrapper and eselect is not a viable solution. This may affected x32 ABI too.

So a patch may needed to allow efibootmgr use match data structure for running kernel when reading/writing EFI variable.

Note: Will send a copy of this bug to Matt_Domsch@dell.com
Comment 1 Matt Domsch 2012-08-19 22:43:10 UTC
This was an intentional design decision when the kernel EFI Variables module (efivars) was first written in ~2001.  There are EFI spec-defined fields which are of type LONG which differs between 32-bit and 64-bit EFI environments and kernels, and therefore userspace.

Matthew Garrett (Red Hat) was working on a new efivars kernel module that also removes the restriction on variables being only 1024 bytes max which was in a pre-1.0 spec but was removed by EFI 1.0, but which unfortunately lives on in both efivars and efibootmgr today. I don't know the status there.  With that complete, it may be possible that the new userspace interface would not be 32-bit or 64-bit specific, at which point efibootmgr could be updated to use the new interface.

For now I'd say either "working as designed", or "feel free to fix efivars, and then fix efibootmgr, but you can't fix efibootmgr without fixing efivars first."
Comment 2 Phattanon Duangdara 2012-08-19 23:42:26 UTC
Created attachment 321730 [details, diff]
efibootmgr efivars read/write workaround patch

Attached (dirty) fixes on efivars reading/writing of efibootmgr when running kernel architecture is different from userland.
Comment 3 Phattanon Duangdara 2012-08-20 01:08:48 UTC
Since current efivars have no mechanism to detect if it use 64bit or 32bit long variable. I think we just leave it as is. It will work as long as userland (efibootmgr) and kernel match.

So specific case require updated efibootmgr to check what correct data structure to use when read/write sysfs, which my patch does by uname(), but patch does not correct data write by --test option.

I seems to lucky because I use recent kernels, it was updated to do more strict validation. Writing invalid values to efivars to older kernel may corrupt firmware, and therefore may cause by this case.
Comment 4 Phattanon Duangdara 2012-08-22 00:02:20 UTC
I also found that booting 32bit kernel in 64bit UEFI results kernel OOPs on efivars module.

I guess 32bit kernel try to use 32bit EFI data structure when booting UEFI 64bit, if it do so it definitely a kernel BUG.

So efivars need to be fixed, anyway and at least provide some variables to detect what UEFI platform is using. And efibootmgr will determinate how to handle it.
Comment 5 Mike Gilbert gentoo-dev 2016-12-31 01:59:26 UTC
If this is still a problem, please re-open.