aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--guts/README1
-rw-r--r--guts/execve.c17
-rw-r--r--pseudo.c1
-rw-r--r--pseudo.h4
-rw-r--r--pseudo_client.c3
-rw-r--r--pseudo_db.c1
-rw-r--r--pseudo_table.c1
-rw-r--r--pseudo_util.c4
-rw-r--r--pseudolog.15
-rw-r--r--pseudolog.c5
-rw-r--r--wrapfuncs.in1
11 files changed, 40 insertions, 3 deletions
diff --git a/guts/README b/guts/README
index 277f712..e933349 100644
--- a/guts/README
+++ b/guts/README
@@ -83,6 +83,7 @@ wrappers:
close
dup
dup2
+ execve (note that all other exec* functions redirect here)
fclose
fopen
fopen64
diff --git a/guts/execve.c b/guts/execve.c
new file mode 100644
index 0000000..e202575
--- /dev/null
+++ b/guts/execve.c
@@ -0,0 +1,17 @@
+/*
+ * static int
+ * wrap_execve(const char *filename, char *const *argv, char *const *envp) {
+ * int rc = -1;
+ */
+ /* note: we don't canonicalize this, because we are intentionally
+ * NOT redirecting execs into the chroot environment. If you try
+ * to execute /bin/sh, you get the actual /bin/sh, not
+ * <CHROOT>/bin/sh. This allows use of basic utilities. This
+ * design will likely be revisited.
+ */
+ pseudo_client_op(OP_EXEC, PSA_EXEC, 0, 0, filename, 0);
+ rc = real_execve(filename, argv, envp);
+
+/* return rc;
+ * }
+ */
diff --git a/pseudo.c b/pseudo.c
index e6e6a39..583adb1 100644
--- a/pseudo.c
+++ b/pseudo.c
@@ -481,6 +481,7 @@ pseudo_op(pseudo_msg_t *msg, const char *tag) {
* as of this writing, but might be logged by accident: */
pseudo_diag("error: op %s sent to server.\n", pseudo_op_name(msg->op));
break;
+ case OP_EXEC:
case OP_OPEN:
/* nothing to do -- just sent in case we're logging */
break;
diff --git a/pseudo.h b/pseudo.h
index aec6f60..93f3e89 100644
--- a/pseudo.h
+++ b/pseudo.h
@@ -40,7 +40,11 @@ typedef enum {
OP_RENAME,
OP_STAT,
OP_UNLINK,
+ /* added after the original release, so they have to go out of order
+ * to avoid breaking the operation numbers in old logs.
+ */
OP_SYMLINK,
+ OP_EXEC,
OP_MAX
} op_id_t;
extern char *pseudo_op_name(op_id_t id);
diff --git a/pseudo_client.c b/pseudo_client.c
index 3066570..e144456 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -835,10 +835,11 @@ pseudo_client_op(op_id_t op, int access, int fd, int dirfd, const char *path, co
* (operations which can create should be CREAT or MKNOD
* or MKDIR)
*/
- case OP_LINK:
+ case OP_EXEC:
case OP_CHOWN:
case OP_FCHOWN:
case OP_FSTAT:
+ case OP_LINK:
case OP_RENAME:
case OP_STAT:
case OP_UNLINK:
diff --git a/pseudo_db.c b/pseudo_db.c
index 84a9103..04eb412 100644
--- a/pseudo_db.c
+++ b/pseudo_db.c
@@ -63,6 +63,7 @@ id_row op_rows[] = {
OP_ROW(OP_CLOSE, "close"),
OP_ROW(OP_CREAT, "creat"),
OP_ROW(OP_DUP, "dup"),
+ OP_ROW(OP_EXEC, "exec"),
OP_ROW(OP_FCHMOD, "fchmod"),
OP_ROW(OP_FCHOWN, "fchown"),
OP_ROW(OP_FSTAT, "fstat"),
diff --git a/pseudo_table.c b/pseudo_table.c
index 171ba7b..7225422 100644
--- a/pseudo_table.c
+++ b/pseudo_table.c
@@ -43,6 +43,7 @@ static char *operation_names[] = {
"stat",
"unlink",
"symlink",
+ "exec",
NULL
};
diff --git a/pseudo_util.c b/pseudo_util.c
index 55e0488..bb60edb 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -604,6 +604,10 @@ pseudo_access_fopen(const char *mode) {
if (mode[1] == '+' || (mode[1] == 'b' && mode[2] == '+'))
access |= PSA_READ;
break;
+ /* special case */
+ case 'x':
+ access |= PSA_EXEC;
+ break;
default:
access = -1;
break;
diff --git a/pseudolog.1 b/pseudolog.1
index 8aaf9c8..b7c9bbb 100644
--- a/pseudolog.1
+++ b/pseudolog.1
@@ -185,7 +185,10 @@ such as "r+" to indicate read/write access. Note that specifying
.B \&a
as an access mode will include non-append writes, as the "a" mode
implies write and append both. This feature is slightly experimental
-and may not correctly identify the access type of every access.
+and may not correctly identify the access type of every access. The
+string
+.B x
+may be specified to indicate execute access.
.TP 8
.B c
Client ID (the PID of a client).
diff --git a/pseudolog.c b/pseudolog.c
index 4d189b6..877a643 100644
--- a/pseudolog.c
+++ b/pseudolog.c
@@ -382,7 +382,7 @@ plog_trait(int opt, char *string) {
case PSQF_ACCESS:
new_trait->data.ivalue = pseudo_access_fopen(string);
if (new_trait->data.ivalue == (unsigned long long) -1) {
- pseudo_diag("access flags should be specified like fopen(3) mode strings.\n");
+ pseudo_diag("access flags should be specified like fopen(3) mode strings (or x for exec).\n");
free(new_trait);
return 0;
}
@@ -646,6 +646,7 @@ format_one(log_entry *e, char *format) {
switch (*s) {
case 'a': /* PSQF_ACCESS */
+ *scratch = '\0';
if (e->access == -1) {
strcpy(scratch, "invalid");
} else if (e->access != 0) {
@@ -661,6 +662,8 @@ format_one(log_entry *e, char *format) {
}
if (e->access & PSA_READ)
strcat(scratch, "+");
+ } else if (e->access & PSA_EXEC) {
+ strcpy(scratch, "x");
}
/* this should be impossible... should. */
if (e->access & PSA_APPEND && !(e->access & PSA_WRITE)) {
diff --git a/wrapfuncs.in b/wrapfuncs.in
index 2eabd5d..22510dc 100644
--- a/wrapfuncs.in
+++ b/wrapfuncs.in
@@ -88,3 +88,4 @@ char *tmpnam(char *s);
int truncate(const char *path, off_t length);
int utime(const char *path, const struct utimbuf *buf);
int utimes(const char *path, const struct timeval *times);
+int execve(const char *filename, char *const *argv, char *const *envp);