1 /*
2  *  Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 #include <xen/errno.h>
6 #include <xen/kernel.h>
7 #include <xen/lib.h>
8 #include <xen/livepatch_elf.h>
9 #include <xen/livepatch.h>
10 
11 #include <asm/page.h>
12 #include <asm/livepatch.h>
13 
arch_livepatch_apply(struct livepatch_func * func)14 void arch_livepatch_apply(struct livepatch_func *func)
15 {
16     uint32_t insn;
17     uint32_t *new_ptr;
18     unsigned int i, len;
19 
20     BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE > sizeof(func->opaque));
21     BUILD_BUG_ON(ARCH_PATCH_INSN_SIZE != sizeof(insn));
22 
23     ASSERT(vmap_of_xen_text);
24 
25     len = livepatch_insn_len(func);
26     if ( !len )
27         return;
28 
29     /* Save old ones. */
30     memcpy(func->opaque, func->old_addr, len);
31 
32     if ( func->new_addr )
33     {
34         s32 delta;
35 
36         /*
37          * PC is current address (old_addr) + 8 bytes. The semantics for a
38          * unconditional branch is to jump to PC + imm32 (offset).
39          *
40          * ARM DDI 0406C.c, see A2.3 (pg 45) and A8.8.18 pg (pg 334,335)
41          *
42          */
43         delta = (s32)func->new_addr - (s32)(func->old_addr + 8);
44 
45         /* The arch_livepatch_symbol_ok should have caught it. */
46         ASSERT(delta >= -(s32)ARCH_LIVEPATCH_RANGE ||
47                delta < (s32)ARCH_LIVEPATCH_RANGE);
48 
49         /* CPU shifts by two (left) when decoding, so we shift right by two. */
50         delta = delta >> 2;
51         /* Lets not modify the cond. */
52         delta &= 0x00FFFFFF;
53 
54         insn = 0xea000000 | delta;
55     }
56     else
57         insn = 0xe1a00000; /* mov r0, r0 */
58 
59     new_ptr = func->old_addr - (void *)_start + vmap_of_xen_text;
60     len = len / sizeof(uint32_t);
61 
62     /* PATCH! */
63     for ( i = 0; i < len; i++ )
64         *(new_ptr + i) = insn;
65 
66     /*
67     * When we upload the payload, it will go through the data cache
68     * (the region is cacheable). Until the data cache is cleaned, the data
69     * may not reach the memory. And in the case the data and instruction cache
70     * are separated, we may read invalid instruction from the memory because
71     * the data cache have not yet synced with the memory. Hence sync it.
72     */
73     if ( func->new_addr )
74         clean_and_invalidate_dcache_va_range(func->new_addr, func->new_size);
75     clean_and_invalidate_dcache_va_range(new_ptr, sizeof (*new_ptr) * len);
76 }
77 
78 /* arch_livepatch_revert shared with ARM 32/ARM 64. */
79 
arch_livepatch_verify_elf(const struct livepatch_elf * elf)80 int arch_livepatch_verify_elf(const struct livepatch_elf *elf)
81 {
82     const Elf_Ehdr *hdr = elf->hdr;
83 
84     if ( hdr->e_machine != EM_ARM ||
85          hdr->e_ident[EI_CLASS] != ELFCLASS32 )
86     {
87         dprintk(XENLOG_ERR, LIVEPATCH "%s: Unsupported ELF Machine type!\n",
88                 elf->name);
89         return -EOPNOTSUPP;
90     }
91 
92     if ( (hdr->e_flags & EF_ARM_EABI_MASK) != EF_ARM_EABI_VER5 )
93     {
94         dprintk(XENLOG_ERR, LIVEPATCH "%s: Unsupported ELF EABI(%x)!\n",
95                 elf->name, hdr->e_flags);
96         return -EOPNOTSUPP;
97     }
98 
99     return 0;
100 }
101 
arch_livepatch_symbol_deny(const struct livepatch_elf * elf,const struct livepatch_elf_sym * sym)102 bool arch_livepatch_symbol_deny(const struct livepatch_elf *elf,
103                                 const struct livepatch_elf_sym *sym)
104 {
105     /*
106      * Xen does not use Thumb instructions - and we should not see any of
107      * them. If we do, abort.
108      */
109     if ( sym->name && sym->name[0] == '$' && sym->name[1] == 't' )
110         return ( !sym->name[2] || sym->name[2] == '.' );
111 
112     return false;
113 }
114 
get_addend(unsigned char type,void * dest)115 static s32 get_addend(unsigned char type, void *dest)
116 {
117     s32 addend = 0;
118 
119     switch ( type ) {
120     case R_ARM_NONE:
121         /* ignore */
122         break;
123 
124     case R_ARM_ABS32:
125         addend = *(u32 *)dest;
126         break;
127 
128     case R_ARM_REL32:
129         addend = *(u32 *)dest;
130         break;
131 
132     case R_ARM_MOVW_ABS_NC:
133     case R_ARM_MOVT_ABS:
134         addend =  (*(u32 *)dest & 0x00000FFF);
135         addend |= (*(u32 *)dest & 0x000F0000) >> 4;
136         /* Addend is to sign-extend ([19:16],[11:0]). */
137         addend = (s16)addend;
138         break;
139 
140     case R_ARM_CALL:
141     case R_ARM_JUMP24:
142         /* Addend = sign_extend (insn[23:0]) << 2 */
143         addend = ((*(u32 *)dest & 0xFFFFFF) ^ 0x800000) - 0x800000;
144         addend = addend << 2;
145         break;
146     }
147 
148     return addend;
149 }
150 
perform_rel(unsigned char type,void * dest,uint32_t val,s32 addend)151 static int perform_rel(unsigned char type, void *dest, uint32_t val, s32 addend)
152 {
153 
154     switch ( type ) {
155     case R_ARM_NONE:
156         /* ignore */
157         break;
158 
159     case R_ARM_ABS32: /* (S + A) | T */
160         *(u32 *)dest = (val + addend);
161         break;
162 
163     case R_ARM_REL32: /* ((S + A) | T) – P */
164         *(u32 *)dest = (val + addend) - (uint32_t)dest;
165         break;
166 
167     case R_ARM_MOVW_ABS_NC: /* S + A */
168     case R_ARM_MOVT_ABS: /* S + A */
169         /* Clear addend if needed . */
170         if ( addend )
171             *(u32 *)dest &= 0xFFF0F000;
172 
173         if ( type == R_ARM_MOVT_ABS )
174         {
175             /*
176              * Almost the same as MOVW except it uses the 16 bit
177              * high value. Putting it in insn requires shifting right by
178              * 16-bit (as we only have 16-bit for imm.
179              */
180             val &= 0xFFFF0000; /* ResultMask */
181             val = val >> 16;
182         }
183         else
184         {
185             /* MOVW loads 16 bits into the bottom half of a register. */
186             val &= 0xFFFF;
187         }
188         /* [11:0] = Result_Mask(X) & 0xFFF,[19:16] = Result_Mask(X) >> 12 */
189         *(u32 *)dest |= val & 0xFFF;
190         *(u32 *)dest |= (val >> 12) << 16;
191         break;
192 
193     case R_ARM_CALL:
194     case R_ARM_JUMP24: /* (S + A) - P */
195         /* Clear the old addend. */
196         if ( addend )
197             *(u32 *)dest &= 0xFF000000;
198 
199         val += addend - (uint32_t)dest;
200 
201         /*
202          * arch_livepatch_verify_distance can't account of addend so we have
203          * to do the check here as well.
204          */
205         if ( (s32)val < -(s32)ARCH_LIVEPATCH_RANGE ||
206              (s32)val >= (s32)ARCH_LIVEPATCH_RANGE )
207             return -EOVERFLOW;
208 
209         /* CPU always shifts insn by two, so complement it. */
210         val = val >> 2;
211         val &= 0x00FFFFFE;
212         *(u32 *)dest |= (uint32_t)val;
213         break;
214 
215     default:
216          return -EOPNOTSUPP;
217     }
218 
219     return 0;
220 }
221 
arch_livepatch_perform(struct livepatch_elf * elf,const struct livepatch_elf_sec * base,const struct livepatch_elf_sec * rela,bool use_rela)222 int arch_livepatch_perform(struct livepatch_elf *elf,
223                            const struct livepatch_elf_sec *base,
224                            const struct livepatch_elf_sec *rela,
225                            bool use_rela)
226 {
227     unsigned int i;
228     int rc = 0;
229 
230     for ( i = 0; i < (rela->sec->sh_size / rela->sec->sh_entsize); i++ )
231     {
232         unsigned int symndx;
233         uint32_t val;
234         void *dest;
235         unsigned char type;
236         s32 addend;
237 
238         if ( use_rela )
239         {
240             const Elf_RelA *r_a = rela->data + i * rela->sec->sh_entsize;
241 
242             symndx = ELF32_R_SYM(r_a->r_info);
243             type = ELF32_R_TYPE(r_a->r_info);
244             dest = base->load_addr + r_a->r_offset; /* P */
245             addend = r_a->r_addend;
246         }
247         else
248         {
249             const Elf_Rel *r = rela->data + i * rela->sec->sh_entsize;
250 
251             symndx = ELF32_R_SYM(r->r_info);
252             type = ELF32_R_TYPE(r->r_info);
253             dest = base->load_addr + r->r_offset; /* P */
254             addend = get_addend(type, dest);
255         }
256 
257         if ( symndx == STN_UNDEF )
258         {
259             dprintk(XENLOG_ERR, LIVEPATCH "%s: Encountered STN_UNDEF\n",
260                     elf->name);
261             return -EOPNOTSUPP;
262         }
263         else if ( symndx >= elf->nsym )
264         {
265             dprintk(XENLOG_ERR, LIVEPATCH "%s: Relative symbol wants symbol@%u which is past end!\n",
266                     elf->name, symndx);
267             return -EINVAL;
268         }
269         else if ( !elf->sym[symndx].sym )
270         {
271             dprintk(XENLOG_ERR, LIVEPATCH "%s: No relative symbol@%u\n",
272                     elf->name, symndx);
273             return -EINVAL;
274         }
275 
276         val = elf->sym[symndx].sym->st_value; /* S */
277 
278         rc = perform_rel(type, dest, val, addend);
279         switch ( rc )
280         {
281         case -EOVERFLOW:
282             dprintk(XENLOG_ERR, LIVEPATCH "%s: Overflow in relocation %u in %s for %s!\n",
283                     elf->name, i, rela->name, base->name);
284             break;
285 
286         case -EOPNOTSUPP:
287             dprintk(XENLOG_ERR, LIVEPATCH "%s: Unhandled relocation #%x\n",
288                     elf->name, type);
289             break;
290         }
291 
292         if ( rc )
293             break;
294     }
295 
296     return rc;
297 }
298 
arch_livepatch_perform_rel(struct livepatch_elf * elf,const struct livepatch_elf_sec * base,const struct livepatch_elf_sec * rela)299 int arch_livepatch_perform_rel(struct livepatch_elf *elf,
300                                const struct livepatch_elf_sec *base,
301                                const struct livepatch_elf_sec *rela)
302 {
303     return arch_livepatch_perform(elf, base, rela, false);
304 }
305 
arch_livepatch_perform_rela(struct livepatch_elf * elf,const struct livepatch_elf_sec * base,const struct livepatch_elf_sec * rela)306 int arch_livepatch_perform_rela(struct livepatch_elf *elf,
307                                 const struct livepatch_elf_sec *base,
308                                 const struct livepatch_elf_sec *rela)
309 {
310     return arch_livepatch_perform(elf, base, rela, true);
311 }
312 
313 /*
314  * Local variables:
315  * mode: C
316  * c-file-style: "BSD"
317  * c-basic-offset: 4
318  * tab-width: 4
319  * indent-tabs-mode: nil
320  * End:
321  */
322