1 /* $OpenBSD: loadfile_subr.c,v 1.3 2013/03/21 21:50:59 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2010 Miodrag Vallat. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <lib/libkern/libkern.h> 22 23 #include <sys/exec_elf.h> 24 #include <lib/libsa/loadfile.h> 25 26 #include <machine/alpha_cpu.h> 27 #include <machine/rpb.h> 28 29 #define ptoa(a) ((a) << PAGE_SHIFT) 30 31 /* 32 * Prevent loading a kernel if it would overlap the SRM. 33 */ 34 int 35 check_phdr(void *hdr) 36 { 37 Elf64_Phdr *phdr = (Elf64_Phdr *)hdr; 38 struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR; 39 struct mddt *mddtp; 40 struct mddt_cluster *memc; 41 u_int64_t cstart, cend; 42 u_int64_t i; 43 44 mddtp = (struct mddt *)(((caddr_t)hwrpb) + hwrpb->rpb_memdat_off); 45 for (i = 0; i < mddtp->mddt_cluster_cnt; i++) { 46 memc = &mddtp->mddt_clusters[i]; 47 if (memc->mddt_usage & MDDT_PALCODE) { 48 cstart = ALPHA_PHYS_TO_K0SEG(ptoa(memc->mddt_pfn)); 49 cend = cstart + ptoa(memc->mddt_pg_cnt); 50 51 if (phdr->p_vaddr + phdr->p_memsz <= cstart || 52 phdr->p_vaddr >= cend) 53 continue; 54 55 printf("SRM console and kernel image would overlap.\n" 56 "Please report this to <alpha@openbsd.org>, " 57 "with the following values:\n" 58 "SRM range: %p-%p\n" 59 "kernel range: %p-%p\n", 60 cstart, cend, phdr->p_vaddr, 61 phdr->p_vaddr + phdr->p_memsz); 62 return 1; 63 } 64 } 65 66 return 0; 67 } 68