summaryrefslogtreecommitdiff
path: root/usr.bin/vi/ex
diff options
context:
space:
mode:
authorMatthias Kilian <kili@cvs.openbsd.org>2013-05-03 20:43:26 +0000
committerMatthias Kilian <kili@cvs.openbsd.org>2013-05-03 20:43:26 +0000
commitfc4e7800f4685450654eb04e191fba1dee02b299 (patch)
treec67251a31c1be9e97d8b84025c0603aa085faeeb /usr.bin/vi/ex
parente76a254a0f9ef4d6877f5286df7b932faea5cafb (diff)
Use open(2) / fstat(2) instead of stat(2) / open(2) for checking
proper permissions of "local" .exrc or .nexrc files. With some hints and fixes from deraadt@ and tobias@. ok millert@ tobias@ (more tweaks suggested by millert@ and some cleanup will be done in separate diffs)
Diffstat (limited to 'usr.bin/vi/ex')
-rw-r--r--usr.bin/vi/ex/ex_init.c77
-rw-r--r--usr.bin/vi/ex/ex_source.c37
2 files changed, 81 insertions, 33 deletions
diff --git a/usr.bin/vi/ex/ex_init.c b/usr.bin/vi/ex/ex_init.c
index 2d18324244f..02c3bcb113a 100644
--- a/usr.bin/vi/ex/ex_init.c
+++ b/usr.bin/vi/ex/ex_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ex_init.c,v 1.9 2009/10/27 23:59:47 deraadt Exp $ */
+/* $OpenBSD: ex_init.c,v 1.10 2013/05/03 20:43:25 kili Exp $ */
/*-
* Copyright (c) 1992, 1993, 1994
@@ -17,6 +17,7 @@
#include <sys/stat.h>
#include <bitstring.h>
+#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
@@ -29,9 +30,9 @@
#include "pathnames.h"
enum rc { NOEXIST, NOPERM, RCOK };
-static enum rc exrc_isok(SCR *, struct stat *, char *, int, int);
+static enum rc exrc_isok(SCR *, struct stat *, int *, char *, int, int);
-static int ex_run_file(SCR *, char *);
+static int ex_run_file(SCR *, int, char *);
/*
* ex_screen_copy --
@@ -143,6 +144,7 @@ ex_exrc(sp)
{
struct stat hsb, lsb;
char *p, path[MAXPATHLEN];
+ int fd;
/*
* Source the system, environment, $HOME and local .exrc values.
@@ -168,12 +170,12 @@ ex_exrc(sp)
* it's going to make some commands behave oddly, and I can't imagine
* anyone depending on it.
*/
- switch (exrc_isok(sp, &hsb, _PATH_SYSEXRC, 1, 0)) {
+ switch (exrc_isok(sp, &hsb, &fd, _PATH_SYSEXRC, 1, 0)) {
case NOEXIST:
case NOPERM:
break;
case RCOK:
- if (ex_run_file(sp, _PATH_SYSEXRC))
+ if (ex_run_file(sp, fd, _PATH_SYSEXRC))
return (1);
break;
}
@@ -192,18 +194,18 @@ ex_exrc(sp)
return (1);
} else if ((p = getenv("HOME")) != NULL && *p) {
(void)snprintf(path, sizeof(path), "%s/%s", p, _PATH_NEXRC);
- switch (exrc_isok(sp, &hsb, path, 0, 1)) {
+ switch (exrc_isok(sp, &hsb, &fd, path, 0, 1)) {
case NOEXIST:
(void)snprintf(path,
sizeof(path), "%s/%s", p, _PATH_EXRC);
- if (exrc_isok(sp,
- &hsb, path, 0, 1) == RCOK && ex_run_file(sp, path))
+ if (exrc_isok(sp, &hsb, &fd, path, 0, 1) == RCOK &&
+ ex_run_file(sp, fd, path))
return (1);
break;
case NOPERM:
break;
case RCOK:
- if (ex_run_file(sp, path))
+ if (ex_run_file(sp, fd, path))
return (1);
break;
}
@@ -217,21 +219,27 @@ ex_exrc(sp)
/* Previous commands may have set the exrc option. */
if (O_ISSET(sp, O_EXRC)) {
- switch (exrc_isok(sp, &lsb, _PATH_NEXRC, 0, 0)) {
+ switch (exrc_isok(sp, &lsb, &fd, _PATH_NEXRC, 0, 0)) {
case NOEXIST:
- if (exrc_isok(sp, &lsb, _PATH_EXRC, 0, 0) == RCOK &&
- (lsb.st_dev != hsb.st_dev ||
- lsb.st_ino != hsb.st_ino) &&
- ex_run_file(sp, _PATH_EXRC))
- return (1);
+ if (exrc_isok(sp, &lsb, &fd, _PATH_EXRC, 0, 0)
+ == RCOK) {
+ if (lsb.st_dev != hsb.st_dev ||
+ lsb.st_ino != hsb.st_ino) {
+ if (ex_run_file(sp, fd, _PATH_EXRC))
+ return (1);
+ } else
+ close(fd);
+ }
break;
case NOPERM:
break;
case RCOK:
- if ((lsb.st_dev != hsb.st_dev ||
- lsb.st_ino != hsb.st_ino) &&
- ex_run_file(sp, _PATH_NEXRC))
- return (1);
+ if (lsb.st_dev != hsb.st_dev ||
+ lsb.st_ino != hsb.st_ino) {
+ if (ex_run_file(sp, fd, _PATH_NEXRC))
+ return (1);
+ } else
+ close(fd);
break;
}
/* Run the commands. */
@@ -249,8 +257,9 @@ ex_exrc(sp)
* Set up a file of ex commands to run.
*/
static int
-ex_run_file(sp, name)
+ex_run_file(sp, fd, name)
SCR *sp;
+ int fd;
char *name;
{
ARGS *ap[2], a;
@@ -258,7 +267,7 @@ ex_run_file(sp, name)
ex_cinit(&cmd, C_SOURCE, 0, OOBLNO, OOBLNO, 0, ap);
ex_cadd(&cmd, &a, name, strlen(name));
- return (ex_source(sp, &cmd));
+ return (ex_sourcefd(sp, &cmd, fd));
}
/*
@@ -308,7 +317,7 @@ ex_run_str(sp, name, str, len, ex_flags, nocopy)
/*
* exrc_isok --
- * Check a .exrc file for source-ability.
+ * Open and check a .exrc file for source-ability.
*
* !!!
* Historically, vi read the $HOME and local .exrc files if they were owned
@@ -343,9 +352,10 @@ ex_run_str(sp, name, str, len, ex_flags, nocopy)
* files.
*/
static enum rc
-exrc_isok(sp, sbp, path, rootown, rootid)
+exrc_isok(sp, sbp, fdp, path, rootown, rootid)
SCR *sp;
struct stat *sbp;
+ int *fdp;
char *path;
int rootown, rootid;
{
@@ -354,9 +364,23 @@ exrc_isok(sp, sbp, path, rootown, rootid)
int nf1, nf2;
char *a, *b, buf[MAXPATHLEN];
- /* Check for the file's existence. */
- if (stat(path, sbp))
- return (NOEXIST);
+ if ((*fdp = open(path, O_RDONLY, 0)) < 0) {
+ if (errno == ENOENT)
+ /* This is the only case where ex_exrc()
+ * should silently try the next file, for
+ * example .exrc after .nexrc.
+ */
+ return (NOEXIST);
+
+ msgq_str(sp, M_SYSERR, path, "%s");
+ return (NOPERM);
+ }
+
+ if (fstat(*fdp, sbp)) {
+ msgq_str(sp, M_SYSERR, path, "%s");
+ close(*fdp);
+ return (NOPERM);
+ }
/* Check ownership permissions. */
euid = geteuid();
@@ -411,5 +435,6 @@ denied: a = msg_print(sp, path, &nf1);
if (nf1)
FREE_SPACE(sp, a, 0);
+ close(*fdp);
return (NOPERM);
}
diff --git a/usr.bin/vi/ex/ex_source.c b/usr.bin/vi/ex/ex_source.c
index 8bd88bb24ac..d772fe3cb45 100644
--- a/usr.bin/vi/ex/ex_source.c
+++ b/usr.bin/vi/ex/ex_source.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ex_source.c,v 1.7 2009/10/27 23:59:47 deraadt Exp $ */
+/* $OpenBSD: ex_source.c,v 1.8 2013/05/03 20:43:25 kili Exp $ */
/*-
* Copyright (c) 1992, 1993, 1994
@@ -27,22 +27,23 @@
#include "../common/common.h"
/*
- * ex_source -- :source file
- * Execute ex commands from a file.
+ * ex_sourcefd -- :source already opened file
+ * Execute ex commands from the given file descriptor
*
- * PUBLIC: int ex_source(SCR *, EXCMD *);
+ * PUBLIC: int ex_sourcefd(SCR *, EXCMD *, int);
*/
int
-ex_source(sp, cmdp)
+ex_sourcefd(sp, cmdp, fd)
SCR *sp;
EXCMD *cmdp;
+ int fd;
{
struct stat sb;
- int fd, len;
+ int len;
char *bp, *name;
name = cmdp->argv[0]->bp;
- if ((fd = open(name, O_RDONLY, 0)) < 0 || fstat(fd, &sb))
+ if (fstat(fd, &sb))
goto err;
/*
@@ -81,3 +82,25 @@ err: msgq_str(sp, M_SYSERR, name, "%s");
/* Put it on the ex queue. */
return (ex_run_str(sp, name, bp, (size_t)sb.st_size, 1, 1));
}
+
+/*
+ * ex_source -- :source file
+ * Execute ex commands from a file.
+ *
+ * PUBLIC: int ex_source(SCR *, EXCMD *);
+ */
+int
+ex_source(sp, cmdp)
+ SCR *sp;
+ EXCMD *cmdp;
+{
+ char *name;
+ int fd;
+
+ name = cmdp->argv[0]->bp;
+ if ((fd = open(name, O_RDONLY, 0)) >= 0)
+ return (ex_sourcefd(sp, cmdp, fd));
+
+ msgq_str(sp, M_SYSERR, name, "%s");
+ return (1);
+}