diff options
-rw-r--r-- | guts/README | 1 | ||||
-rw-r--r-- | guts/execve.c | 17 | ||||
-rw-r--r-- | pseudo.c | 1 | ||||
-rw-r--r-- | pseudo.h | 4 | ||||
-rw-r--r-- | pseudo_client.c | 3 | ||||
-rw-r--r-- | pseudo_db.c | 1 | ||||
-rw-r--r-- | pseudo_table.c | 1 | ||||
-rw-r--r-- | pseudo_util.c | 4 | ||||
-rw-r--r-- | pseudolog.1 | 5 | ||||
-rw-r--r-- | pseudolog.c | 5 | ||||
-rw-r--r-- | wrapfuncs.in | 1 |
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; + * } + */ @@ -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; @@ -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); |