[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 4/4] x86/livepatch: perform sanity checks on the payload exception table contents
Ensure the entries of a payload exception table only apply to text regions in the payload itself. Since the payload exception table needs to be loaded and active even before a patch is applied (because hooks might already rely on it), make sure the exception table (if any) only contains fixups for the payload text section. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- Changes since v3: - Rename to extable_in_bounds(). - Use _p() instead of casting to void *. Changes since v2: - New in this version. --- xen/arch/x86/extable.c | 18 ++++++++++++++++++ xen/arch/x86/include/asm/uaccess.h | 3 +++ xen/common/livepatch.c | 9 +++++++++ 3 files changed, 30 insertions(+) diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c index 8415cd1fa249..2be090b92df8 100644 --- a/xen/arch/x86/extable.c +++ b/xen/arch/x86/extable.c @@ -228,3 +228,21 @@ unsigned long asmlinkage search_pre_exception_table(struct cpu_user_regs *regs) } return fixup; } + +#ifdef CONFIG_LIVEPATCH +bool extable_in_bounds(const struct exception_table_entry *ex_start, + const struct exception_table_entry *ex_end, + const void *start, const void *end) +{ + for ( ; ex_start < ex_end; ex_start++ ) + { + const void *addr = _p(ex_addr(ex_start)); + const void *cont = _p(ex_cont(ex_start)); + + if ( addr < start || addr >= end || cont < start || cont >= end ) + return false; + } + + return true; +} +#endif diff --git a/xen/arch/x86/include/asm/uaccess.h b/xen/arch/x86/include/asm/uaccess.h index 48b684c19d44..4995edfdd8db 100644 --- a/xen/arch/x86/include/asm/uaccess.h +++ b/xen/arch/x86/include/asm/uaccess.h @@ -426,5 +426,8 @@ extern unsigned long search_exception_table(const struct cpu_user_regs *regs, extern void sort_exception_tables(void); extern void sort_exception_table(struct exception_table_entry *start, const struct exception_table_entry *stop); +extern bool extable_in_bounds(const struct exception_table_entry *ex_start, + const struct exception_table_entry *ex_end, + const void *start, const void *end); #endif /* __X86_UACCESS_H__ */ diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c index 1afde0281402..4702c06902a9 100644 --- a/xen/common/livepatch.c +++ b/xen/common/livepatch.c @@ -912,6 +912,15 @@ static int prepare_payload(struct payload *payload, s = sec->load_addr; e = sec->load_addr + sec->sec->sh_size; + if ( !extable_in_bounds(s, e, payload->text_addr, + payload->text_addr + payload->text_size) ) + { + printk(XENLOG_ERR LIVEPATCH + "%s: Invalid exception table with out of bounds entries\n", + elf->name); + return -EINVAL; + } + sort_exception_table(s ,e); region->ex = s; -- 2.44.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |