aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/comproot.c15
-rw-r--r--src/comproot.h5
-rw-r--r--src/handlers/handle_chown.c4
-rw-r--r--src/handlers/handle_stat.c10
-rw-r--r--src/util.c31
-rw-r--r--src/util.h5
6 files changed, 35 insertions, 35 deletions
diff --git a/src/comproot.c b/src/comproot.c
index ac7d451..1223ff7 100644
--- a/src/comproot.c
+++ b/src/comproot.c
@@ -28,6 +28,8 @@ struct comproot comproot = {
static void new_notification(short revents, int notifyfd) {
struct seccomp_notif *req;
struct seccomp_notif_resp *resp;
+ int rc, procfd = -1;
+ char procpath[PATH_MAX];
if (!(revents & POLLIN))
ERRX(2, "notifyfd has status %d", revents);
@@ -40,10 +42,19 @@ static void new_notification(short revents, int notifyfd) {
resp->id = req->id;
resp->flags = 0;
+ rc = snprintf(procpath, PATH_MAX, "/proc/%jd", (intmax_t)req->pid);
+ if (rc < 0 || rc >= PATH_MAX)
+ ERR(3, "snprintf(\"/proc/%%jd\") = %d", rc);
+ procfd = open(procpath, O_CLOEXEC|O_DIRECTORY|O_PATH);
+ if (seccomp_notify_id_valid(notifyfd, req->id) || procfd == -1) {
+ PWARNX(req->pid, "died during trace!");
+ goto out;
+ }
+
switch(req->data.nr) {
#define X(syscall_name) \
case SCMP_SYS(syscall_name): \
- handle_##syscall_name(notifyfd, req, resp); \
+ handle_##syscall_name(notifyfd, req, resp, procfd); \
break;
#include "handlers/handlers.h"
#undef X
@@ -55,6 +66,8 @@ static void new_notification(short revents, int notifyfd) {
if (seccomp_notify_respond(notifyfd, resp))
ERR(3, "seccomp_notify_respond");
+out:
+ close(procfd);
seccomp_notify_free(req, resp);
}
diff --git a/src/comproot.h b/src/comproot.h
index eca8cae..0bb3a63 100644
--- a/src/comproot.h
+++ b/src/comproot.h
@@ -41,8 +41,9 @@ extern struct comproot comproot;
#define A_HANDLER_FD int HANDLER_FD
#define A_HANDLER_REQ struct seccomp_notif *HANDLER_REQ
#define A_HANDLER_RESP struct seccomp_notif_resp *HANDLER_RESP
-#define HANDLER_ARGS A_HANDLER_FD, A_HANDLER_REQ, A_HANDLER_RESP
-#define PASS_HANDLER_ARGS HANDLER_FD, HANDLER_REQ, HANDLER_RESP
+#define A_HANDLER_PROC int HANDLER_PROC
+#define HANDLER_ARGS A_HANDLER_FD, A_HANDLER_REQ, A_HANDLER_RESP, A_HANDLER_PROC
+#define PASS_HANDLER_ARGS HANDLER_FD, HANDLER_REQ, HANDLER_RESP, HANDLER_PROC
typedef void (*handler_func)(HANDLER_ARGS);
#define DECL_HANDLER(syscall_name) void handle_##syscall_name(HANDLER_ARGS)
diff --git a/src/handlers/handle_chown.c b/src/handlers/handle_chown.c
index 8e05501..8f78ca9 100644
--- a/src/handlers/handle_chown.c
+++ b/src/handlers/handle_chown.c
@@ -37,7 +37,7 @@ static void handle_chown_inner(char *syscall_name, HANDLER_ARGS, int follow) {
int rc = -1;
- if (pull_pathname(HANDLER_FD, HANDLER_REQ, 0, pathname) == -1)
+ if (pull_pathname(HANDLER_PROC, HANDLER_REQ, 0, pathname) == -1)
goto out;
PDBGX(HANDLER_PID, "%s(\"%s\", %d, %d)", syscall_name, pathname, owner, group);
@@ -88,7 +88,7 @@ DECL_HANDLER(fchownat) {
int rc = -1;
- pathname_l = pull_pathname(HANDLER_FD, HANDLER_REQ, 1, pathname);
+ pathname_l = pull_pathname(HANDLER_PROC, HANDLER_REQ, 1, pathname);
if (pathname_l == -1)
goto out;
diff --git a/src/handlers/handle_stat.c b/src/handlers/handle_stat.c
index 84ab63b..f7ff466 100644
--- a/src/handlers/handle_stat.c
+++ b/src/handlers/handle_stat.c
@@ -17,7 +17,7 @@ static void handle_stat_inner(char *syscall_name, HANDLER_ARGS, int follow) {
int rc = -1;
- if (pull_pathname(HANDLER_FD, HANDLER_REQ, 0, pathname) == -1)
+ if (pull_pathname(HANDLER_PROC, HANDLER_REQ, 0, pathname) == -1)
goto out;
if (pathname[0] != '/') {
@@ -31,9 +31,7 @@ static void handle_stat_inner(char *syscall_name, HANDLER_ARGS, int follow) {
PDBGX(HANDLER_PID, "%s(\"%s\", "STAT_FMT")", syscall_name, pathname, STAT_ARG(statbuf));
- struct iovec liov[] = {{&statbuf, sizeof(statbuf)}};
- struct iovec riov[] = {{(void *)HANDLER_ARG(1), sizeof(statbuf)}};
- if (tx_data(HANDLER_FD, HANDLER_REQ, liov, 1, riov, 1, 1) == -1)
+ if (tx_data(HANDLER_PROC, &statbuf, HANDLER_ARG(1), sizeof(statbuf), 1) == -1)
goto out;
rc = 0;
@@ -60,9 +58,7 @@ DECL_HANDLER(fstat) {
PDBGX(HANDLER_PID, "fstat(%d, "STAT_FMT")", fd, STAT_ARG(statbuf));
- struct iovec liov[] = {{&statbuf, sizeof(statbuf)}};
- struct iovec riov[] = {{(void *)HANDLER_ARG(1), sizeof(statbuf)}};
- if (tx_data(HANDLER_FD, HANDLER_REQ, liov, 1, riov, 1, 1) == -1)
+ if (tx_data(HANDLER_PROC, &statbuf, HANDLER_ARG(1), sizeof(statbuf), 1) == -1)
goto out;
rc = 0;
diff --git a/src/util.c b/src/util.c
index 982ef25..d16bb92 100644
--- a/src/util.c
+++ b/src/util.c
@@ -36,27 +36,20 @@ int chdir_to_fd(pid_t pid, int fd, char procpath[PATH_MAX]) {
return 0;
}
-int tx_data(A_HANDLER_FD, A_HANDLER_REQ, A_PROC_VM_BUFS, int push) {
+int tx_data(A_HANDLER_PROC, void *buf, uint64_t addr, size_t len, int push) {
int rc = -1;
- ssize_t (*func)(pid_t pid, A_PROC_VM_BUFS, unsigned long flags) = 0;
-
- if (push)
- func = process_vm_writev;
- else
- func = process_vm_readv;
-
- if ((rc = func(HANDLER_PID, liov, nl, riov, nr, 0)) == -1) {
- PWARN(HANDLER_PID, "tx_data");
- errno = EIO;
- goto out;
- }
- if (seccomp_notify_id_valid(HANDLER_FD, HANDLER_ID)) {
- PWARNX(HANDLER_PID, "died during trace!");
- rc = -1;
+ int procfd = openat(HANDLER_PROC, "mem", O_RDWR|O_CLOEXEC);
+ if (procfd == -1) {
+ WARNX("process died during trace!");
errno = EIO;
goto out;
}
+ if (push)
+ rc = pwrite(procfd, buf, len, addr);
+ else
+ rc = pread(procfd, buf, len, addr);
+ close(procfd);
out:
return rc;
}
@@ -72,12 +65,10 @@ int check_pathname(char pathname[PATH_MAX]) {
return rc;
}
-int pull_pathname(A_HANDLER_FD, A_HANDLER_REQ, int argno, char pathname[PATH_MAX]) {
+int pull_pathname(A_HANDLER_PROC, A_HANDLER_REQ, int argno, char pathname[PATH_MAX]) {
int rc = -1;
- struct iovec liov[] = {{pathname, PATH_MAX+1}};
- struct iovec riov[] = {{(void *)HANDLER_ARG(argno), PATH_MAX+1}};
- if ((rc = tx_data(HANDLER_FD, HANDLER_REQ, liov, 1, riov, 1, 0)) == -1)
+ if ((rc = tx_data(HANDLER_PROC, pathname, HANDLER_ARG(argno), PATH_MAX+1, 0)) == -1)
goto out;
rc = check_pathname(pathname);
diff --git a/src/util.h b/src/util.h
index 5a512f3..651c803 100644
--- a/src/util.h
+++ b/src/util.h
@@ -9,9 +9,8 @@
int get_fd_path(pid_t pid, int fd, char procpath[PATH_MAX]);
int chdir_to_fd(pid_t pid, int fd, char procpath[PATH_MAX]);
-#define A_PROC_VM_BUFS const struct iovec liov[], unsigned long nl, const struct iovec riov[], unsigned long nr
-int tx_data(A_HANDLER_FD, A_HANDLER_REQ, A_PROC_VM_BUFS, int push);
+int tx_data(A_HANDLER_PROC, void *buf, uint64_t addr, size_t len, int push);
int check_pathname(char pathname[PATH_MAX]);
-int pull_pathname(A_HANDLER_FD, A_HANDLER_REQ, int argno, char pathname[PATH_MAX]);
+int pull_pathname(A_HANDLER_PROC, A_HANDLER_REQ, int argno, char pathname[PATH_MAX]);
void set_cloexec(int fd);