aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2016-02-09 08:36:24 -0800
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2016-02-09 08:36:24 -0800
commit243b23fbf1f58577a2cfadc64b6f4c0d12f1491e (patch)
tree917801ba6b6ba2867e660b968765ffd8d66e47a5
parent613cf530f09fc1b27701b1be2538730539415db4 (diff)
downloadefitools-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.rules3
-rw-r--r--lib/Makefile6
-rw-r--r--lib/security_policy.c123
3 files changed, 13 insertions, 119 deletions
diff --git a/Make.rules b/Make.rules
index 1a1ef5c..f3251ff 100644
--- a/Make.rules
+++ b/Make.rules
@@ -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;