Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105770769
D23910.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D23910.diff
View Options
Index: head/tools/tools/controlelf/Makefile
===================================================================
--- head/tools/tools/controlelf/Makefile
+++ head/tools/tools/controlelf/Makefile
@@ -1,14 +0,0 @@
-# $FreeBSD$
-
-ELFTCDIR= ${SRCTOP}/contrib/elftoolchain
-
-PROG= controlelf
-SRCS= controlelf.c
-
-LIBADD= elftc elf
-
-CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common
-
-WARNS?= 6
-
-.include <bsd.prog.mk>
Index: head/tools/tools/controlelf/controlelf.1
===================================================================
--- head/tools/tools/controlelf/controlelf.1
+++ head/tools/tools/controlelf/controlelf.1
@@ -1,94 +0,0 @@
-.\" Copyright 2019 The FreeBSD Foundation.
-.\"
-.\" This software was developed by Bora Ozarslan under sponsorship from
-.\" the FreeBSD Foundation.
-.\"
-.\" 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.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd September 27, 2019
-.Dt CONTROLELF 1
-.Os
-.Sh NAME
-.Nm controlelf
-.Nd change an ELF binary's feature control note
-.Sh SYNOPSIS
-.Nm
-.Op Fl h | Fl -help
-.Op Fl l
-.Op Fl e Ar featurelist
-.Ar
-.Sh DESCRIPTION
-The
-.Nm
-utility modifies feature flags in the feature control note in an ELF binary.
-.Pp
-The options are as follows:
-.Bl -tag -width indent
-.It Fl h | Fl -help
-Print a usage message and exit.
-.It Fl l
-List known ELF feature flags.
-.It Fl e Ar featurelist
-Edit features from the given comma separated list
-.Ar featurelist .
-.Ar featurelist
-starts with one of the three operations:
-.Dq Li +
-to turn on the features,
-.Dq Li -
-to turn off the features,
-.Dq Li =
-to only turn on the given features.
-A comma separated list of feature names follows the operation.
-.El
-.Pp
-If
-.Fl e
-is not specified
-.Nm
-displays the status of each feature in the ELF note in each
-.Ar .
-.Sh EXIT STATUS
-Exit status is 0 on success, and 1 if the command
-fails if a file does not exist, is too short,
-or fails to find or edit features note.
-.Sh EXAMPLES
-The following is an example of a typical usage
-of the
-.Nm
-command:
-.Bd -literal -offset indent
-controlelf file
-controlelf -e +aslr file
-.Ed
-.Sh HISTORY
-.Nm
-first appeared in
-.Fx 13.0 .
-.Sh AUTHORS
-.Nm
-was written by
-.An Bora Ozarslan Mt borako.ozarslan@gmail.com
-under sponsorship from the
-.Fx Foundation.
Index: head/tools/tools/controlelf/controlelf.c
===================================================================
--- head/tools/tools/controlelf/controlelf.c
+++ head/tools/tools/controlelf/controlelf.c
@@ -1,392 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * Copyright (c) 2019 The FreeBSD Foundation.
- *
- * This software was developed by Bora Ozarslan under sponsorship from
- * the FreeBSD Foundation.
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/param.h>
-#include <sys/elf_common.h>
-#include <sys/endian.h>
-#include <sys/stat.h>
-
-#include <err.h>
-#include <fcntl.h>
-#include <gelf.h>
-#include <getopt.h>
-#include <libelf.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "_elftc.h"
-
-__FBSDID("$FreeBSD$");
-
-static bool convert_to_feature_val(char *, u_int32_t *);
-static bool edit_file_features(Elf *, int, int, char *);
-static bool get_file_features(Elf *, int, int, u_int32_t *, u_int64_t *);
-static void print_features(void);
-static bool print_file_features(Elf *, int, int, char *);
-static void usage(void);
-
-struct ControlFeatures {
- const char *alias;
- unsigned long value;
- const char *desc;
-};
-
-static struct ControlFeatures featurelist[] = {
- { "aslr", NT_FREEBSD_FCTL_ASLR_DISABLE, "Disable ASLR" },
- { "protmax", NT_FREEBSD_FCTL_PROTMAX_DISABLE,
- "Disable implicit PROT_MAX" },
- { "stackgap", NT_FREEBSD_FCTL_STKGAP_DISABLE, "Disable stack gap" },
-};
-
-static struct option long_opts[] = {
- { "help", no_argument, NULL, 'h' },
- { NULL, 0, NULL, 0 }
-};
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define SUPPORTED_ENDIAN ELFDATA2LSB
-#else
-#define SUPPORTED_ENDIAN ELFDATA2MSB
-#endif
-
-int
-main(int argc, char **argv)
-{
- GElf_Ehdr ehdr;
- Elf *elf;
- Elf_Kind kind;
- int ch, fd, editfeatures, retval;
- char *features;
- bool lflag;
-
- lflag = 0;
- editfeatures = 0;
- retval = 0;
-
- if (elf_version(EV_CURRENT) == EV_NONE)
- errx(EXIT_FAILURE, "elf_version error");
-
- while ((ch = getopt_long(argc, argv, "hle:", long_opts, NULL)) != -1) {
- switch (ch) {
- case 'l':
- print_features();
- lflag = true;
- break;
- case 'e':
- features = optarg;
- editfeatures = 1;
- break;
- case 'h':
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
- if (argc == 0) {
- if (lflag)
- exit(0);
- else {
- warnx("no file(s) specified");
- usage();
- }
- }
-
- while (argc) {
- elf = NULL;
-
- if ((fd = open(argv[0],
- editfeatures ? O_RDWR : O_RDONLY, 0)) < 0) {
- warn("error opening file %s", argv[0]);
- retval = 1;
- goto fail;
- }
-
- if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
- warnx("elf_begin failed: %s", elf_errmsg(-1));
- retval = 1;
- goto fail;
- }
-
- if ((kind = elf_kind(elf)) != ELF_K_ELF) {
- if (kind == ELF_K_AR)
- warnx("file '%s' is an archive", argv[0]);
- else
- warnx("file '%s' is not an ELF file", argv[0]);
- retval = 1;
- goto fail;
- }
-
- if (gelf_getehdr(elf, &ehdr) == NULL) {
- warnx("gelf_getehdr: %s", elf_errmsg(-1));
- retval = 1;
- goto fail;
- }
- /*
- * XXX need to support cross-endian operation, but for now
- * exit on error rather than misbehaving.
- */
- if (ehdr.e_ident[EI_DATA] != SUPPORTED_ENDIAN) {
- warnx("file endianness must match host");
- retval = 1;
- goto fail;
- }
-
- if (!editfeatures) {
- if (!print_file_features(elf, ehdr.e_phnum, fd,
- argv[0])) {
- retval = 1;
- goto fail;
- }
- } else if (!edit_file_features(elf, ehdr.e_phnum, fd,
- features)) {
- retval = 1;
- goto fail;
- }
-fail:
- if (elf != NULL)
- elf_end(elf);
-
- if (fd >= 0)
- close(fd);
-
- argc--;
- argv++;
- }
-
- return (retval);
-}
-
-#define USAGE_MESSAGE \
- "\
-Usage: %s [options] file...\n\
- Set or display the control features for an ELF object.\n\n\
- Supported options are:\n\
- -l List known control features.\n\
- -e [+-=]feature,list Edit features from a comma separated list.\n\
- -h | --help Print a usage message and exit.\n"
-
-static void
-usage(void)
-{
-
- fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME());
- exit(1);
-}
-
-static bool
-convert_to_feature_val(char *feature_str, u_int32_t *feature_val)
-{
- char *feature;
- int i, len;
- u_int32_t input;
- char operation;
-
- input = 0;
- operation = *feature_str;
- feature_str++;
- len = nitems(featurelist);
- while ((feature = strsep(&feature_str, ",")) != NULL) {
- for (i = 0; i < len; ++i) {
- if (strcmp(featurelist[i].alias, feature) == 0) {
- input |= featurelist[i].value;
- break;
- }
- }
- if (i == len) {
- warnx("%s is not a valid feature", feature);
- return (false);
- }
- }
-
- if (operation == '+') {
- *feature_val |= input;
- } else if (operation == '=') {
- *feature_val = input;
- } else if (operation == '-') {
- *feature_val &= ~input;
- } else {
- warnx("'%c' not an operator - use '+', '-', '='",
- feature_str[0]);
- return (false);
- }
- return (true);
-}
-
-static bool
-edit_file_features(Elf *elf, int phcount, int fd, char *val)
-{
- u_int32_t features;
- u_int64_t off;
-
- if (!get_file_features(elf, phcount, fd, &features, &off)) {
- warnx("NT_FREEBSD_FEATURE_CTL note not found");
- return (false);
- }
-
- if (!convert_to_feature_val(val, &features))
- return (false);
-
- if (lseek(fd, off, SEEK_SET) == -1 ||
- write(fd, &features, sizeof(features)) <
- (ssize_t)sizeof(features)) {
- warnx("error writing feature value");
- return (false);
- }
- return (true);
-}
-
-static void
-print_features(void)
-{
- size_t i;
-
- printf("Known features are:\n");
- for (i = 0; i < nitems(featurelist); ++i)
- printf("%-16s%s\n", featurelist[i].alias,
- featurelist[i].desc);
-}
-
-static bool
-print_file_features(Elf *elf, int phcount, int fd, char *filename)
-{
- u_int32_t features;
- unsigned long i;
-
- if (!get_file_features(elf, phcount, fd, &features, NULL)) {
- return (false);
- }
-
- printf("File '%s' features:\n", filename);
- for (i = 0; i < nitems(featurelist); ++i) {
- printf("%-16s'%s' is ", featurelist[i].alias,
- featurelist[i].desc);
-
- if ((featurelist[i].value & features) == 0)
- printf("un");
-
- printf("set.\n");
- }
- return (true);
-}
-
-static bool
-get_file_features(Elf *elf, int phcount, int fd, u_int32_t *features,
- u_int64_t *off)
-{
- GElf_Phdr phdr;
- Elf_Note note;
- unsigned long read_total;
- int namesz, descsz, i;
- char *name;
- ssize_t size;
-
- /*
- * Go through each program header to find one that is of type PT_NOTE
- * and has a note for feature control.
- */
- for (i = 0; i < phcount; ++i) {
- if (gelf_getphdr(elf, i, &phdr) == NULL) {
- warnx("gelf_getphdr failed: %s", elf_errmsg(-1));
- return (false);
- }
-
- if (phdr.p_type != PT_NOTE)
- continue;
-
- if (lseek(fd, phdr.p_offset, SEEK_SET) < 0) {
- warn("lseek() failed:");
- return (false);
- }
-
- read_total = 0;
- while (read_total < phdr.p_filesz) {
- size = read(fd, ¬e, sizeof(note));
- if (size < (ssize_t)sizeof(note)) {
- warn("read() failed:");
- return (false);
- }
- read_total += sizeof(note);
-
- /*
- * XXX: Name and descriptor are 4 byte aligned, however,
- * the size given doesn't include the padding.
- */
- namesz = roundup2(note.n_namesz, 4);
- name = malloc(namesz);
- if (name == NULL) {
- warn("malloc() failed.");
- return (false);
- }
- descsz = roundup2(note.n_descsz, 4);
- size = read(fd, name, namesz);
- read_total += namesz;
-
- if (note.n_namesz != 8 ||
- strncmp("FreeBSD", name, 7) != 0 ||
- note.n_type != NT_FREEBSD_FEATURE_CTL) {
- /* Not the right note. Skip the description */
- if (lseek(fd, descsz, SEEK_CUR) < 0) {
- warn("lseek() failed.");
- free(name);
- return (false);
- }
- read_total += descsz;
- free(name);
- continue;
- }
-
- if (note.n_descsz < sizeof(u_int32_t)) {
- warnx("Feature descriptor can't "
- "be less than 4 bytes");
- free(name);
- return (false);
- }
-
- /*
- * XXX: For now we look at only 4 bytes of the
- * descriptor. This should respect descsz.
- */
- if (note.n_descsz > sizeof(u_int32_t))
- warnx("Feature note is bigger than expected");
- read(fd, features, sizeof(u_int32_t));
- if (off != NULL)
- *off = phdr.p_offset + read_total;
- free(name);
- return (true);
- }
- }
-
- warnx("NT_FREEBSD_FEATURE_CTL note not found");
- return (false);
-}
Index: head/usr.bin/Makefile
===================================================================
--- head/usr.bin/Makefile
+++ head/usr.bin/Makefile
@@ -31,6 +31,7 @@
diff \
dirname \
du \
+ elfctl \
elfdump \
enigma \
env \
Index: head/usr.bin/elfctl/Makefile
===================================================================
--- head/usr.bin/elfctl/Makefile
+++ head/usr.bin/elfctl/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+ELFTCDIR= ${SRCTOP}/contrib/elftoolchain
+
+PROG= elfctl
+
+LIBADD= elftc elf
+
+CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common
+
+.include <bsd.prog.mk>
Index: head/usr.bin/elfctl/elfctl.1
===================================================================
--- head/usr.bin/elfctl/elfctl.1
+++ head/usr.bin/elfctl/elfctl.1
@@ -0,0 +1,94 @@
+.\" Copyright 2019 The FreeBSD Foundation.
+.\"
+.\" This software was developed by Bora Ozarslan under sponsorship from
+.\" the FreeBSD Foundation.
+.\"
+.\" 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.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 1, 2020
+.Dt ELFCTL 1
+.Os
+.Sh NAME
+.Nm elfctl
+.Nd change an ELF binary's feature control note
+.Sh SYNOPSIS
+.Nm
+.Op Fl h | Fl -help
+.Op Fl l
+.Op Fl e Ar featurelist
+.Ar
+.Sh DESCRIPTION
+The
+.Nm
+utility modifies feature flags in the feature control note in an ELF binary.
+.Pp
+The options are as follows:
+.Bl -tag -width indent
+.It Fl h | Fl -help
+Print a usage message and exit.
+.It Fl l
+List known ELF feature flags.
+.It Fl e Ar featurelist
+Edit features from the given comma separated list
+.Ar featurelist .
+.Ar featurelist
+starts with one of the three operations:
+.Dq Li +
+to turn on the features,
+.Dq Li -
+to turn off the features,
+.Dq Li =
+to only turn on the given features.
+A comma separated list of feature names follows the operation.
+.El
+.Pp
+If
+.Fl e
+is not specified
+.Nm
+displays the status of each feature in the ELF note in each
+.Ar .
+.Sh EXIT STATUS
+Exit status is 0 on success, and 1 if the command
+fails if a file does not exist, is too short,
+or fails to find or edit features note.
+.Sh EXAMPLES
+The following is an example of a typical usage
+of the
+.Nm
+command:
+.Bd -literal -offset indent
+elfctl file
+elfctl -e +aslr file
+.Ed
+.Sh HISTORY
+.Nm
+first appeared in
+.Fx 13.0 .
+.Sh AUTHORS
+.Nm
+was written by
+.An Bora Ozarslan Mt borako.ozarslan@gmail.com
+under sponsorship from the
+.Fx Foundation.
Index: head/usr.bin/elfctl/elfctl.c
===================================================================
--- head/usr.bin/elfctl/elfctl.c
+++ head/usr.bin/elfctl/elfctl.c
@@ -0,0 +1,392 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2019 The FreeBSD Foundation.
+ *
+ * This software was developed by Bora Ozarslan under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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/param.h>
+#include <sys/elf_common.h>
+#include <sys/endian.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <getopt.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "_elftc.h"
+
+__FBSDID("$FreeBSD$");
+
+static bool convert_to_feature_val(char *, u_int32_t *);
+static bool edit_file_features(Elf *, int, int, char *);
+static bool get_file_features(Elf *, int, int, u_int32_t *, u_int64_t *);
+static void print_features(void);
+static bool print_file_features(Elf *, int, int, char *);
+static void usage(void);
+
+struct ControlFeatures {
+ const char *alias;
+ unsigned long value;
+ const char *desc;
+};
+
+static struct ControlFeatures featurelist[] = {
+ { "aslr", NT_FREEBSD_FCTL_ASLR_DISABLE, "Disable ASLR" },
+ { "protmax", NT_FREEBSD_FCTL_PROTMAX_DISABLE,
+ "Disable implicit PROT_MAX" },
+ { "stackgap", NT_FREEBSD_FCTL_STKGAP_DISABLE, "Disable stack gap" },
+};
+
+static struct option long_opts[] = {
+ { "help", no_argument, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+};
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define SUPPORTED_ENDIAN ELFDATA2LSB
+#else
+#define SUPPORTED_ENDIAN ELFDATA2MSB
+#endif
+
+int
+main(int argc, char **argv)
+{
+ GElf_Ehdr ehdr;
+ Elf *elf;
+ Elf_Kind kind;
+ int ch, fd, editfeatures, retval;
+ char *features;
+ bool lflag;
+
+ lflag = 0;
+ editfeatures = 0;
+ retval = 0;
+
+ if (elf_version(EV_CURRENT) == EV_NONE)
+ errx(EXIT_FAILURE, "elf_version error");
+
+ while ((ch = getopt_long(argc, argv, "hle:", long_opts, NULL)) != -1) {
+ switch (ch) {
+ case 'l':
+ print_features();
+ lflag = true;
+ break;
+ case 'e':
+ features = optarg;
+ editfeatures = 1;
+ break;
+ case 'h':
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 0) {
+ if (lflag)
+ exit(0);
+ else {
+ warnx("no file(s) specified");
+ usage();
+ }
+ }
+
+ while (argc) {
+ elf = NULL;
+
+ if ((fd = open(argv[0],
+ editfeatures ? O_RDWR : O_RDONLY, 0)) < 0) {
+ warn("error opening file %s", argv[0]);
+ retval = 1;
+ goto fail;
+ }
+
+ if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
+ warnx("elf_begin failed: %s", elf_errmsg(-1));
+ retval = 1;
+ goto fail;
+ }
+
+ if ((kind = elf_kind(elf)) != ELF_K_ELF) {
+ if (kind == ELF_K_AR)
+ warnx("file '%s' is an archive", argv[0]);
+ else
+ warnx("file '%s' is not an ELF file", argv[0]);
+ retval = 1;
+ goto fail;
+ }
+
+ if (gelf_getehdr(elf, &ehdr) == NULL) {
+ warnx("gelf_getehdr: %s", elf_errmsg(-1));
+ retval = 1;
+ goto fail;
+ }
+ /*
+ * XXX need to support cross-endian operation, but for now
+ * exit on error rather than misbehaving.
+ */
+ if (ehdr.e_ident[EI_DATA] != SUPPORTED_ENDIAN) {
+ warnx("file endianness must match host");
+ retval = 1;
+ goto fail;
+ }
+
+ if (!editfeatures) {
+ if (!print_file_features(elf, ehdr.e_phnum, fd,
+ argv[0])) {
+ retval = 1;
+ goto fail;
+ }
+ } else if (!edit_file_features(elf, ehdr.e_phnum, fd,
+ features)) {
+ retval = 1;
+ goto fail;
+ }
+fail:
+ if (elf != NULL)
+ elf_end(elf);
+
+ if (fd >= 0)
+ close(fd);
+
+ argc--;
+ argv++;
+ }
+
+ return (retval);
+}
+
+#define USAGE_MESSAGE \
+ "\
+Usage: %s [options] file...\n\
+ Set or display the control features for an ELF object.\n\n\
+ Supported options are:\n\
+ -l List known control features.\n\
+ -e [+-=]feature,list Edit features from a comma separated list.\n\
+ -h | --help Print a usage message and exit.\n"
+
+static void
+usage(void)
+{
+
+ fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME());
+ exit(1);
+}
+
+static bool
+convert_to_feature_val(char *feature_str, u_int32_t *feature_val)
+{
+ char *feature;
+ int i, len;
+ u_int32_t input;
+ char operation;
+
+ input = 0;
+ operation = *feature_str;
+ feature_str++;
+ len = nitems(featurelist);
+ while ((feature = strsep(&feature_str, ",")) != NULL) {
+ for (i = 0; i < len; ++i) {
+ if (strcmp(featurelist[i].alias, feature) == 0) {
+ input |= featurelist[i].value;
+ break;
+ }
+ }
+ if (i == len) {
+ warnx("%s is not a valid feature", feature);
+ return (false);
+ }
+ }
+
+ if (operation == '+') {
+ *feature_val |= input;
+ } else if (operation == '=') {
+ *feature_val = input;
+ } else if (operation == '-') {
+ *feature_val &= ~input;
+ } else {
+ warnx("'%c' not an operator - use '+', '-', '='",
+ feature_str[0]);
+ return (false);
+ }
+ return (true);
+}
+
+static bool
+edit_file_features(Elf *elf, int phcount, int fd, char *val)
+{
+ u_int32_t features;
+ u_int64_t off;
+
+ if (!get_file_features(elf, phcount, fd, &features, &off)) {
+ warnx("NT_FREEBSD_FEATURE_CTL note not found");
+ return (false);
+ }
+
+ if (!convert_to_feature_val(val, &features))
+ return (false);
+
+ if (lseek(fd, off, SEEK_SET) == -1 ||
+ write(fd, &features, sizeof(features)) <
+ (ssize_t)sizeof(features)) {
+ warnx("error writing feature value");
+ return (false);
+ }
+ return (true);
+}
+
+static void
+print_features(void)
+{
+ size_t i;
+
+ printf("Known features are:\n");
+ for (i = 0; i < nitems(featurelist); ++i)
+ printf("%-16s%s\n", featurelist[i].alias,
+ featurelist[i].desc);
+}
+
+static bool
+print_file_features(Elf *elf, int phcount, int fd, char *filename)
+{
+ u_int32_t features;
+ unsigned long i;
+
+ if (!get_file_features(elf, phcount, fd, &features, NULL)) {
+ return (false);
+ }
+
+ printf("File '%s' features:\n", filename);
+ for (i = 0; i < nitems(featurelist); ++i) {
+ printf("%-16s'%s' is ", featurelist[i].alias,
+ featurelist[i].desc);
+
+ if ((featurelist[i].value & features) == 0)
+ printf("un");
+
+ printf("set.\n");
+ }
+ return (true);
+}
+
+static bool
+get_file_features(Elf *elf, int phcount, int fd, u_int32_t *features,
+ u_int64_t *off)
+{
+ GElf_Phdr phdr;
+ Elf_Note note;
+ unsigned long read_total;
+ int namesz, descsz, i;
+ char *name;
+ ssize_t size;
+
+ /*
+ * Go through each program header to find one that is of type PT_NOTE
+ * and has a note for feature control.
+ */
+ for (i = 0; i < phcount; ++i) {
+ if (gelf_getphdr(elf, i, &phdr) == NULL) {
+ warnx("gelf_getphdr failed: %s", elf_errmsg(-1));
+ return (false);
+ }
+
+ if (phdr.p_type != PT_NOTE)
+ continue;
+
+ if (lseek(fd, phdr.p_offset, SEEK_SET) < 0) {
+ warn("lseek() failed:");
+ return (false);
+ }
+
+ read_total = 0;
+ while (read_total < phdr.p_filesz) {
+ size = read(fd, ¬e, sizeof(note));
+ if (size < (ssize_t)sizeof(note)) {
+ warn("read() failed:");
+ return (false);
+ }
+ read_total += sizeof(note);
+
+ /*
+ * XXX: Name and descriptor are 4 byte aligned, however,
+ * the size given doesn't include the padding.
+ */
+ namesz = roundup2(note.n_namesz, 4);
+ name = malloc(namesz);
+ if (name == NULL) {
+ warn("malloc() failed.");
+ return (false);
+ }
+ descsz = roundup2(note.n_descsz, 4);
+ size = read(fd, name, namesz);
+ read_total += namesz;
+
+ if (note.n_namesz != 8 ||
+ strncmp("FreeBSD", name, 7) != 0 ||
+ note.n_type != NT_FREEBSD_FEATURE_CTL) {
+ /* Not the right note. Skip the description */
+ if (lseek(fd, descsz, SEEK_CUR) < 0) {
+ warn("lseek() failed.");
+ free(name);
+ return (false);
+ }
+ read_total += descsz;
+ free(name);
+ continue;
+ }
+
+ if (note.n_descsz < sizeof(u_int32_t)) {
+ warnx("Feature descriptor can't "
+ "be less than 4 bytes");
+ free(name);
+ return (false);
+ }
+
+ /*
+ * XXX: For now we look at only 4 bytes of the
+ * descriptor. This should respect descsz.
+ */
+ if (note.n_descsz > sizeof(u_int32_t))
+ warnx("Feature note is bigger than expected");
+ read(fd, features, sizeof(u_int32_t));
+ if (off != NULL)
+ *off = phdr.p_offset + read_total;
+ free(name);
+ return (true);
+ }
+ }
+
+ warnx("NT_FREEBSD_FEATURE_CTL note not found");
+ return (false);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 21, 11:22 AM (17 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15540819
Default Alt Text
D23910.diff (26 KB)
Attached To
Mode
D23910: Move ELF feature note tool to usr.bin/elfctl
Attached
Detach File
Event Timeline
Log In to Comment