1 /*
2  * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
3  *
4  */
5 
6 #ifndef __XEN_LIVEPATCH_H__
7 #define __XEN_LIVEPATCH_H__
8 
9 struct livepatch_elf;
10 struct livepatch_elf_sec;
11 struct livepatch_elf_sym;
12 struct xen_sysctl_livepatch_op;
13 
14 #include <xen/elfstructs.h>
15 #include <xen/errno.h> /* For -ENOSYS or -EOVERFLOW */
16 #ifdef CONFIG_LIVEPATCH
17 
18 /*
19  * We use alternative and exception table code - which by default are __init
20  * only, however we need them during runtime. These macros allows us to build
21  * the image with these functions built-in. (See the #else below).
22  */
23 #define init_or_livepatch_const
24 #define init_or_livepatch_constrel
25 #define init_or_livepatch_data
26 #define init_or_livepatch_read_mostly __read_mostly
27 #define init_or_livepatch
28 
29 /* Convenience define for printk. */
30 #define LIVEPATCH             "livepatch: "
31 /* ELF payload special section names. */
32 #define ELF_LIVEPATCH_FUNC        ".livepatch.funcs"
33 #define ELF_LIVEPATCH_DEPENDS     ".livepatch.depends"
34 #define ELF_LIVEPATCH_XEN_DEPENDS ".livepatch.xen_depends"
35 #define ELF_BUILD_ID_NOTE         ".note.gnu.build-id"
36 #define ELF_LIVEPATCH_LOAD_HOOKS      ".livepatch.hooks.load"
37 #define ELF_LIVEPATCH_UNLOAD_HOOKS    ".livepatch.hooks.unload"
38 #define ELF_LIVEPATCH_PREAPPLY_HOOK   ".livepatch.hooks.preapply"
39 #define ELF_LIVEPATCH_APPLY_HOOK      ".livepatch.hooks.apply"
40 #define ELF_LIVEPATCH_POSTAPPLY_HOOK  ".livepatch.hooks.postapply"
41 #define ELF_LIVEPATCH_PREREVERT_HOOK  ".livepatch.hooks.prerevert"
42 #define ELF_LIVEPATCH_REVERT_HOOK     ".livepatch.hooks.revert"
43 #define ELF_LIVEPATCH_POSTREVERT_HOOK ".livepatch.hooks.postrevert"
44 /* Arbitrary limit for payload size and .bss section size. */
45 #define LIVEPATCH_MAX_SIZE     MB(2)
46 
47 struct livepatch_symbol {
48     const char *name;
49     unsigned long value;
50     unsigned int size;
51     bool_t new_symbol;
52 };
53 
54 int livepatch_op(struct xen_sysctl_livepatch_op *);
55 void check_for_livepatch_work(void);
56 unsigned long livepatch_symbols_lookup_by_name(const char *symname);
57 bool_t is_patch(const void *addr);
58 
59 /* Arch hooks. */
60 int arch_livepatch_verify_elf(const struct livepatch_elf *elf);
61 bool arch_livepatch_symbol_ok(const struct livepatch_elf *elf,
62                               const struct livepatch_elf_sym *sym);
63 bool arch_livepatch_symbol_deny(const struct livepatch_elf *elf,
64                                 const struct livepatch_elf_sym *sym);
65 int arch_livepatch_perform_rel(struct livepatch_elf *elf,
66                                const struct livepatch_elf_sec *base,
67                                const struct livepatch_elf_sec *rela);
68 int arch_livepatch_perform_rela(struct livepatch_elf *elf,
69                                 const struct livepatch_elf_sec *base,
70                                 const struct livepatch_elf_sec *rela);
71 enum va_type {
72     LIVEPATCH_VA_RX, /* .text */
73     LIVEPATCH_VA_RW, /* .data */
74     LIVEPATCH_VA_RO, /* .rodata */
75 };
76 
77 /*
78  * Function to secure the allocate pages (from arch_livepatch_alloc_payload)
79  * with the right page permissions.
80  */
81 int arch_livepatch_secure(const void *va, unsigned int pages, enum va_type types);
82 
83 void arch_livepatch_init(void);
84 
85 #include <public/sysctl.h> /* For struct livepatch_func. */
86 #include <asm/livepatch.h>
87 int arch_livepatch_verify_func(const struct livepatch_func *func);
88 
89 static inline
livepatch_insn_len(const struct livepatch_func * func)90 unsigned int livepatch_insn_len(const struct livepatch_func *func)
91 {
92     if ( !func->new_addr )
93         return func->new_size;
94 
95     return ARCH_PATCH_INSN_SIZE;
96 }
97 
livepatch_verify_distance(const struct livepatch_func * func)98 static inline int livepatch_verify_distance(const struct livepatch_func *func)
99 {
100     long offset;
101     long range = ARCH_LIVEPATCH_RANGE;
102 
103     if ( !func->new_addr ) /* Ignore NOPs. */
104         return 0;
105 
106     offset = func->old_addr - func->new_addr;
107     if ( offset < -range || offset >= range )
108         return -EOVERFLOW;
109 
110     return 0;
111 }
112 /*
113  * These functions are called around the critical region patching live code,
114  * for an architecture to take make appropratie global state adjustments.
115  */
116 int arch_livepatch_safety_check(void);
117 int arch_livepatch_quiesce(void);
118 void arch_livepatch_revive(void);
119 
120 void arch_livepatch_apply(struct livepatch_func *func);
121 void arch_livepatch_revert(const struct livepatch_func *func);
122 void arch_livepatch_post_action(void);
123 
124 void arch_livepatch_mask(void);
125 void arch_livepatch_unmask(void);
126 
common_livepatch_apply(struct livepatch_func * func)127 static inline void common_livepatch_apply(struct livepatch_func *func)
128 {
129     /* If the action has been already executed on this function, do nothing. */
130     if ( func->applied == LIVEPATCH_FUNC_APPLIED )
131     {
132         printk(XENLOG_WARNING LIVEPATCH "%s: %s has been already applied before\n",
133                 __func__, func->name);
134         return;
135     }
136 
137     arch_livepatch_apply(func);
138     func->applied = LIVEPATCH_FUNC_APPLIED;
139 }
140 
common_livepatch_revert(struct livepatch_func * func)141 static inline void common_livepatch_revert(struct livepatch_func *func)
142 {
143     /* If the apply action hasn't been executed on this function, do nothing. */
144     if ( !func->old_addr || func->applied == LIVEPATCH_FUNC_NOT_APPLIED )
145     {
146         printk(XENLOG_WARNING LIVEPATCH "%s: %s has not been applied before\n",
147                 __func__, func->name);
148         return;
149     }
150 
151     arch_livepatch_revert(func);
152     func->applied = LIVEPATCH_FUNC_NOT_APPLIED;
153 }
154 #else
155 
156 /*
157  * If not compiling with Live Patch certain functionality should stay as
158  * __init.
159  */
160 #define init_or_livepatch_const       __initconst
161 #define init_or_livepatch_constrel    __initconstrel
162 #define init_or_livepatch_data        __initdata
163 #define init_or_livepatch_read_mostly __initdata
164 #define init_or_livepatch             __init
165 
livepatch_op(struct xen_sysctl_livepatch_op * op)166 static inline int livepatch_op(struct xen_sysctl_livepatch_op *op)
167 {
168     return -ENOSYS;
169 }
170 
check_for_livepatch_work(void)171 static inline void check_for_livepatch_work(void) { };
is_patch(const void * addr)172 static inline bool_t is_patch(const void *addr)
173 {
174     return 0;
175 }
176 #endif /* CONFIG_LIVEPATCH */
177 
178 #endif /* __XEN_LIVEPATCH_H__ */
179 
180 /*
181  * Local variables:
182  * mode: C
183  * c-file-style: "BSD"
184  * c-basic-offset: 4
185  * tab-width: 4
186  * indent-tabs-mode: nil
187  * End:
188  */
189