sh: Add -o verify to use O_VERIFY when sourcing scripts
Add -o verify to sh to make it use O_VERIFY when sourcing scripts and reading profiles. Useful in conjunction with mac_veriexec to help protect at least some parts of the boot sequence, e.g., /etc/rc*. Differential revision: https://reviews.freebsd.org/D30464 Reviewed by: jilles, sjg Obtained from: Stormshield
This commit is contained in:
parent
90f6610b19
commit
d2c233176f
@ -418,7 +418,7 @@ find_command(const char *name, struct cmdentry *entry, int act,
|
||||
if (!S_ISREG(statb.st_mode))
|
||||
continue;
|
||||
if (opt) { /* this is a %func directory */
|
||||
readcmdfile(fullname);
|
||||
readcmdfile(fullname, -1 /* verify */);
|
||||
if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION)
|
||||
error("%s not defined in %s", name, fullname);
|
||||
stunalloc(fullname);
|
||||
|
@ -447,7 +447,7 @@ histcmd(int argc, char **argv __unused)
|
||||
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
|
||||
sprintf(editcmd, "%s %s", editor, editfile);
|
||||
evalstring(editcmd, 0); /* XXX - should use no JC command */
|
||||
readcmdfile(editfile); /* XXX - should read back - quick tst */
|
||||
readcmdfile(editfile, 0 /* verify */); /* XXX - should read back - quick tst */
|
||||
unlink(editfile);
|
||||
}
|
||||
|
||||
|
@ -352,17 +352,25 @@ popstring(void)
|
||||
/*
|
||||
* Set the input to take input from a file. If push is set, push the
|
||||
* old input onto the stack first.
|
||||
* About verify:
|
||||
* -1: Obey verifyflag
|
||||
* 0: Do not verify
|
||||
* 1: Do verify
|
||||
*/
|
||||
|
||||
void
|
||||
setinputfile(const char *fname, int push)
|
||||
setinputfile(const char *fname, int push, int verify)
|
||||
{
|
||||
int e;
|
||||
int fd;
|
||||
int fd2;
|
||||
int oflags = O_RDONLY | O_CLOEXEC;
|
||||
|
||||
if (verify == 1 || (verify == -1 && verifyflag))
|
||||
oflags |= O_VERIFY;
|
||||
|
||||
INTOFF;
|
||||
if ((fd = open(fname, O_RDONLY | O_CLOEXEC)) < 0) {
|
||||
if ((fd = open(fname, oflags)) < 0) {
|
||||
e = errno;
|
||||
errorwithstatus(e == ENOENT || e == ENOTDIR ? 127 : 126,
|
||||
"cannot open %s: %s", fname, strerror(e));
|
||||
|
@ -53,7 +53,7 @@ int preadbuffer(void);
|
||||
int preadateof(void);
|
||||
void pungetc(void);
|
||||
void pushstring(const char *, int, struct alias *);
|
||||
void setinputfile(const char *, int);
|
||||
void setinputfile(const char *, int, int);
|
||||
void setinputfd(int, int);
|
||||
void setinputstring(const char *, int);
|
||||
void popfile(void);
|
||||
|
@ -253,12 +253,16 @@ read_profile(const char *name)
|
||||
{
|
||||
int fd;
|
||||
const char *expandedname;
|
||||
int oflags = O_RDONLY | O_CLOEXEC;
|
||||
|
||||
if (verifyflag)
|
||||
oflags |= O_VERIFY;
|
||||
|
||||
expandedname = expandstr(name);
|
||||
if (expandedname == NULL)
|
||||
return;
|
||||
INTOFF;
|
||||
if ((fd = open(expandedname, O_RDONLY | O_CLOEXEC)) >= 0)
|
||||
if ((fd = open(expandedname, oflags)) >= 0)
|
||||
setinputfd(fd, 1);
|
||||
INTON;
|
||||
if (fd < 0)
|
||||
@ -274,9 +278,9 @@ read_profile(const char *name)
|
||||
*/
|
||||
|
||||
void
|
||||
readcmdfile(const char *name)
|
||||
readcmdfile(const char *name, int verify)
|
||||
{
|
||||
setinputfile(name, 1);
|
||||
setinputfile(name, 1, verify);
|
||||
cmdloop(0);
|
||||
popfile();
|
||||
}
|
||||
@ -331,7 +335,7 @@ dotcmd(int argc, char **argv)
|
||||
filename = argc > 2 && strcmp(argv[1], "--") == 0 ? argv[2] : argv[1];
|
||||
|
||||
fullname = find_dot_file(filename);
|
||||
setinputfile(fullname, 1);
|
||||
setinputfile(fullname, 1, -1 /* verify */);
|
||||
commandname = fullname;
|
||||
cmdloop(0);
|
||||
popfile();
|
||||
|
@ -39,4 +39,4 @@ extern int rootpid; /* pid of main shell */
|
||||
extern int rootshell; /* true if we aren't a child of the main shell */
|
||||
extern struct jmploc main_handler; /* top level exception handler */
|
||||
|
||||
void readcmdfile(const char *);
|
||||
void readcmdfile(const char *, int);
|
||||
|
@ -112,7 +112,7 @@ procargs(int argc, char **argv)
|
||||
arg0 = argv[0];
|
||||
if (sflag == 0 && minusc == NULL) {
|
||||
scriptname = *argptr++;
|
||||
setinputfile(scriptname, 0);
|
||||
setinputfile(scriptname, 0, -1 /* verify */);
|
||||
commandname = arg0 = scriptname;
|
||||
}
|
||||
/* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
|
||||
|
@ -68,9 +68,10 @@ struct shparam {
|
||||
#define hflag optval[18]
|
||||
#define nologflag optval[19]
|
||||
#define pipefailflag optval[20]
|
||||
#define verifyflag optval[21]
|
||||
|
||||
#define NSHORTOPTS 19
|
||||
#define NOPTS 21
|
||||
#define NOPTS 22
|
||||
|
||||
extern char optval[NOPTS];
|
||||
extern const char optletter[NSHORTOPTS];
|
||||
@ -99,6 +100,7 @@ static const unsigned char optname[] =
|
||||
"\010trackall"
|
||||
"\005nolog"
|
||||
"\010pipefail"
|
||||
"\006verify"
|
||||
;
|
||||
#endif
|
||||
|
||||
|
@ -355,6 +355,11 @@ if a command such as
|
||||
in the pipeline terminates with status 0 without reading its
|
||||
input completely.
|
||||
This option only has a long name.
|
||||
.It Li verify
|
||||
Set
|
||||
.Dv O_VERIFY
|
||||
when sourcing files or loading profiles. See also
|
||||
.Xr mac_veriexec 4 .
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
|
Loading…
Reference in New Issue
Block a user