Commit 5e5a6c54 authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman

lkdtm: Add a test for function descriptors protection

Add WRITE_OPD to check that you can't modify function
descriptors.

Gives the following result when function descriptors are
not protected:

	lkdtm: Performing direct entry WRITE_OPD
	lkdtm: attempting bad 16 bytes write at c00000000269b358
	lkdtm: FAIL: survived bad write
	lkdtm: do_nothing was hijacked!

Looks like a standard compiler barrier() is not enough to force
GCC to use the modified function descriptor. Had to add a fake empty
inline assembly to force GCC to reload the function descriptor.
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Acked-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/7eeba50d16a35e9d799820e43304150225f20197.1644928018.git.christophe.leroy@csgroup.eu
parent 72a86433
...@@ -149,6 +149,7 @@ static const struct crashtype crashtypes[] = { ...@@ -149,6 +149,7 @@ static const struct crashtype crashtypes[] = {
CRASHTYPE(WRITE_RO), CRASHTYPE(WRITE_RO),
CRASHTYPE(WRITE_RO_AFTER_INIT), CRASHTYPE(WRITE_RO_AFTER_INIT),
CRASHTYPE(WRITE_KERN), CRASHTYPE(WRITE_KERN),
CRASHTYPE(WRITE_OPD),
CRASHTYPE(REFCOUNT_INC_OVERFLOW), CRASHTYPE(REFCOUNT_INC_OVERFLOW),
CRASHTYPE(REFCOUNT_ADD_OVERFLOW), CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW), CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
......
...@@ -106,6 +106,7 @@ void __init lkdtm_perms_init(void); ...@@ -106,6 +106,7 @@ void __init lkdtm_perms_init(void);
void lkdtm_WRITE_RO(void); void lkdtm_WRITE_RO(void);
void lkdtm_WRITE_RO_AFTER_INIT(void); void lkdtm_WRITE_RO_AFTER_INIT(void);
void lkdtm_WRITE_KERN(void); void lkdtm_WRITE_KERN(void);
void lkdtm_WRITE_OPD(void);
void lkdtm_EXEC_DATA(void); void lkdtm_EXEC_DATA(void);
void lkdtm_EXEC_STACK(void); void lkdtm_EXEC_STACK(void);
void lkdtm_EXEC_KMALLOC(void); void lkdtm_EXEC_KMALLOC(void);
......
...@@ -44,6 +44,11 @@ static noinline void do_overwritten(void) ...@@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
return; return;
} }
static noinline void do_almost_nothing(void)
{
pr_info("do_nothing was hijacked!\n");
}
static void *setup_function_descriptor(func_desc_t *fdesc, void *dst) static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
{ {
if (!have_function_descriptors()) if (!have_function_descriptors())
...@@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void) ...@@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
do_overwritten(); do_overwritten();
} }
void lkdtm_WRITE_OPD(void)
{
size_t size = sizeof(func_desc_t);
void (*func)(void) = do_nothing;
if (!have_function_descriptors()) {
pr_info("XFAIL: Platform doesn't use function descriptors.\n");
return;
}
pr_info("attempting bad %zu bytes write at %px\n", size, do_nothing);
memcpy(do_nothing, do_almost_nothing, size);
pr_err("FAIL: survived bad write\n");
asm("" : "=m"(func));
func();
}
void lkdtm_EXEC_DATA(void) void lkdtm_EXEC_DATA(void)
{ {
execute_location(data_area, CODE_WRITE); execute_location(data_area, CODE_WRITE);
......
...@@ -44,6 +44,7 @@ ACCESS_NULL ...@@ -44,6 +44,7 @@ ACCESS_NULL
WRITE_RO WRITE_RO
WRITE_RO_AFTER_INIT WRITE_RO_AFTER_INIT
WRITE_KERN WRITE_KERN
WRITE_OPD
REFCOUNT_INC_OVERFLOW REFCOUNT_INC_OVERFLOW
REFCOUNT_ADD_OVERFLOW REFCOUNT_ADD_OVERFLOW
REFCOUNT_INC_NOT_ZERO_OVERFLOW REFCOUNT_INC_NOT_ZERO_OVERFLOW
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment