diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-02-09 08:36:24 -0800 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-02-09 08:36:24 -0800 |
commit | 243b23fbf1f58577a2cfadc64b6f4c0d12f1491e (patch) | |
tree | 917801ba6b6ba2867e660b968765ffd8d66e47a5 | |
parent | 613cf530f09fc1b27701b1be2538730539415db4 (diff) | |
download | efitools-243b23fbf1f58577a2cfadc64b6f4c0d12f1491e.tar.gz |
security_policy: switch to EFIAPI calling convention
Remove the assembly thunk that converts between EFI and C calling conventions
on x86_64 and use the EFIAPI tag instead, which informs gcc to use the EFI
calling conventions for the function. This means security_policy.o can now be
built unconditionally for all architectures
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | Make.rules | 3 | ||||
-rw-r--r-- | lib/Makefile | 6 | ||||
-rw-r--r-- | lib/security_policy.c | 123 |
3 files changed, 13 insertions, 119 deletions
@@ -29,6 +29,9 @@ MANDIR = $(DESTDIR)/usr/share/man/man1 EFIDIR = $(DESTDIR)/usr/share/efitools/efi DOCDIR = $(DESTDIR)/usr/share/efitools +# globally use EFI calling conventions (requires gcc >= 4.7) +CFLAGS += -DGNU_EFI_USE_MS_ABI + ifeq ($(ARCH),x86_64) CFLAGS += -DEFI_FUNCTION_WRAPPER endif diff --git a/lib/Makefile b/lib/Makefile index 945805c..92b4d8f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,8 +1,6 @@ FILES = simple_file.o pecoff.o guid.o sha256.o console.o \ - execute.o configtable.o shell.o -ifeq ($(ARCH),x86_64) -FILES += security_policy.o -endif + execute.o configtable.o shell.o security_policy.o + LIBFILES = $(FILES) kernel_efivars.o EFILIBFILES = $(patsubst %.o,%.efi.o,$(FILES)) variables.o diff --git a/lib/security_policy.c b/lib/security_policy.c index b688763..39654d4 100644 --- a/lib/security_policy.c +++ b/lib/security_policy.c @@ -107,23 +107,8 @@ security_policy_check_mok(void *data, UINTN len) static EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL; static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL; -static EFI_STATUS thunk_security_policy_authentication( - const EFI_SECURITY_PROTOCOL *This, - UINT32 AuthenticationStatus, - const EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -__attribute__((unused)); - -static EFI_STATUS thunk_security2_policy_authentication( - const EFI_SECURITY2_PROTOCOL *This, - const EFI_DEVICE_PATH_PROTOCOL *DevicePath, - VOID *FileBuffer, - UINTN FileSize, - BOOLEAN BootPolicy - ) -__attribute__((unused)); - -static __attribute__((used)) EFI_STATUS +EFI_STATUS +EFIAPI security2_policy_authentication ( const EFI_SECURITY2_PROTOCOL *This, const EFI_DEVICE_PATH_PROTOCOL *DevicePath, @@ -154,7 +139,8 @@ security2_policy_authentication ( return auth; } -static __attribute__((used)) EFI_STATUS +EFI_STATUS +EFIAPI security_policy_authentication ( const EFI_SECURITY_PROTOCOL *This, UINT32 AuthenticationStatus, @@ -213,99 +199,6 @@ security_policy_authentication ( return status; } - -/* Nasty: ELF and EFI have different calling conventions. Here is the map for - * calling ELF -> EFI - * - * 1) rdi -> rcx (32 saved) - * 2) rsi -> rdx (32 saved) - * 3) rdx -> r8 ( 32 saved) - * 4) rcx -> r9 (32 saved) - * 5) r8 -> 32(%rsp) (48 saved) - * 6) r9 -> 40(%rsp) (48 saved) - * 7) pad+0(%rsp) -> 48(%rsp) (64 saved) - * 8) pad+8(%rsp) -> 56(%rsp) (64 saved) - * 9) pad+16(%rsp) -> 64(%rsp) (80 saved) - * 10) pad+24(%rsp) -> 72(%rsp) (80 saved) - * 11) pad+32(%rsp) -> 80(%rsp) (96 saved) - - * - * So for a five argument callback, the map is ignore the first two arguments - * and then map (EFI -> ELF) assuming pad = 0. - * - * ARG4 -> ARG1 - * ARG3 -> ARG2 - * ARG5 -> ARG3 - * ARG6 -> ARG4 - * ARG11 -> ARG5 - * - * Calling conventions also differ over volatile and preserved registers in - * MS: RBX, RBP, RDI, RSI, R12, R13, R14, and R15 are considered nonvolatile . - * In ELF: Registers %rbp, %rbx and %r12 through %r15 “belong” to the calling - * function and the called function is required to preserve their values. - * - * This means when accepting a function callback from MS -> ELF, we have to do - * separate preservation on %rdi, %rsi before swizzling the arguments and - * handing off to the ELF function. - */ - -asm ( -".type security2_policy_authentication,@function\n" -"thunk_security2_policy_authentication:\n\t" - "mov 0x28(%rsp), %r10 # ARG5\n\t" - "push %rdi\n\t" - "push %rsi\n\t" - "mov %r10, %rdi\n\t" - "subq $8, %rsp # space for storing stack pad\n\t" - "mov $0x08, %rax\n\t" - "mov $0x10, %r10\n\t" - "and %rsp, %rax\n\t" - "cmovnz %rax, %r11\n\t" - "cmovz %r10, %r11\n\t" - "subq %r11, %rsp\n\t" - "addq $8, %r11\n\t" - "mov %r11, (%rsp)\n\t" -"# five argument swizzle\n\t" - "mov %rdi, %r10\n\t" - "mov %rcx, %rdi\n\t" - "mov %rdx, %rsi\n\t" - "mov %r8, %rdx\n\t" - "mov %r9, %rcx\n\t" - "mov %r10, %r8\n\t" - "callq security2_policy_authentication@PLT\n\t" - "mov (%rsp), %r11\n\t" - "addq %r11, %rsp\n\t" - "pop %rsi\n\t" - "pop %rdi\n\t" - "ret\n" -); - -asm ( -".type security_policy_authentication,@function\n" -"thunk_security_policy_authentication:\n\t" - "push %rdi\n\t" - "push %rsi\n\t" - "subq $8, %rsp # space for storing stack pad\n\t" - "mov $0x08, %rax\n\t" - "mov $0x10, %r10\n\t" - "and %rsp, %rax\n\t" - "cmovnz %rax, %r11\n\t" - "cmovz %r10, %r11\n\t" - "subq %r11, %rsp\n\t" - "addq $8, %r11\n\t" - "mov %r11, (%rsp)\n\t" -"# three argument swizzle\n\t" - "mov %rcx, %rdi\n\t" - "mov %rdx, %rsi\n\t" - "mov %r8, %rdx\n\t" - "callq security_policy_authentication@PLT\n\t" - "mov (%rsp), %r11\n\t" - "addq %r11, %rsp\n\t" - "pop %rsi\n\t" - "pop %rdi\n\t" - "ret\n" -); - EFI_STATUS security_policy_install(void) { @@ -334,19 +227,19 @@ security_policy_install(void) if (security2_protocol) { es2fa = security2_protocol->FileAuthentication; security2_protocol->FileAuthentication = - thunk_security2_policy_authentication; + security2_policy_authentication; /* check for security policy in write protected memory */ if (security2_protocol->FileAuthentication - != thunk_security2_policy_authentication) + != security2_policy_authentication) return EFI_ACCESS_DENIED; } esfas = security_protocol->FileAuthenticationState; security_protocol->FileAuthenticationState = - thunk_security_policy_authentication; + security_policy_authentication; /* check for security policy in write protected memory */ if (security_protocol->FileAuthenticationState - != thunk_security_policy_authentication) + != security_policy_authentication) return EFI_ACCESS_DENIED; return EFI_SUCCESS; |