Commit e1478d8e authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman

asm-generic: Refactor dereference_[kernel]_function_descriptor()

dereference_function_descriptor() and
dereference_kernel_function_descriptor() are identical on the
three architectures implementing them.

Make them common and put them out-of-line in kernel/extable.c
which is one of the users and has similar type of functions.
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
Acked-by: default avatarHelge Deller <deller@gmx.de>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/449db09b2eba57f4ab05f80102a67d8675bc8bcd.1644928018.git.christophe.leroy@csgroup.eu
parent 0dc690e4
...@@ -30,23 +30,4 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b ...@@ -30,23 +30,4 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
extern char __start_unwind[], __end_unwind[]; extern char __start_unwind[], __end_unwind[];
extern char __start_ivt_text[], __end_ivt_text[]; extern char __start_ivt_text[], __end_ivt_text[];
#undef dereference_function_descriptor
static inline void *dereference_function_descriptor(void *ptr)
{
struct fdesc *desc = ptr;
void *p;
if (!get_kernel_nofault(p, (void *)&desc->addr))
ptr = p;
return ptr;
}
#undef dereference_kernel_function_descriptor
static inline void *dereference_kernel_function_descriptor(void *ptr)
{
if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
return ptr;
return dereference_function_descriptor(ptr);
}
#endif /* _ASM_IA64_SECTIONS_H */ #endif /* _ASM_IA64_SECTIONS_H */
...@@ -12,13 +12,4 @@ typedef Elf64_Fdesc func_desc_t; ...@@ -12,13 +12,4 @@ typedef Elf64_Fdesc func_desc_t;
extern char __alt_instructions[], __alt_instructions_end[]; extern char __alt_instructions[], __alt_instructions_end[];
#ifdef CONFIG_64BIT
#undef dereference_function_descriptor
void *dereference_function_descriptor(void *);
#undef dereference_kernel_function_descriptor
void *dereference_kernel_function_descriptor(void *);
#endif
#endif #endif
...@@ -263,27 +263,6 @@ __get_wchan(struct task_struct *p) ...@@ -263,27 +263,6 @@ __get_wchan(struct task_struct *p)
return 0; return 0;
} }
#ifdef CONFIG_64BIT
void *dereference_function_descriptor(void *ptr)
{
Elf64_Fdesc *desc = ptr;
void *p;
if (!get_kernel_nofault(p, (void *)&desc->addr))
ptr = p;
return ptr;
}
void *dereference_kernel_function_descriptor(void *ptr)
{
if (ptr < (void *)__start_opd ||
ptr >= (void *)__end_opd)
return ptr;
return dereference_function_descriptor(ptr);
}
#endif
static inline unsigned long brk_rnd(void) static inline unsigned long brk_rnd(void)
{ {
return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT; return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
......
...@@ -58,29 +58,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end) ...@@ -58,29 +58,6 @@ static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
(unsigned long)_stext < end; (unsigned long)_stext < end;
} }
#ifdef PPC64_ELF_ABI_v1
#undef dereference_function_descriptor
static inline void *dereference_function_descriptor(void *ptr)
{
struct func_desc *desc = ptr;
void *p;
if (!get_kernel_nofault(p, (void *)&desc->addr))
ptr = p;
return ptr;
}
#undef dereference_kernel_function_descriptor
static inline void *dereference_kernel_function_descriptor(void *ptr)
{
if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
return ptr;
return dereference_function_descriptor(ptr);
}
#endif /* PPC64_ELF_ABI_v1 */
#endif #endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -60,6 +60,8 @@ extern __visible const void __nosave_begin, __nosave_end; ...@@ -60,6 +60,8 @@ extern __visible const void __nosave_begin, __nosave_end;
/* Function descriptor handling (if any). Override in asm/sections.h */ /* Function descriptor handling (if any). Override in asm/sections.h */
#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS #ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
void *dereference_function_descriptor(void *ptr);
void *dereference_kernel_function_descriptor(void *ptr);
#else #else
#define dereference_function_descriptor(p) ((void *)(p)) #define dereference_function_descriptor(p) ((void *)(p))
#define dereference_kernel_function_descriptor(p) ((void *)(p)) #define dereference_kernel_function_descriptor(p) ((void *)(p))
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM. Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
*/ */
#include <linux/elf.h>
#include <linux/ftrace.h> #include <linux/ftrace.h>
#include <linux/memory.h> #include <linux/memory.h>
#include <linux/extable.h> #include <linux/extable.h>
...@@ -132,12 +133,32 @@ int kernel_text_address(unsigned long addr) ...@@ -132,12 +133,32 @@ int kernel_text_address(unsigned long addr)
} }
/* /*
* On some architectures (PPC64, IA64) function pointers * On some architectures (PPC64, IA64, PARISC) function pointers
* are actually only tokens to some data that then holds the * are actually only tokens to some data that then holds the
* real function address. As a result, to find if a function * real function address. As a result, to find if a function
* pointer is part of the kernel text, we need to do some * pointer is part of the kernel text, we need to do some
* special dereferencing first. * special dereferencing first.
*/ */
#ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
void *dereference_function_descriptor(void *ptr)
{
func_desc_t *desc = ptr;
void *p;
if (!get_kernel_nofault(p, (void *)&desc->addr))
ptr = p;
return ptr;
}
void *dereference_kernel_function_descriptor(void *ptr)
{
if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
return ptr;
return dereference_function_descriptor(ptr);
}
#endif
int func_ptr_is_kernel_text(void *ptr) int func_ptr_is_kernel_text(void *ptr)
{ {
unsigned long addr; unsigned long addr;
......
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