2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2000, 2001 David O'Brien
5 * Copyright (c) 1996 Søren Schmidt
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer
13 * in this position and unchanged.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
35 #include <sys/param.h>
36 #include <sys/capsicum.h>
37 #include <sys/elf_common.h>
38 #include <sys/errno.h>
40 #include <capsicum_helpers.h>
49 #include <libcasper.h>
50 #include <casper/cap_fileargs.h>
52 static int elftype(const char *);
53 static const char *iselftype(int);
54 static void printelftypes(void);
55 static void usage(void);
61 /* XXX - any more types? */
62 static struct ELFtypes elftypes[] = {
63 { "FreeBSD", ELFOSABI_FREEBSD },
64 { "Linux", ELFOSABI_LINUX },
65 { "Solaris", ELFOSABI_SOLARIS },
66 { "SVR4", ELFOSABI_SYSV }
70 main(int argc, char **argv)
73 const char *strtype = "FreeBSD";
74 int ch, flags, retval, type;
75 bool change, force, listed;
79 type = ELFOSABI_FREEBSD;
85 while ((ch = getopt(argc, argv, "f:lt:v")) != -1)
89 errx(1, "f option incompatible with t option");
92 if (errno == ERANGE || type < 0 || type > 255) {
93 warnx("invalid argument to option f: %s",
107 errx(1, "t option incompatible with f option");
120 warnx("no file(s) specified");
125 if (!force && (type = elftype(strtype)) == -1) {
126 warnx("invalid ELF type '%s'", strtype);
131 flags = change || force ? O_RDWR : O_RDONLY;
132 cap_rights_init(&rights, CAP_READ, CAP_SEEK);
134 cap_rights_set(&rights, CAP_WRITE);
136 fa = fileargs_init(argc, argv, flags, 0, &rights);
138 errx(1, "unable to init casper");
140 caph_cache_catpages();
141 if (caph_limit_stdio() < 0 || caph_enter_casper() < 0)
142 err(1, "unable to enter capability mode");
146 char buffer[EI_NIDENT];
148 if ((fd = fileargs_open(fa, argv[0])) < 0) {
149 warn("error opening file %s", argv[0]);
153 if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) {
154 warnx("file '%s' too short", argv[0]);
158 if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 ||
159 buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) {
160 warnx("file '%s' is not ELF format", argv[0]);
164 if (!change && !force) {
166 "File '%s' is of brand '%s' (%u).\n",
167 argv[0], iselftype(buffer[EI_OSABI]),
169 if (!iselftype(type)) {
170 warnx("ELF ABI Brand '%u' is unknown",
176 buffer[EI_OSABI] = type;
177 lseek(fd, 0, SEEK_SET);
178 if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) {
179 warn("error writing %s %d", argv[0], fd);
197 (void)fprintf(stderr,
198 "usage: brandelf [-lv] [-f ELF_ABI_number] [-t string] file ...\n");
207 for (elfwalk = 0; elfwalk < nitems(elftypes); elfwalk++)
208 if (etype == elftypes[elfwalk].value)
209 return (elftypes[elfwalk].str);
214 elftype(const char *elfstrtype)
218 for (elfwalk = 0; elfwalk < nitems(elftypes); elfwalk++)
219 if (strcasecmp(elfstrtype, elftypes[elfwalk].str) == 0)
220 return (elftypes[elfwalk].value);
229 fprintf(stderr, "known ELF types are: ");
230 for (elfwalk = 0; elfwalk < nitems(elftypes); elfwalk++)
231 fprintf(stderr, "%s(%u) ", elftypes[elfwalk].str,
232 elftypes[elfwalk].value);
233 fprintf(stderr, "\n");