summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/systrace.4208
1 files changed, 179 insertions, 29 deletions
diff --git a/share/man/man4/systrace.4 b/share/man/man4/systrace.4
index 9d3d4a0d4b9..69c3acb57d3 100644
--- a/share/man/man4/systrace.4
+++ b/share/man/man4/systrace.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: systrace.4,v 1.14 2004/11/08 00:53:10 jmc Exp $
+.\" $OpenBSD: systrace.4,v 1.15 2004/11/09 23:23:56 jaredy Exp $
.\"
.\" Copyright (c) 2002, 2003 CubeSoft Communications, Inc.
.\" All rights reserved.
@@ -46,16 +46,16 @@ interface.
.Nm
can assign the following policies to system calls:
.Bl -tag -width SYSTR_POLICY_XXXXXX
-.It SYSTR_POLICY_ASK
+.It Dv SYSTR_POLICY_ASK
Send a message of the type
.Dv SYSTR_MSG_ASK ,
and put the process to sleep until a
.Dv STRIOCANSWER
.Xr ioctl 2
is made.
-.It SYSTR_POLICY_PERMIT
+.It Dv SYSTR_POLICY_PERMIT
Immediately allow the system call.
-.It SYSTR_POLICY_NEVER
+.It Dv SYSTR_POLICY_NEVER
Immediately return an error code.
.El
.Sh SYSTRACE MESSAGES
@@ -68,14 +68,15 @@ return the following structure:
.Bd -literal
struct str_message {
int msg_type;
-#define SYSTR_MSG_ASK 1
-#define SYSTR_MSG_RES 2
-#define SYSTR_MSG_EMUL 3
-#define SYSTR_MSG_CHILD 4
+#define SYSTR_MSG_ASK 1
+#define SYSTR_MSG_RES 2
+#define SYSTR_MSG_EMUL 3
+#define SYSTR_MSG_CHILD 4
#define SYSTR_MSG_UGID 5
#define SYSTR_MSG_POLICYFREE 6
#define SYSTR_MSG_EXECVE 7
pid_t msg_pid;
+ u_int16_t msg_seqnr; /* answer has to match seqnr */
short msg_policy;
union {
struct str_msg_emul msg_emul;
@@ -111,7 +112,8 @@ struct str_msg_child {
pid_t new_pid;
};
.Ed
-These messages are all to the userland control process.
+.Pp
+These messages are all sent to the userland control process.
.Bl -tag -width SYSTR_MSG_XXXXXXXXXX
.It SYSTR_MSG_ASK
This message is sent whenever the kernel does not have a cached
@@ -146,17 +148,15 @@ argument.
supports the following
.Xr ioctl 2
commands:
-.Bl -tag -width STRIOCXXXXXXXX
-.It Dv SYSTR_CLONE Fa "int"
+.Bl -tag -width Ds
+.It Dv STRIOCCLONE Fa "int *"
Return a
.Nm
file descriptor for
further
.Xr ioctl 2
operations.
-.El
-.Bl -tag -width STRIOCXXXXXXXX
-.It Dv STRIOCATTACH Fa "pid_t"
+.It Dv STRIOCATTACH Fa "pid_t *"
Attach to a process, unless:
.Bl -enum -compact -width 2n
.It
@@ -174,9 +174,9 @@ and the
kernel was not compiled with
.Cd option INSECURE .
.El
-.It Dv STRIOCDETACH Fa "pid_t"
+.It Dv STRIOCDETACH Fa "pid_t *"
Wake up a process if it is waiting for an answer, and detach from it.
-.It Dv STRIOCANSWER Fa "struct systrace_answer"
+.It Dv STRIOCANSWER Fa "struct systrace_answer *"
Tell
.Nm
what to do with a system call that was assigned a policy of
@@ -184,37 +184,46 @@ what to do with a system call that was assigned a policy of
.Bd -literal
struct systrace_answer {
pid_t stra_pid; /* PID of process being traced */
+ u_int16_t stra_seqnr;
+ short reserved;
+ uid_t stra_seteuid; /* Elevated privileges for syscall */
+ uid_t stra_setegid;
int stra_policy; /* Policy to assign */
int stra_error; /* Return value of denied syscall
(will return EPERM if zero) */
int stra_flags;
-#define SYSTR_FLAGS_RESULT 0x0001 /* Report syscall result */
+#define SYSTR_FLAGS_RESULT 0x001 /* Report syscall result */
+#define SYSTR_FLAGS_SETEUID 0x002
+#define SYSTR_FLAGS_SETEGID 0x004
};
.Ed
-.It Dv STRIOCREPORT Fa "pid_t"
+.It Dv STRIOCREPORT Fa "pid_t *"
Report the current emulation a process is using inside the
-.Va msg_emul
+.Vt msg_emul
structure.
-.It Dv STRIOCREPLACE Fa "struct systrace_replace"
+.It Dv STRIOCREPLACE Fa "struct systrace_replace *"
Arrange for system call arguments to be replaced by arguments
supplied by the monitoring process.
.Bd -literal
struct systrace_replace {
pid_t strr_pid;
+ u_int16_t strr_seqnr;
+ int16_t reserved;
int strr_nrepl; /* # of arguments to replace */
caddr_t strr_base; /* Base user memory */
size_t strr_len; /* Length of memory */
int strr_argind[SYSTR_MAXARGS]; /* Argument indexes */
size_t strr_off[SYSTR_MAXARGS]; /* Argument offsets */
size_t strr_offlen[SYSTR_MAXARGS]; /* Argument sizes */
+ int32_t strr_flags[SYSTR_MAXARGS];
};
.Ed
-.It Dv STRIOCIO Fa "struct systrace_io"
+.It Dv STRIOCIO Fa "struct systrace_io *"
Copy data in/out of the process being traced.
.Bd -literal
struct systrace_io {
pid_t strio_pid; /* PID of process being traced */
- int strio_ops;
+ int strio_op;
#define SYSTR_READ 1
#define SYSTR_WRITE 2
void *strio_offs;
@@ -222,14 +231,14 @@ struct systrace_io {
size_t strio_len;
};
.Ed
-.It Dv STRIOCPOLICY Fa "struct systrace_policy"
+.It Dv STRIOCPOLICY Fa "struct systrace_policy *"
Manipulate the set of policies.
.Bd -literal
struct systrace_policy {
int strp_op;
-#define SYSTR_POLICY_NEW 1 /* Allocate a new policy */
-#define SYSTR_POLICY_ASSIGN 2 /* Assign policy to process */
-#define SYSTR_POLICY_MODIFY 3 /* Modify an entry */
+#define SYSTR_POLICY_NEW 1 /* Allocate a new policy */
+#define SYSTR_POLICY_ASSIGN 2 /* Assign policy to process */
+#define SYSTR_POLICY_MODIFY 3 /* Modify an entry */
int strp_num;
union {
struct {
@@ -251,10 +260,13 @@ struct systrace_policy {
.Pp
The
.Dv SYSTR_POLICY_NEW
-operation allocates a new policy with all entries initialized to
+operation allocates a new policy of
+.Va strp_maxents
+entries with each initialized to
.Dv SYSTR_POLICY_ASK ,
and returns the new policy number into
.Va strp_num .
+.Pp
The
.Dv SYSTR_POLICY_ASSIGN
operation attaches the policy identified by
@@ -264,13 +276,14 @@ to
with a maximum of
.Va strp_maxents
entries.
+.Pp
The
.Dv SYSTR_POLICY_MODIFY
operation changes the entry indexed by
.Va strp_code
to
.Va strp_policy .
-.It Dv STRIOCGETCWD Fa "pid_t"
+.It Dv STRIOCGETCWD Fa "pid_t *"
Set the working directory of the current process to that of the
named process.
.It Dv STRIOCRESCWD
@@ -289,13 +302,146 @@ struct systrace_inject {
pid_t stri_pid;
};
.Ed
+.It Dv STRIOCSCRIPTNAME Fa "struct systrace_scriptname *"
+Set the path of executed scripts to
+.Va sn_scriptname .
+.Bd -literal
+struct systrace_scriptname {
+ pid_t sn_pid;
+ char sn_scriptname[MAXPATHLEN];
+};
+.Ed
.El
.Sh FILES
.Bl -tag -width "/dev/systrace" -compact
.It Pa /dev/systrace
system call tracing facility
.El
+.Sh EXAMPLES
+The following is an example program that traces another process,
+printing out the path to any
+.Xr open 2
+system calls it performs.
+.Bd -literal
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <dev/systrace.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/*
+ * Number of system calls that will be covered in our policy.
+ */
+#define NSYSCALLS 512
+
+int
+main(int argc, char *argv[])
+{
+ struct systrace_policy strpol;
+ struct systrace_answer strans;
+ struct systrace_io strio;
+ struct str_message strmsg;
+ int fd, cfd, pid, i;
+ ssize_t n;
+ void *p;
+ char c;
+
+ if ((fd = open("/dev/systrace", O_RDONLY)) == -1)
+ err(1, "/dev/systrace");
+
+ /*
+ * Get a systrace descriptor.
+ */
+ if (ioctl(fd, STRIOCCLONE, &cfd) == -1)
+ err(1, "STRIOCCLONE");
+ close(fd);
+
+ /* Gather the PID of a process to systrace from somewhere. */
+ /* ... */
+
+ if (ioctl(cfd, STRIOCATTACH, &pid) == -1)
+ err(1, "STRIOCATTACH");
+
+ /* Install one policy. */
+ strpol.strp_op = SYSTR_POLICY_NEW;
+ strpol.strp_maxents = NSYSCALLS;
+
+ if (ioctl(cfd, STRIOCPOLICY, &strpol) == -1)
+ err(1, "STRIOCPOLICY NEW");
+
+ strpol.strp_op = SYSTR_POLICY_ASSIGN;
+ strpol.strp_pid = pid;
+
+ if (ioctl(cfd, STRIOCPOLICY, &strpol) == -1)
+ err(1, "STRIOCPOLICY ASSIGN");
+
+ /* Permit all system calls. */
+ for (i = 0; i < NSYSCALLS; i++) {
+ strpol.strp_op = SYSTR_POLICY_MODIFY;
+ strpol.strp_code = i;
+ strpol.strp_policy = SYSTR_POLICY_PERMIT;
+
+ if (ioctl(cfd, STRIOCPOLICY, &strpol) == -1)
+ err(1, "STRIOCPOLICY MODIFY");
+ }
+
+ /* Ask us about open(2) system calls. */
+ strpol.strp_op = SYSTR_POLICY_MODIFY;
+ strpol.strp_code = 5; /* open(2) */
+ strpol.strp_policy = SYSTR_POLICY_ASK;
+
+ if (ioctl(cfd, STRIOCPOLICY, &strpol) == -1)
+ err(1, "STRIOCPOLICY MODIFY");
+
+ /*
+ * Now this process just answers requests for the operations the
+ * traced process performs that we have requested systrace to ask
+ * us about.
+ */
+ while ((n = read(cfd, &strmsg, sizeof(strmsg))) ==
+ sizeof(strmsg)) {
+ switch (strmsg.msg_type) {
+ case SYSTR_MSG_ASK:
+ /* Print out the path argument to open(2). */
+ memcpy(&p, &strmsg.msg_data.msg_ask.args,
+ sizeof(p));
+ printf("open(");
+ do {
+ memset(&strio, 0, sizeof(strio));
+ strio.strio_pid = strmsg.msg_pid;
+ strio.strio_op = SYSTR_READ;
+ strio.strio_offs = p;
+ strio.strio_addr = &c;
+ strio.strio_len = 1;
+
+ if (ioctl(cfd, STRIOCIO, &strio) == -1)
+ err(1, "STRIOCIO");
+ putchar(c);
+ (unsigned char *)p += sizeof(char);
+ } while (c != '\e0');
+ printf(")\en");
+
+ memset(&strans, 0, sizeof(strans));
+ strans.stra_pid = strmsg.msg_pid;
+ strans.stra_seqnr = strmsg.msg_seqnr;
+ strans.stra_policy = SYSTR_POLICY_PERMIT;
+
+ if (ioctl(cfd, STRIOCANSWER, &strans) == -1)
+ err(1, "STRIOCANSWER");
+ break;
+ }
+ }
+ if (n == -1)
+ err(1, "read");
+ close(cfd);
+ exit(0);
+}
+.Ed
.Sh SEE ALSO
+.Xr systrace 1 ,
.Xr ioctl 2 ,
.Xr read 2 ,
.Xr options 4 ,
@@ -306,4 +452,8 @@ The
facility first appeared in
.Ox 3.2 .
.\" .Sh BUGS
-.\" .Sh CAVEATS
+.Sh CAVEATS
+When creating new policies, if
+.Va strp_maxents
+is not large enough to accommodate any system calls needed for
+fundamental process operations, the traced process will block forever.