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: Christophe Leroy <christophe.leroy@csgroup.eu> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/7eeba50d16a35e9d799820e43304150225f20197.1644928018.git.christophe.leroy@csgroup.eu
This commit is contained in:
Родитель
72a8643304
Коммит
5e5a6c5441
|
@ -149,6 +149,7 @@ static const struct crashtype crashtypes[] = {
|
|||
CRASHTYPE(WRITE_RO),
|
||||
CRASHTYPE(WRITE_RO_AFTER_INIT),
|
||||
CRASHTYPE(WRITE_KERN),
|
||||
CRASHTYPE(WRITE_OPD),
|
||||
CRASHTYPE(REFCOUNT_INC_OVERFLOW),
|
||||
CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
|
||||
CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
|
||||
|
|
|
@ -106,6 +106,7 @@ void __init lkdtm_perms_init(void);
|
|||
void lkdtm_WRITE_RO(void);
|
||||
void lkdtm_WRITE_RO_AFTER_INIT(void);
|
||||
void lkdtm_WRITE_KERN(void);
|
||||
void lkdtm_WRITE_OPD(void);
|
||||
void lkdtm_EXEC_DATA(void);
|
||||
void lkdtm_EXEC_STACK(void);
|
||||
void lkdtm_EXEC_KMALLOC(void);
|
||||
|
|
|
@ -44,6 +44,11 @@ static noinline void do_overwritten(void)
|
|||
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)
|
||||
{
|
||||
if (!have_function_descriptors())
|
||||
|
@ -144,6 +149,23 @@ void lkdtm_WRITE_KERN(void)
|
|||
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)
|
||||
{
|
||||
execute_location(data_area, CODE_WRITE);
|
||||
|
|
|
@ -44,6 +44,7 @@ ACCESS_NULL
|
|||
WRITE_RO
|
||||
WRITE_RO_AFTER_INIT
|
||||
WRITE_KERN
|
||||
WRITE_OPD
|
||||
REFCOUNT_INC_OVERFLOW
|
||||
REFCOUNT_ADD_OVERFLOW
|
||||
REFCOUNT_INC_NOT_ZERO_OVERFLOW
|
||||
|
|
Загрузка…
Ссылка в новой задаче