Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/crunch/crunchgen/crunched_main.c
Show All 17 Lines | |||||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | * 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 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||||||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||||
* | * | ||||||||
* Author: James da Silva, Systems Design and Analysis Group | * Author: James da Silva, Systems Design and Analysis Group | ||||||||
* Computer Science Department | * Computer Science Department | ||||||||
* University of Maryland at College Park | * University of Maryland at College Park | ||||||||
*/ | */ | ||||||||
/*- | |||||||||
* SPDX-License-Identifier: BSD-2-Clause | |||||||||
* | |||||||||
* Copyright 2020 Alex Richardson <arichardson@FreeBSD.org> | |||||||||
* | |||||||||
* This software was developed by SRI International and the University of | |||||||||
* Cambridge Computer Laboratory (Department of Computer Science and | |||||||||
* Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the | |||||||||
* DARPA SSITH research programme. | |||||||||
* | |||||||||
* 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. | |||||||||
* | |||||||||
*/ | |||||||||
/* | /* | ||||||||
* crunched_main.c - main program for crunched binaries, it branches to a | * crunched_main.c - main program for crunched binaries, it branches to a | ||||||||
* particular subprogram based on the value of argv[0]. Also included | * particular subprogram based on the value of argv[0]. Also included | ||||||||
* is a little program invoked when the crunched binary is called via | * is a little program invoked when the crunched binary is called via | ||||||||
* its EXECNAME. This one prints out the list of compiled-in binaries, | * its EXECNAME. This one prints out the list of compiled-in binaries, | ||||||||
* or calls one of them based on argv[1]. This allows the testing of | * or calls one of them based on argv[1]. This allows the testing of | ||||||||
* the crunched binary without creating all the links. | * the crunched binary without creating all the links. | ||||||||
*/ | */ | ||||||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||||||
#include <sys/param.h> | |||||||||
#include <sys/auxv.h> | |||||||||
#include <sys/sysctl.h> | |||||||||
#include <err.h> | |||||||||
#include <stdio.h> | #include <stdio.h> | ||||||||
#include <stdlib.h> | #include <stdlib.h> | ||||||||
#include <string.h> | #include <string.h> | ||||||||
struct stub { | struct stub { | ||||||||
char *name; | char *name; | ||||||||
int (*f)(); | int (*f)(); | ||||||||
}; | }; | ||||||||
extern char *__progname; | extern const char *__progname; | ||||||||
extern struct stub entry_points[]; | extern struct stub entry_points[]; | ||||||||
static void crunched_usage(void); | static void crunched_usage(void); | ||||||||
static struct stub * | |||||||||
find_entry_point(const char *basename) | |||||||||
{ | |||||||||
struct stub *ep = NULL; | |||||||||
for (ep = entry_points; ep->name != NULL; ep++) | |||||||||
if (!strcmp(basename, ep->name)) | |||||||||
break; | |||||||||
return (ep); | |||||||||
} | |||||||||
static const char * | |||||||||
get_basename(const char *exe_path) | |||||||||
{ | |||||||||
const char *slash = strrchr(exe_path, '/'); | |||||||||
return (slash ? slash + 1 : exe_path); | |||||||||
} | |||||||||
int | int | ||||||||
main(int argc, char **argv, char **envp) | main(int argc, char **argv, char **envp) | ||||||||
{ | { | ||||||||
char *slash, *basename; | struct stub *ep = NULL; | ||||||||
struct stub *ep; | const char *basename = NULL; | ||||||||
if (argv[0] == NULL || *argv[0] == '\0') | /* | ||||||||
crunched_usage(); | * Look at __progname first (this will be set if the crunched binary is | ||||||||
* invoked directly). | |||||||||
*/ | |||||||||
if (__progname) { | |||||||||
basename = get_basename(__progname); | |||||||||
ep = find_entry_point(basename); | |||||||||
} | |||||||||
slash = strrchr(argv[0], '/'); | /* | ||||||||
basename = slash ? slash + 1 : argv[0]; | * Otherwise try to find entry point based on argv[0] (this works for | ||||||||
* both symlinks as well as hardlinks). However, it does not work when | |||||||||
* su invokes a crunched shell because it sets argv[0] to _su when | |||||||||
* invoking the shell. In that case we look at AT_EXECPATH as a | |||||||||
* fallback. | |||||||||
*/ | |||||||||
if (ep == NULL) { | |||||||||
basename = get_basename(argv[0]); | |||||||||
ep = find_entry_point(basename); | |||||||||
} | |||||||||
for (ep = entry_points; ep->name != NULL; ep++) | /* | ||||||||
if (!strcmp(basename, ep->name)) | * If we didn't find the entry point based on __progname or argv[0], | ||||||||
break; | * try AT_EXECPATH to get the actual binary that was executed. | ||||||||
*/ | |||||||||
if (ep == NULL) { | |||||||||
char buf[MAXPATHLEN]; | |||||||||
brooksUnsubmitted Done Inline Actions
brooks: | |||||||||
int error = elf_aux_info(AT_EXECPATH, &buf, sizeof(buf)); | |||||||||
if (ep->name) | if (error == 0) { | ||||||||
const char *exe_name = get_basename(buf); | |||||||||
/* | |||||||||
* Keep using argv[0] if AT_EXECPATH is the crunched | |||||||||
* binary so that symlinks to the crunched binary report | |||||||||
* "not compiled in" instead of invoking | |||||||||
* crunched_main(). | |||||||||
*/ | |||||||||
if (strcmp(exe_name, EXECNAME) != 0) { | |||||||||
basename = exe_name; | |||||||||
ep = find_entry_point(basename); | |||||||||
} | |||||||||
Done Inline ActionsThe :\n seems odd, I would expect no newline emaste: The `:\n` seems odd, I would expect no newline | |||||||||
Done Inline Actions
That was a bug caused by me converting the CheriBSD fprintf() to use warnc(). Will fix. arichardson: > The `:\n` seems odd, I would expect no newline
That was a bug caused by me converting the… | |||||||||
} else { | |||||||||
warnc(error, "elf_aux_info(AT_EXECPATH) failed"); | |||||||||
Not Done Inline ActionsThe : shouldn't be required at all. The manpage says: The err(), errc(), verr(), verrc(), warn(), warnc(), vwarn(), and vwarnc() functions append an error message obtained from strerror(3) based on a supplied error code value or the global variable errno, preceded by another colon and space unless the fmt argument is NULL. brooks: The `:` shouldn't be required at all. The manpage says:
```
The err(), errc(), verr()… | |||||||||
} | |||||||||
} | |||||||||
if (basename == NULL || *basename == '\0') | |||||||||
crunched_usage(); | |||||||||
if (ep != NULL) { | |||||||||
return ep->f(argc, argv, envp); | return ep->f(argc, argv, envp); | ||||||||
else { | } else { | ||||||||
fprintf(stderr, "%s: %s not compiled in\n", EXECNAME, basename); | fprintf(stderr, "%s: %s not compiled in\n", EXECNAME, basename); | ||||||||
crunched_usage(); | crunched_usage(); | ||||||||
} | } | ||||||||
} | } | ||||||||
int | int | ||||||||
crunched_main(int argc, char **argv, char **envp) | crunched_main(int argc, char **argv, char **envp) | ||||||||
{ | { | ||||||||
char *slash; | |||||||||
struct stub *ep; | |||||||||
int columns, len; | |||||||||
if (argc <= 1) | if (argc <= 1) | ||||||||
crunched_usage(); | crunched_usage(); | ||||||||
slash = strrchr(argv[1], '/'); | __progname = get_basename(argv[1]); | ||||||||
__progname = slash ? slash + 1 : argv[1]; | |||||||||
return main(--argc, ++argv, envp); | return main(--argc, ++argv, envp); | ||||||||
} | } | ||||||||
static void | static void | ||||||||
crunched_usage() | crunched_usage() | ||||||||
{ | { | ||||||||
int columns, len; | int columns, len; | ||||||||
struct stub *ep; | struct stub *ep; | ||||||||
Show All 19 Lines |