diff options
-rw-r--r-- | usr.sbin/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/rdsetroot/Makefile | 7 | ||||
-rw-r--r-- | usr.sbin/rdsetroot/elf32.c | 3 | ||||
-rw-r--r-- | usr.sbin/rdsetroot/elf64.c | 3 | ||||
-rw-r--r-- | usr.sbin/rdsetroot/elfrd_size.c | 396 | ||||
-rw-r--r-- | usr.sbin/rdsetroot/rdsetroot.8 | 54 | ||||
-rw-r--r-- | usr.sbin/rdsetroot/rdsetroot.c | 204 | ||||
-rw-r--r-- | usr.sbin/rdsetroot/rdsetroot.h | 13 |
8 files changed, 682 insertions, 2 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index f62cc04e093..e8869d618ce 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.204 2019/01/26 10:59:30 florian Exp $ +# $OpenBSD: Makefile,v 1.205 2019/04/05 21:07:11 deraadt Exp $ .include <bsd.own.mk> @@ -13,7 +13,7 @@ SUBDIR= ac accton acme-client acpidump adduser amd apm apmd arp \ npppctl npppd nsd ntpd ocspcheck ospfctl ospfd ospf6d ospf6ctl \ pcidump pkg_add portmap pppd procmap pstat pwd_mkdb \ quot quotaon ractl rad radiusctl radiusd rarpd rbootd \ - rcctl rdate rebound relayctl relayd repquota ripctl ripd \ + rcctl rdate rdsetroot rebound relayctl relayd repquota ripctl ripd \ rmt route6d rpc.bootparamd rpc.lockd rpc.statd \ sa sasyncd sensorsd slaacctl slowcgi smtpd \ snmpctl snmpd spamdb switchctl switchd syslogc syslogd sysmerge \ diff --git a/usr.sbin/rdsetroot/Makefile b/usr.sbin/rdsetroot/Makefile new file mode 100644 index 00000000000..eb9059ab556 --- /dev/null +++ b/usr.sbin/rdsetroot/Makefile @@ -0,0 +1,7 @@ +# $OpenBSD: Makefile,v 1.1 2019/04/05 21:07:11 deraadt Exp $ + +PROG= rdsetroot +MAN= rdsetroot.8 +SRCS= rdsetroot.c elf32.c elf64.c + +.include <bsd.prog.mk> diff --git a/usr.sbin/rdsetroot/elf32.c b/usr.sbin/rdsetroot/elf32.c new file mode 100644 index 00000000000..4b303b5135f --- /dev/null +++ b/usr.sbin/rdsetroot/elf32.c @@ -0,0 +1,3 @@ +/* $OpenBSD: elf32.c,v 1.1 2019/04/05 21:07:11 deraadt Exp $ */ +#define ELFSIZE 32 +#include "elfrd_size.c" diff --git a/usr.sbin/rdsetroot/elf64.c b/usr.sbin/rdsetroot/elf64.c new file mode 100644 index 00000000000..3f453fd586e --- /dev/null +++ b/usr.sbin/rdsetroot/elf64.c @@ -0,0 +1,3 @@ +/* $OpenBSD: elf64.c,v 1.1 2019/04/05 21:07:11 deraadt Exp $ */ +#define ELFSIZE 64 +#include "elfrd_size.c" diff --git a/usr.sbin/rdsetroot/elfrd_size.c b/usr.sbin/rdsetroot/elfrd_size.c new file mode 100644 index 00000000000..1a9755990c4 --- /dev/null +++ b/usr.sbin/rdsetroot/elfrd_size.c @@ -0,0 +1,396 @@ +/* $OpenBSD: elfrd_size.c,v 1.1 2019/04/05 21:07:11 deraadt Exp $ */ + +/* + * Copyright (c) 1994 Gordon W. Ross + * Copyright (c) 1997 Per Fogelstrom. (ELF modifications) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> + +#include <elf.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <nlist.h> +#include <err.h> + +#include <errno.h> +#include <limits.h> + +#include "rdsetroot.h" + +void +ELFNAME(locate_image)(int, struct elfhdr *, char *, long *, long *, off_t *, + size_t *); +int +ELFNAME(find_rd_root_image)(char *, int, Elf_Phdr *, int, long *, long *, + off_t *, size_t *); +int +ELFNAME(nlist)(int, struct nlist *); + +struct elf_fn ELFDEFNNAME(fn) = +{ + ELFNAME(locate_image), + ELFNAME(find_rd_root_image) +}; + +void +ELFNAME(locate_image)(int fd, struct elfhdr *ghead, char *file, + long *prd_root_size_off, long *prd_root_image_off, off_t *pmmap_off, + size_t *pmmap_size) +{ + int n; + int found = 0; + size_t phsize; + Elf_Ehdr head; + + Elf_Phdr *ph; + + /* elfhdr may not have the full header? */ + lseek(fd, 0, SEEK_SET); + + if (read(fd, &head, sizeof(head)) != sizeof(head)) + err(1, "can't read phdr area"); + + phsize = head.e_phnum * sizeof(Elf_Phdr); + if ((ph = malloc(phsize)) == NULL) + err(1, "malloc"); + + lseek(fd, head.e_phoff, SEEK_SET); + + if (read(fd, ph, phsize) != phsize) + err(1, "can't read phdr area"); + + for (n = 0; n < head.e_phnum && !found; n++) { + if (ph[n].p_type == PT_LOAD) + found = ELFNAME(find_rd_root_image)(file, fd, &ph[n], + n, prd_root_size_off, prd_root_image_off, + pmmap_off, pmmap_size); + } + if (!found) + errx(1, "can't locate space for rd_root_image!"); + free(ph); +} + +struct nlist ELFNAME(wantsyms)[] = { + { "_rd_root_size", 0 }, + { "_rd_root_image", 0 }, + { NULL, 0 } +}; + +int +ELFNAME(find_rd_root_image)(char *file, int fd, Elf_Phdr *ph, int segment, + long *prd_root_size_off, long *prd_root_image_off, off_t *pmmap_off, + size_t *pmmap_size) +{ + unsigned long kernel_start, kernel_size; + uint64_t rd_root_size_off, rd_root_image_off; + + if (ELFNAME(nlist)(fd, ELFNAME(wantsyms))) + errx(1, "no rd_root_image symbols?"); + kernel_start = ph->p_paddr; + kernel_size = ph->p_filesz; + + rd_root_size_off = ELFNAME(wantsyms)[0].n_value - kernel_start; + if (rd_root_size_off < (ph->p_vaddr - ph->p_paddr)) + return (0); + rd_root_size_off -= (ph->p_vaddr - ph->p_paddr); + + rd_root_image_off = ELFNAME(wantsyms)[1].n_value - kernel_start; + if (rd_root_image_off < (ph->p_vaddr - ph->p_paddr)) + return (0); + rd_root_image_off -= (ph->p_vaddr - ph->p_paddr); + + if (debug) { + fprintf(stderr, "segment %d rd_root_size_off = 0x%llx\n", segment, + rd_root_size_off); + if ((ph->p_vaddr - ph->p_paddr) != 0) + fprintf(stderr, "root_off v %zx p %zx, diff %zx altered %llx\n", + (size_t)ph->p_vaddr, (size_t)ph->p_paddr, + (size_t)(ph->p_vaddr - ph->p_paddr), + rd_root_size_off - (ph->p_vaddr - ph->p_paddr)); + fprintf(stderr, "rd_root_image_off = 0x%llx\n", rd_root_image_off); + } + + /* + * Sanity check locations of db_* symbols + */ + if (rd_root_image_off >= kernel_size) + return (0); + if (rd_root_size_off >= kernel_size) + errx(1, "rd_root_size not in data segment?"); + *pmmap_off = ph->p_offset; + *pmmap_size = kernel_size; + *prd_root_size_off = rd_root_size_off; + *prd_root_image_off = rd_root_image_off; + return (1); +} + +/* + * __elf_is_okay__ - Determine if ehdr really + * is ELF and valid for the target platform. + * + * WARNING: This is NOT a ELF ABI function and + * as such its use should be restricted. + */ +int +ELFNAME(__elf_is_okay__)(Elf_Ehdr *ehdr) +{ + int retval = 0; + /* + * We need to check magic, class size, endianess, + * and version before we look at the rest of the + * Elf_Ehdr structure. These few elements are + * represented in a machine independent fashion. + */ + if (IS_ELF(*ehdr) && + ehdr->e_ident[EI_DATA] == ELF_TARG_DATA && + ehdr->e_ident[EI_VERSION] == ELF_TARG_VER) { + +#if 0 /* allow cross, no arch check */ + /* Now check the machine dependent header */ + if (ehdr->e_machine == ELF_TARG_MACH && + ehdr->e_version == ELF_TARG_VER) +#endif + retval = 1; + } + + return retval; +} + +#define ISLAST(p) (p->n_name == 0 || p->n_name[0] == 0) +#define MIN(x, y) ((x)<(y)? (x) : (y)) + + +int +ELFNAME(nlist)(int fd, struct nlist *list) +{ + struct nlist *p; + caddr_t strtab; + Elf_Off symoff = 0, symstroff = 0; + Elf_Word symsize = 0; + long symstrsize = 0; + Elf_Sword nent, cc, i; + Elf_Sym sbuf[1024]; + Elf_Sym *s; + Elf_Ehdr ehdr; + Elf_Shdr *shdr = NULL; + size_t shdr_size; + struct stat st; + int usemalloc = 0; + size_t left, len; + + /* Make sure obj is OK */ + if (pread(fd, &ehdr, sizeof(Elf_Ehdr), (off_t)0) != sizeof(Elf_Ehdr) || + !ELFNAME(__elf_is_okay__)(&ehdr) || fstat(fd, &st) < 0) + return (-1); + + /* calculate section header table size */ + shdr_size = ehdr.e_shentsize * ehdr.e_shnum; + + /* Make sure it's not too big to mmap */ + if (SIZE_MAX - ehdr.e_shoff < shdr_size || + (S_ISREG(st.st_mode) && ehdr.e_shoff + shdr_size > st.st_size)) { + errno = EFBIG; + return (-1); + } + + /* mmap section header table */ + shdr = (Elf_Shdr *)mmap(NULL, (size_t)shdr_size, PROT_READ, + MAP_SHARED|MAP_FILE, fd, (off_t) ehdr.e_shoff); + if (shdr == MAP_FAILED) { + usemalloc = 1; + if ((shdr = malloc(shdr_size)) == NULL) + return (-1); + + if (pread(fd, shdr, shdr_size, (off_t)ehdr.e_shoff) != + shdr_size) { + free(shdr); + return (-1); + } + } + + /* + * Find the symbol table entry and its corresponding + * string table entry. Version 1.1 of the ABI states + * that there is only one symbol table but that this + * could change in the future. + */ + for (i = 0; i < ehdr.e_shnum; i++) { + if (shdr[i].sh_type == SHT_SYMTAB) { + if (shdr[i].sh_link >= ehdr.e_shnum) + continue; + symoff = shdr[i].sh_offset; + symsize = shdr[i].sh_size; + symstroff = shdr[shdr[i].sh_link].sh_offset; + symstrsize = shdr[shdr[i].sh_link].sh_size; + break; + } + } + + /* Flush the section header table */ + if (usemalloc) + free(shdr); + else + munmap((caddr_t)shdr, shdr_size); + + /* + * clean out any left-over information for all valid entries. + * Type and value defined to be 0 if not found; historical + * versions cleared other and desc as well. Also figure out + * the largest string length so don't read any more of the + * string table than we have to. + * + * XXX clearing anything other than n_type and n_value violates + * the semantics given in the man page. + */ + nent = 0; + for (p = list; !ISLAST(p); ++p) { + p->n_type = 0; + p->n_other = 0; + p->n_desc = 0; + p->n_value = 0; + ++nent; + } + + /* Don't process any further if object is stripped. */ + /* ELFism - dunno if stripped by looking at header */ + if (symoff == 0) + return nent; + + /* Check for files too large to mmap. */ + if (SIZE_MAX - symstrsize < symstroff || + (S_ISREG(st.st_mode) && symstrsize + symstroff > st.st_size)) { + errno = EFBIG; + return (-1); + } + + /* + * Map string table into our address space. This gives us + * an easy way to randomly access all the strings, without + * making the memory allocation permanent as with malloc/free + * (i.e., munmap will return it to the system). + */ + if (usemalloc) { + if ((strtab = malloc(symstrsize)) == NULL) + return (-1); + if (pread(fd, strtab, symstrsize, (off_t)symstroff) != + symstrsize) { + free(strtab); + return (-1); + } + } else { + strtab = mmap(NULL, (size_t)symstrsize, PROT_READ, + MAP_SHARED|MAP_FILE, fd, (off_t) symstroff); + if (strtab == MAP_FAILED) + return (-1); + } + + while (symsize >= sizeof(Elf_Sym)) { + cc = MIN(symsize, sizeof(sbuf)); + if (pread(fd, sbuf, cc, (off_t)symoff) != cc) + break; + symsize -= cc; + symoff += cc; + for (s = sbuf; cc > 0; ++s, cc -= sizeof(*s)) { + Elf_Word soff = s->st_name; + + if (soff == 0 || soff >= symstrsize) + continue; + left = symstrsize - soff; + + for (p = list; !ISLAST(p); p++) { + char *sym; + + /* + * First we check for the symbol as it was + * provided by the user. If that fails + * and the first char is an '_', skip over + * the '_' and try again. + * XXX - What do we do when the user really + * wants '_foo' and there are symbols + * for both 'foo' and '_foo' in the + * table and 'foo' is first? + */ + sym = p->n_name; + len = strlen(sym); + + if ((len >= left || + strcmp(&strtab[soff], sym) != 0) && + (sym[0] != '_' || len - 1 >= left || + strcmp(&strtab[soff], sym + 1) != 0)) + continue; + + p->n_value = s->st_value; + + /* XXX - type conversion */ + /* is pretty rude. */ + switch (ELF_ST_TYPE(s->st_info)) { + case STT_NOTYPE: + switch (s->st_shndx) { + case SHN_UNDEF: + p->n_type = N_UNDF; + break; + case SHN_ABS: + p->n_type = N_ABS; + break; + case SHN_COMMON: + p->n_type = N_COMM; + break; + default: + p->n_type = N_COMM | N_EXT; + break; + } + break; + case STT_OBJECT: + p->n_type = N_DATA; + break; + case STT_FUNC: + p->n_type = N_TEXT; + break; + case STT_FILE: + p->n_type = N_FN; + break; + } + if (ELF_ST_BIND(s->st_info) == STB_LOCAL) + p->n_type = N_EXT; + p->n_desc = 0; + p->n_other = 0; + if (--nent <= 0) + break; + } + } + } + if (usemalloc) + free(strtab); + else + munmap(strtab, symstrsize); + return (nent); +} diff --git a/usr.sbin/rdsetroot/rdsetroot.8 b/usr.sbin/rdsetroot/rdsetroot.8 new file mode 100644 index 00000000000..8bcf2038260 --- /dev/null +++ b/usr.sbin/rdsetroot/rdsetroot.8 @@ -0,0 +1,54 @@ +.\" $OpenBSD: rdsetroot.8,v 1.1 2019/04/05 21:07:11 deraadt Exp $ +.\" +.\" Copyright (c) 2019 Theo de Raadt +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 5 2019 $ +.Dt RDSETROOT 8 +.Os +.Sh NAME +.Nm rdsetroot +.Nd insert disk image into RAMDISK kernel +.Sh SYNOPSIS +.Nm rdsetroot +.Op Fl dx +.Ar kernel +.Op Ar disk.fs +.Sh DESCRIPTION +The +.Nm +utility inserts the file +.Ar disk.fs +into the reserved space inside a RAMDISK kernel. +If +.Ar disk.fs +is not specified, +.Nm +reads from standard input. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl d +Debug. +.It Fl x +Rather than inserting, extract the +.Ar disk.fs +image. +The disk can be made accessable using +.Xr vnconfig 8 , +filesystems can be manipulated, and finally re-inserted into the RAMDISK kernel. +.Sh SEE ALSO +.Xr config 8 , +.Xr disklabel 8 , +.Xr vnconfig 8
\ No newline at end of file diff --git a/usr.sbin/rdsetroot/rdsetroot.c b/usr.sbin/rdsetroot/rdsetroot.c new file mode 100644 index 00000000000..ef3101e3329 --- /dev/null +++ b/usr.sbin/rdsetroot/rdsetroot.c @@ -0,0 +1,204 @@ +/* $OpenBSD: rdsetroot.c,v 1.1 2019/04/05 21:07:11 deraadt Exp $ */ + +/* + * Copyright (c) 1994 Gordon W. Ross + * Copyright (c) 1997 Per Fogelstrom. (ELF modifications) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copy a ramdisk image into the space reserved for it. + * Kernel variables: rd_root_size, rd_root_image + */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> + +#include <elf.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <err.h> + +#include "rdsetroot.h" + +struct elfhdr head; + +/* Offsets relative to start of data segment. */ +long rd_root_image_off, rd_root_size_off; + +/* value in the location at rd_root_size_off */ +off_t rd_root_size_val; + +/* pointers to pieces of mapped file */ +char *dataseg; + +/* parameters to mmap digged out from program header */ +off_t mmap_off; +size_t mmap_size; + +__dead void usage(void); + +int debug; + +struct elf_fn *elf_fn; + +int +main(int argc, char *argv[]) +{ + int ch, kfd, n, xflag = 0, fsfd; + char *fs = NULL; + char *kernel; + u_int32_t *ip; + + while ((ch = getopt(argc, argv, "dx")) != -1) { + switch (ch) { + case 'd': + debug = 1; + break; + case 'x': + xflag = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc == 1) + kernel = argv[0]; + else if (argc == 2) { + kernel = argv[0]; + fs = argv[1]; + } else + usage(); + + kfd = open(kernel, xflag ? O_RDONLY : O_RDWR, 0644); + if (kfd < 0) + err(1, "%s", kernel); + + if (fs) { + if (xflag) + fsfd = open(fs, O_RDWR | O_CREAT | O_TRUNC, 0644); + else + fsfd = open(fs, O_RDONLY, 0644); + } else { + if (xflag) + fsfd = dup(STDOUT_FILENO); + else + fsfd = dup(STDIN_FILENO); + } + if (fsfd < 0) + err(1, "%s", fs); + + if (pledge("stdio", NULL) == -1) + err(1, "pledge"); + + n = read(kfd, &head, sizeof(head)); + if (n < sizeof(head)) + err(1, "%s: reading header", kernel); + + if (!IS_ELF(head)) + err(1, "%s: bad magic number", kernel); + + if (head.e_ident[EI_CLASS] == ELFCLASS32) { + elf_fn = &ELF32_fn; + } else if (head.e_ident[EI_CLASS] == ELFCLASS64) { + elf_fn = &ELF64_fn; + } else { + fprintf(stderr, "%s: invalid elf, not 32 or 64 bit", kernel); + exit(1); + } + + elf_fn->locate_image(kfd, &head, kernel, &rd_root_size_off, + &rd_root_image_off, &mmap_off, &mmap_size); + + /* + * Map in the whole data segment. + * The file offset needs to be page aligned. + */ + dataseg = mmap(NULL, mmap_size, + xflag ? PROT_READ : PROT_READ | PROT_WRITE, + MAP_SHARED, kfd, mmap_off); + if (dataseg == MAP_FAILED) + err(1, "%s: can not map data seg", kernel); + + /* + * Find value in the location: rd_root_size + */ + ip = (u_int32_t *) (dataseg + rd_root_size_off); + rd_root_size_val = *ip; + if (debug) + fprintf(stderr, "rd_root_size val: 0x%llx (%lld blocks)\n", + (unsigned long long)rd_root_size_val, + (unsigned long long)rd_root_size_val >> 9); + + /* + * Copy the symbol table and string table. + */ + if (debug) + fprintf(stderr, "copying root image...\n"); + + if (xflag) { + n = write(fsfd, dataseg + rd_root_image_off, + (size_t)rd_root_size_val); + if (n != rd_root_size_val) + err(1, "write"); + } else { + struct stat sstat; + + if (fstat(fsfd, &sstat) == -1) + err(1, "fstat"); + if (S_ISREG(sstat.st_mode) && + sstat.st_size > rd_root_size_val) { + fprintf(stderr, "ramdisk too small 0x%llx 0x%llx\n", + (unsigned long long)sstat.st_size, + (unsigned long long)rd_root_size_val); + exit(1); + } + n = read(fsfd, dataseg + rd_root_image_off, + (size_t)rd_root_size_val); + if (n < 0) + err(1, "read"); + + msync(dataseg, mmap_size, 0); + } + + if (debug) + fprintf(stderr, "...copied %d bytes\n", n); + exit(0); +} + +__dead void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, "usage: %s [-dx] bsd [fs]\n", __progname); + exit(1); +} diff --git a/usr.sbin/rdsetroot/rdsetroot.h b/usr.sbin/rdsetroot/rdsetroot.h new file mode 100644 index 00000000000..6c05227aa75 --- /dev/null +++ b/usr.sbin/rdsetroot/rdsetroot.h @@ -0,0 +1,13 @@ +/* $OpenBSD: rdsetroot.h,v 1.1 2019/04/05 21:07:11 deraadt Exp $ */ + +struct elf_fn { + void (*locate_image)(int, struct elfhdr *, char *, long *, long *, + off_t *, size_t *); + int (*find_rd_root_image)(char *, int, Elf_Phdr *, int, long *, long *, + off_t *, size_t *); + +}; + +extern int debug; +extern struct elf_fn ELF32_fn; +extern struct elf_fn ELF64_fn; |