Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/brandelf/brandelf.c
Show All 26 Lines | |||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/capsicum.h> | |||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/elf_common.h> | #include <sys/elf_common.h> | ||||
#include <sys/errno.h> | #include <sys/errno.h> | ||||
#include <capsicum_helpers.h> | |||||
#include <err.h> | #include <err.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <libcasper.h> | |||||
#include <casper/cap_fileargs.h> | |||||
static int elftype(const char *); | static int elftype(const char *); | ||||
static const char *iselftype(int); | static const char *iselftype(int); | ||||
static void printelftypes(void); | static void printelftypes(void); | ||||
static void usage(void); | static void usage(void); | ||||
struct ELFtypes { | struct ELFtypes { | ||||
const char *str; | const char *str; | ||||
int value; | int value; | ||||
}; | }; | ||||
/* XXX - any more types? */ | /* XXX - any more types? */ | ||||
static struct ELFtypes elftypes[] = { | static struct ELFtypes elftypes[] = { | ||||
{ "FreeBSD", ELFOSABI_FREEBSD }, | { "FreeBSD", ELFOSABI_FREEBSD }, | ||||
{ "Linux", ELFOSABI_LINUX }, | { "Linux", ELFOSABI_LINUX }, | ||||
{ "Solaris", ELFOSABI_SOLARIS }, | { "Solaris", ELFOSABI_SOLARIS }, | ||||
{ "SVR4", ELFOSABI_SYSV } | { "SVR4", ELFOSABI_SYSV } | ||||
}; | }; | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
{ | { | ||||
const char *strtype = "FreeBSD"; | const char *strtype = "FreeBSD"; | ||||
int ch, retval, type; | int ch, flags, retval, type; | ||||
bool change, force, listed; | bool change, force, listed; | ||||
fileargs_t *fa; | |||||
cap_rights_t rights; | |||||
type = ELFOSABI_FREEBSD; | type = ELFOSABI_FREEBSD; | ||||
retval = 0; | retval = 0; | ||||
change = false; | change = false; | ||||
force = false; | force = false; | ||||
listed = false; | listed = false; | ||||
while ((ch = getopt(argc, argv, "f:lt:v")) != -1) | while ((ch = getopt(argc, argv, "f:lt:v")) != -1) | ||||
Show All 37 Lines | main(int argc, char **argv) | ||||
} | } | ||||
if (!force && (type = elftype(strtype)) == -1) { | if (!force && (type = elftype(strtype)) == -1) { | ||||
warnx("invalid ELF type '%s'", strtype); | warnx("invalid ELF type '%s'", strtype); | ||||
printelftypes(); | printelftypes(); | ||||
usage(); | usage(); | ||||
} | } | ||||
flags = change || force ? O_RDWR : O_RDONLY; | |||||
cap_rights_init(&rights, CAP_READ, CAP_SEEK); | |||||
if (flags == O_RDWR) | |||||
cap_rights_set(&rights, CAP_WRITE); | |||||
fa = fileargs_init(argc, argv, flags, 0, &rights); | |||||
if (fa == NULL) | |||||
errx(1, "unable to init casper"); | |||||
caph_cache_catpages(); | |||||
if (caph_limit_stdio() < 0 || caph_enter_casper() < 0) | |||||
markj: These should really have separate error messages. | |||||
emasteUnsubmitted Not Done Inline ActionsI'm indifferent on that - is there a different action the user can take based on which error message comes out? emaste: I'm indifferent on that - is there a different action the user can take based on which error… | |||||
markjUnsubmitted Not Done Inline ActionsNo, but the first step taken by anyone debugging the error will be to figure out which of the two calls is failing. markj: No, but the first step taken by anyone debugging the error will be to figure out which of the… | |||||
emasteUnsubmitted Not Done Inline ActionsMost likely the first action is to set kern.trap_enotcap to 1 and get a backtrace? Anyway I'm fine with either. emaste: Most likely the first action is to set `kern.trap_enotcap` to 1 and get a backtrace? Anyway I'm… | |||||
err(1, "unable to enter capability mode"); | |||||
while (argc != 0) { | while (argc != 0) { | ||||
int fd; | int fd; | ||||
char buffer[EI_NIDENT]; | char buffer[EI_NIDENT]; | ||||
if ((fd = open(argv[0], change || force ? O_RDWR : O_RDONLY, 0)) < 0) { | if ((fd = fileargs_open(fa, argv[0])) < 0) { | ||||
warn("error opening file %s", argv[0]); | warn("error opening file %s", argv[0]); | ||||
retval = 1; | retval = 1; | ||||
goto fail; | goto fail; | ||||
} | } | ||||
if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { | if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { | ||||
warnx("file '%s' too short", argv[0]); | warnx("file '%s' too short", argv[0]); | ||||
retval = 1; | retval = 1; | ||||
goto fail; | goto fail; | ||||
Show All 25 Lines | else { | ||||
} | } | ||||
} | } | ||||
fail: | fail: | ||||
close(fd); | close(fd); | ||||
argc--; | argc--; | ||||
argv++; | argv++; | ||||
} | } | ||||
fileargs_free(fa); | |||||
return retval; | return retval; | ||||
} | } | ||||
static void | static void | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
(void)fprintf(stderr, | (void)fprintf(stderr, | ||||
"usage: brandelf [-lv] [-f ELF_ABI_number] [-t string] file ...\n"); | "usage: brandelf [-lv] [-f ELF_ABI_number] [-t string] file ...\n"); | ||||
Show All 36 Lines |
These should really have separate error messages.