diff options
author | Niels Provos <provos@cvs.openbsd.org> | 2002-08-07 21:27:16 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 2002-08-07 21:27:16 +0000 |
commit | 1c3b4444c373ba1a8b49b0b2460b04e0328d6fd4 (patch) | |
tree | 276b19c7472cd9c7d3f747c1e1870bd1dff9c180 | |
parent | 2290c8730c2239e466cfdda2a75bf13c8855a42f (diff) |
deal better with interrupted system calls
-rw-r--r-- | bin/systrace/intercept.c | 32 | ||||
-rw-r--r-- | bin/systrace/openbsd-syscalls.c | 12 |
2 files changed, 35 insertions, 9 deletions
diff --git a/bin/systrace/intercept.c b/bin/systrace/intercept.c index d3678f76148..22b58142b09 100644 --- a/bin/systrace/intercept.c +++ b/bin/systrace/intercept.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intercept.c,v 1.26 2002/08/05 19:10:22 jason Exp $ */ +/* $OpenBSD: intercept.c,v 1.27 2002/08/07 21:27:15 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -109,6 +109,7 @@ SPLAY_PROTOTYPE(pidtree, intercept_pid, next, pidcompare); SPLAY_GENERATE(pidtree, intercept_pid, next, pidcompare); extern struct intercept_system intercept; +int ic_abort; int intercept_init(void) @@ -493,6 +494,9 @@ intercept_get_string(int fd, pid_t pid, void *addr) do { if (intercept.io(fd, pid, INTERCEPT_READ, (char *)addr + off, &name[off], stride) == -1) { + /* Did the current system call get interrupted? */ + if (errno == EBUSY) + return (NULL); if (errno != EINVAL || stride == 4) { warn("%s: ioctl", __func__); return (NULL); @@ -526,11 +530,14 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp) name = intercept_get_string(fd, pid, addr); if (name == NULL) - err(1, "%s: getstring", __func__); + goto abort; if (intercept.getcwd(fd, pid, cwd, sizeof(cwd)) == NULL) - if (name[0] != '/') + if (name[0] != '/') { + if (errno == EBUSY) + goto abort; err(1, "%s: getcwd", __func__); + } if (name[0] != '/') { if (strlcat(cwd, "/", sizeof(cwd)) >= sizeof(cwd)) @@ -614,6 +621,10 @@ intercept_filename(int fd, pid_t pid, void *addr, int userp) return (name); + abort: + ic_abort = 1; + return (NULL); + error: errx(1, "%s: filename too long", __func__); } @@ -633,6 +644,7 @@ intercept_syscall(int fd, pid_t pid, u_int16_t seqnr, int policynr, if (!strcmp(name, "execve")) { struct intercept_pid *icpid; void *addr; + char *argname; if ((icpid = intercept_getpid(pid)) == NULL) err(1, "intercept_getpid"); @@ -644,7 +656,11 @@ intercept_syscall(int fd, pid_t pid, u_int16_t seqnr, int policynr, free(icpid->newname); intercept.getarg(0, args, argsize, &addr); - icpid->newname = strdup(intercept_filename(fd, pid, addr, 0)); + argname = intercept_filename(fd, pid, addr, 0); + if (argname == NULL) + err(1, "%s:%d: intercept_filename", + __func__, __LINE__); + icpid->newname = strdup(argname); if (icpid->newname == NULL) err(1, "%s:%d: strdup", __func__, __LINE__); @@ -658,14 +674,18 @@ intercept_syscall(int fd, pid_t pid, u_int16_t seqnr, int policynr, if (sc != NULL) { struct intercept_translate *tl; + ic_abort = 0; TAILQ_FOREACH(tl, &sc->tls, next) { if (intercept_translate(tl, fd, pid, tl->off, args, argsize) == -1) break; } - action = (*sc->cb)(fd, pid, policynr, name, code, emulation, - args, argsize, &sc->tls, sc->cb_arg); + if (!ic_abort) + action = (*sc->cb)(fd, pid, policynr, name, code, + emulation, args, argsize, &sc->tls, sc->cb_arg); + else + action = ICPOLICY_NEVER; } else if (intercept_gencb != NULL) action = (*intercept_gencb)(fd, pid, policynr, name, code, emulation, args, argsize, intercept_gencbarg); diff --git a/bin/systrace/openbsd-syscalls.c b/bin/systrace/openbsd-syscalls.c index 71fd31a98e2..4251625180f 100644 --- a/bin/systrace/openbsd-syscalls.c +++ b/bin/systrace/openbsd-syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openbsd-syscalls.c,v 1.10 2002/07/30 09:16:19 itojun Exp $ */ +/* $OpenBSD: openbsd-syscalls.c,v 1.11 2002/08/07 21:27:15 provos Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -80,6 +80,7 @@ #include <fcntl.h> #include <unistd.h> #include <string.h> +#include <errno.h> #include <err.h> #include "intercept.h" @@ -447,8 +448,9 @@ obsd_replace(int fd, pid_t pid, struct intercept_replace *repl) } ret = ioctl(fd, STRIOCREPLACE, &replace); - if (ret == -1) + if (ret == -1 && errno != EBUSY) { warn("%s: ioctl", __func__); + } free(replace.strr_base); @@ -459,6 +461,7 @@ static int obsd_io(int fd, pid_t pid, int op, void *addr, u_char *buf, size_t size) { struct systrace_io io; + extern int ic_abort; memset(&io, 0, sizeof(io)); io.strio_pid = pid; @@ -466,8 +469,11 @@ obsd_io(int fd, pid_t pid, int op, void *addr, u_char *buf, size_t size) io.strio_len = size; io.strio_offs = addr; io.strio_op = (op == INTERCEPT_READ ? SYSTR_READ : SYSTR_WRITE); - if (ioctl(fd, STRIOCIO, &io) == -1) + if (ioctl(fd, STRIOCIO, &io) == -1) { + if (errno == EBUSY) + ic_abort = 1; return (-1); + } return (0); } |