(empty log message)
@@ -176,6 +176,86 @@ | ||
176 | 176 | } while (0); |
177 | 177 | } |
178 | 178 | |
179 | +#if defined(CONFIG_ARM64) | |
180 | + | |
181 | +/** | |
182 | + * probe_security_hook_heads_on_arm - Find security_hook_heads on ARM64. | |
183 | + * | |
184 | + * @base: Address of security_bprm_committed_creds(). | |
185 | + * | |
186 | + * Returns address of security_hook_heads.bprm_committed_creds on success, | |
187 | + * NULL otherwise. | |
188 | + */ | |
189 | +static void * __init probe_security_hook_heads_on_arm64(unsigned int *base) | |
190 | +{ | |
191 | + static unsigned int *ip4ret; | |
192 | + int i; | |
193 | + unsigned int *ip = (unsigned int *) base; | |
194 | + | |
195 | + for (i = 0; i < 32; ip++, i++) { | |
196 | + unsigned long tmp; | |
197 | + unsigned long offset; | |
198 | + /* | |
199 | + * Find | |
200 | + * adrp Xd, #imm21 | |
201 | + * add Xd, Xn, #uimm12 | |
202 | + * add Xd, Xn, #uimm12 | |
203 | + * sequence. | |
204 | + * But don't mandate the last one in case it was optimized. | |
205 | + */ | |
206 | + if ((*ip & 0x98000000) != 0x90000000 || | |
207 | + (*(ip + 1) & 0xFFC00000) != 0x91000000) | |
208 | + continue; | |
209 | + tmp = ((unsigned long) ip) & ~0xFFFUL; | |
210 | + offset = (unsigned long) (((((*ip >> 5) & 0x007FFFF) << 2) | | |
211 | + ((*ip >> 29) & 0x3))) << 12; | |
212 | + if (offset & 0x100000000UL) | |
213 | + offset |= 0xFFFFFFFF00000000UL; | |
214 | + tmp += offset; | |
215 | + offset = (*(ip + 1) >> 10) & 0xFFF; | |
216 | + tmp += offset; | |
217 | + if ((*(ip + 2) & 0xFFC00000) == 0x91000000) { | |
218 | + offset = (*(ip + 2) >> 10) & 0xFFF; | |
219 | + tmp += offset; | |
220 | + } | |
221 | + ip4ret = (unsigned int *) tmp; | |
222 | + return &ip4ret; | |
223 | + } | |
224 | + return NULL; | |
225 | +} | |
226 | + | |
227 | +#endif | |
228 | + | |
229 | +#if defined(CONFIG_ARM) | |
230 | + | |
231 | +/** | |
232 | + * probe_security_hook_heads_on_arm - Find security_hook_heads on ARM. | |
233 | + * | |
234 | + * @base: Address of security_bprm_committed_creds(). | |
235 | + * | |
236 | + * Returns address of security_hook_heads.bprm_committed_creds on success, | |
237 | + * NULL otherwise. | |
238 | + */ | |
239 | +static void * __init probe_security_hook_heads_on_arm(unsigned int *base) | |
240 | +{ | |
241 | + static unsigned int *ip4ret; | |
242 | + int i; | |
243 | + const unsigned long addr = (unsigned long) &probe_dummy_security_hook_heads; | |
244 | + const unsigned long offset = (unsigned long) &probe_dummy_security_hook_heads.bprm_committed_creds - addr; | |
245 | + unsigned int *ip = (unsigned int *) probe_security_bprm_committed_creds; | |
246 | + for (i = 0; i < 32; ip++, i++) { | |
247 | + if (*(ip + 2 + ((*ip & 0xFFF) >> 2)) != addr) | |
248 | + continue; | |
249 | + ip = base + i; | |
250 | + ip4ret = (unsigned int *) (*(ip + 2 + ((*ip & 0xFFF) >> 2))); | |
251 | + ip4ret += offset >> 2; | |
252 | + return &ip4ret; | |
253 | + } | |
254 | + return NULL; | |
255 | +} | |
256 | + | |
257 | +#endif | |
258 | + | |
179 | 259 | #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) |
180 | 260 | |
181 | 261 | /* |
@@ -300,6 +380,14 @@ | ||
300 | 380 | base = __symbol_get(symbol); |
301 | 381 | if (!base) |
302 | 382 | return NULL; |
383 | +#if defined(CONFIG_ARM64) && defined(LSM_HOOK_INIT) | |
384 | + if (function == probe_security_bprm_committed_creds) | |
385 | + return probe_security_hook_heads_on_arm64((unsigned int *) base); | |
386 | +#endif | |
387 | +#if defined(CONFIG_ARM) && defined(LSM_HOOK_INIT) | |
388 | + if (function == probe_security_bprm_committed_creds) | |
389 | + return probe_security_hook_heads_on_arm((unsigned int *) base); | |
390 | +#endif | |
303 | 391 | #if defined(CONFIG_ARM) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) && !defined(LSM_HOOK_INIT) |
304 | 392 | if (function == probe_security_file_alloc) |
305 | 393 | return probe_security_ops_on_arm((unsigned int *) base); |