aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephane Rochoy <stephane.rochoy@stormshield.eu>2021-09-23 08:40:59 +0000
committerWojciech Macek <wma@FreeBSD.org>2021-09-23 08:43:09 +0000
commitd2c233176f44944ef3ed941a60010839340c06a7 (patch)
tree2794d8c5bd9db09b831248eef2f235ed16aa25d7
parent90f6610b197550d841bcc13b7c2a90be627443b5 (diff)
downloadsrc-d2c233176f44944ef3ed941a60010839340c06a7.tar.gz
src-d2c233176f44944ef3ed941a60010839340c06a7.zip
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
-rw-r--r--bin/sh/exec.c2
-rw-r--r--bin/sh/histedit.c2
-rw-r--r--bin/sh/input.c12
-rw-r--r--bin/sh/input.h2
-rw-r--r--bin/sh/main.c12
-rw-r--r--bin/sh/main.h2
-rw-r--r--bin/sh/options.c2
-rw-r--r--bin/sh/options.h4
-rw-r--r--bin/sh/sh.15
9 files changed, 31 insertions, 12 deletions
diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index e3779b097e1d..43095a252a35 100644
--- a/bin/sh/exec.c
+++ b/bin/sh/exec.c
@@ -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);
diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c
index 96511b87b451..3c113333f4c8 100644
--- a/bin/sh/histedit.c
+++ b/bin/sh/histedit.c
@@ -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);
}
diff --git a/bin/sh/input.c b/bin/sh/input.c
index a8d048fc4890..3933287524a4 100644
--- a/bin/sh/input.c
+++ b/bin/sh/input.c
@@ -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));
diff --git a/bin/sh/input.h b/bin/sh/input.h
index 71046b9731c3..edb622b6ec2e 100644
--- a/bin/sh/input.h
+++ b/bin/sh/input.h
@@ -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);
diff --git a/bin/sh/main.c b/bin/sh/main.c
index b0a5fac6fd4e..bc87440807b2 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -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();
diff --git a/bin/sh/main.h b/bin/sh/main.h
index ff0a1c61fa22..d12c7ab77fed 100644
--- a/bin/sh/main.h
+++ b/bin/sh/main.h
@@ -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);
diff --git a/bin/sh/options.c b/bin/sh/options.c
index 73d79ca9a74f..97171d32bff1 100644
--- a/bin/sh/options.c
+++ b/bin/sh/options.c
@@ -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... */
diff --git a/bin/sh/options.h b/bin/sh/options.h
index 500d4ad5a903..7c9c4513aa33 100644
--- a/bin/sh/options.h
+++ b/bin/sh/options.h
@@ -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
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index ca3faeff13af..c49230133f9f 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -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