Skip to content

Commit 74d613e

Browse files
committed
efi/libstub: Avoid CopyMem/SetMem EFI services after ExitBootServices
Given that memset/memcpy are intrinsics, the compiler might insert calls to these routines unexpectedly, including in code that executes after ExitBootServices(). In this case, the respective boot services are no longer accessible, and calling them will cause a crash. So fall back to a bytewise copy/store if this happens to occur, even though no such occurrences are known to exist in the kernel currently. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent ac2efaa commit 74d613e

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

drivers/firmware/efi/libstub/intrinsics.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,31 @@ void *__memmove(void *__dest, const void *__src, size_t count) __alias(memmove);
1515
void *__memset(void *s, int c, size_t count) __alias(memset);
1616
#endif
1717

18+
static void *efistub_memmove(u8 *dst, const u8 *src, size_t len)
19+
{
20+
if (src > dst || dst >= (src + len))
21+
for (size_t i = 0; i < len; i++)
22+
dst[i] = src[i];
23+
else
24+
for (ssize_t i = len - 1; i >= 0; i--)
25+
dst[i] = src[i];
26+
27+
return dst;
28+
}
29+
30+
static void *efistub_memset(void *dst, int c, size_t len)
31+
{
32+
for (u8 *d = dst; len--; d++)
33+
*d = c;
34+
35+
return dst;
36+
}
37+
1838
void *memcpy(void *dst, const void *src, size_t len)
1939
{
40+
if (efi_table_attr(efi_system_table, boottime) == NULL)
41+
return efistub_memmove(dst, src, len);
42+
2043
efi_bs_call(copy_mem, dst, src, len);
2144
return dst;
2245
}
@@ -25,6 +48,9 @@ extern void *memmove(void *dst, const void *src, size_t len) __alias(memcpy);
2548

2649
void *memset(void *dst, int c, size_t len)
2750
{
51+
if (efi_table_attr(efi_system_table, boottime) == NULL)
52+
return efistub_memset(dst, c, len);
53+
2854
efi_bs_call(set_mem, dst, len, c & U8_MAX);
2955
return dst;
3056
}

0 commit comments

Comments
 (0)