1*b7041c07Sderaadt /* $OpenBSD: exec_elf.c,v 1.18 2021/10/24 21:24:18 deraadt Exp $ */
235319decSderaadt
335319decSderaadt /*
435319decSderaadt * Copyright (c) 1999 Mats O Jansson. All rights reserved.
535319decSderaadt *
635319decSderaadt * Redistribution and use in source and binary forms, with or without
735319decSderaadt * modification, are permitted provided that the following conditions
835319decSderaadt * are met:
935319decSderaadt * 1. Redistributions of source code must retain the above copyright
1035319decSderaadt * notice, this list of conditions and the following disclaimer.
1135319decSderaadt * 2. Redistributions in binary form must reproduce the above copyright
1235319decSderaadt * notice, this list of conditions and the following disclaimer in the
1335319decSderaadt * documentation and/or other materials provided with the distribution.
1435319decSderaadt *
1535319decSderaadt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1635319decSderaadt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1735319decSderaadt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1835319decSderaadt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1935319decSderaadt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2035319decSderaadt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2135319decSderaadt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2235319decSderaadt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2335319decSderaadt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2435319decSderaadt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2535319decSderaadt */
2635319decSderaadt
27c6b62359Sedd #include <sys/types.h>
28c6b62359Sedd #include <sys/exec.h>
29c6b62359Sedd
309f79a698Smpi #include <elf.h>
3135319decSderaadt #include <err.h>
3235319decSderaadt #include <errno.h>
3335319decSderaadt #include <fcntl.h>
3435319decSderaadt #include <nlist.h>
3535319decSderaadt #include <stdio.h>
36c6b62359Sedd #include <stdlib.h>
3735319decSderaadt #include <unistd.h>
3835319decSderaadt
3935319decSderaadt #include "ukc.h"
401c946cd5Sderaadt #include "config.h"
414d92a8bcSguenther #include "exec.h"
4235319decSderaadt
4335319decSderaadt caddr_t ptr, rest, pre;
446377a087Sart Elf_Ehdr elf_ex;
456377a087Sart Elf_Phdr *elf_phdr;
466377a087Sart Elf_Shdr *elf_shdr;
4735319decSderaadt char *elf_total;
4835319decSderaadt char *elf_shstrtab;
4935319decSderaadt off_t elf_size;
5035319decSderaadt
5135319decSderaadt caddr_t
adjust(caddr_t x)524d92a8bcSguenther adjust(caddr_t x)
5335319decSderaadt {
5435319decSderaadt int i;
556377a087Sart Elf_Shdr *s;
5635319decSderaadt unsigned long y = 0;
5735319decSderaadt
5835319decSderaadt s = elf_shdr;
5935319decSderaadt
6035319decSderaadt for (i = 0; i < elf_ex.e_shnum; i++) {
6135319decSderaadt if (s[i].sh_addr == 0)
6235319decSderaadt continue;
6335319decSderaadt if (((unsigned long)x >= s[i].sh_addr) &&
6435319decSderaadt ((unsigned long)x < (s[i].sh_addr+s[i].sh_size))) {
6535319decSderaadt y = (unsigned long)&elf_total[(unsigned long)x -
66a8d5091fSderaadt s[i].sh_addr + s[i].sh_offset];
6735319decSderaadt break;
6835319decSderaadt }
6935319decSderaadt }
7035319decSderaadt
7135319decSderaadt return((caddr_t)y);
7235319decSderaadt }
7335319decSderaadt
7435319decSderaadt caddr_t
readjust(caddr_t x)754d92a8bcSguenther readjust(caddr_t x)
7635319decSderaadt {
7735319decSderaadt int i;
786377a087Sart Elf_Shdr *s;
7935319decSderaadt unsigned long y = 0;
8035319decSderaadt
8135319decSderaadt s = elf_shdr;
8235319decSderaadt
8335319decSderaadt for (i = 0; i < elf_ex.e_shnum; i++) {
8435319decSderaadt if (s[i].sh_addr == 0)
8535319decSderaadt continue;
8635319decSderaadt if (((x - elf_total) >= s[i].sh_offset) &&
8735319decSderaadt ((x - elf_total) <= (s[i].sh_offset + s[i].sh_size)))
88b90f1bdfSart y = (unsigned long)x - (unsigned long)elf_total +
89b90f1bdfSart (unsigned long)s[i].sh_addr - s[i].sh_offset;
9035319decSderaadt }
9135319decSderaadt
9235319decSderaadt return((caddr_t)y);
9335319decSderaadt }
9435319decSderaadt
9535319decSderaadt void
loadkernel(char * file)964d92a8bcSguenther loadkernel(char *file)
9735319decSderaadt {
9835319decSderaadt int fd;
9935319decSderaadt
100*b7041c07Sderaadt if ((fd = open(file, O_RDONLY | O_EXLOCK)) == -1)
1012cc28a79Saaron err(1, "%s", file);
10235319decSderaadt
10335319decSderaadt if (read(fd, (char *)&elf_ex, sizeof(elf_ex)) != sizeof(elf_ex))
10435319decSderaadt errx(1, "can't read elf header");
10535319decSderaadt
10635319decSderaadt if (!IS_ELF(elf_ex))
10746347781Smpech errx(1, "bad elf magic");
10835319decSderaadt
1097411eadaSderaadt elf_size = lseek(fd, (off_t)0, SEEK_END);
1107411eadaSderaadt (void)lseek(fd, (off_t)0, SEEK_SET);
1117411eadaSderaadt elf_total = emalloc((size_t)elf_size);
11235319decSderaadt
1137411eadaSderaadt if (read(fd, elf_total, (size_t)elf_size) != elf_size)
11435319decSderaadt errx(1, "can't read elf kernel");
11535319decSderaadt
1163fd68e11Sotto if (elf_ex.e_phoff > (size_t)elf_size)
1173fd68e11Sotto errx(1, "incorrect ELF header or truncated file");
1183fd68e11Sotto if (elf_ex.e_shoff > (size_t)elf_size)
1193fd68e11Sotto errx(1, "incorrect ELF header or truncated file");
1203fd68e11Sotto
1216377a087Sart elf_phdr = (Elf_Phdr *)&elf_total[elf_ex.e_phoff];
1226377a087Sart elf_shdr = (Elf_Shdr *)&elf_total[elf_ex.e_shoff];
12335319decSderaadt
1243fd68e11Sotto if ((char *)&elf_shdr[elf_ex.e_shstrndx] +
1253fd68e11Sotto sizeof(elf_shdr[elf_ex.e_shstrndx]) >= elf_total + (size_t)elf_size)
1263fd68e11Sotto errx(1, "incorrect ELF header or truncated file");
1273fd68e11Sotto
1283fd68e11Sotto if ((char *)&elf_shdr[elf_ex.e_shstrndx].sh_offset +
1293fd68e11Sotto sizeof(elf_shdr[elf_ex.e_shstrndx].sh_offset) >=
1303fd68e11Sotto elf_total + (size_t)elf_size)
1313fd68e11Sotto errx(1, "incorrect ELF header or truncated file");
1323fd68e11Sotto
13335319decSderaadt elf_shstrtab = &elf_total[elf_shdr[elf_ex.e_shstrndx].sh_offset];
13435319decSderaadt
13535319decSderaadt close(fd);
13635319decSderaadt }
13735319decSderaadt
13835319decSderaadt void
savekernel(char * outfile)1394d92a8bcSguenther savekernel(char *outfile)
14035319decSderaadt {
14135319decSderaadt int fd;
14235319decSderaadt
143df69c215Sderaadt if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0700)) == -1)
1442cc28a79Saaron err(1, "%s", outfile);
14535319decSderaadt
1467411eadaSderaadt if (write(fd, elf_total, (size_t)elf_size) != elf_size)
14735319decSderaadt errx(1, "can't write file %s", outfile);
14835319decSderaadt
14935319decSderaadt close(fd);
15035319decSderaadt }
151