aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Rees <maxcrees@me.com> 2021-01-03 02:57:12 -0500
committerMax Rees <maxcrees@me.com> 2021-01-03 02:57:12 -0500
commit174b5a4bdb9a35e6de9f52f2a073e5c2a66a126b (patch)
treee4147b06030332d6c7419f6cae6ef70feed81b02
parente59452cce378ce341946401e89e95dac091667b5 (diff)
Abstract away some seccomp details from the view of the handlers
-rw-r--r--src/comproot.h16
-rw-r--r--src/handlers/handle_chown.c49
-rw-r--r--src/handlers/handle_stat.c26
-rw-r--r--src/util.c18
-rw-r--r--src/util.h6
5 files changed, 61 insertions, 54 deletions
diff --git a/src/comproot.h b/src/comproot.h
index 3265090..73e5e5d 100644
--- a/src/comproot.h
+++ b/src/comproot.h
@@ -36,7 +36,19 @@ extern struct comproot comproot;
#define PDBG(pid, fmt, ...) _LOGFN_W(comproot.verbose > 1, warn, "[%jd] "fmt, (intmax_t)pid, ##__VA_ARGS__)
#define PDBGX(pid, fmt, ...) _LOGFN_W(comproot.verbose > 1, warnx, "[%jd] "fmt, (intmax_t)pid, ##__VA_ARGS__)
-#define HANDLER_ARGS int notifyfd, struct seccomp_notif *req, struct seccomp_notif_resp *resp
-#define PASS_HANDLER_ARGS notifyfd, req, resp
+#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
typedef void (*handler_func)(HANDLER_ARGS);
#define DECL_HANDLER(syscall_name) void handle_##syscall_name(HANDLER_ARGS)
+
+#define HANDLER_ID HANDLER_REQ->id
+#define HANDLER_PID HANDLER_REQ->pid
+#define HANDLER_ARG(i) HANDLER_REQ->data.args[i]
+#define HANDLER_END \
+ do { \
+ HANDLER_RESP->val = rc; \
+ HANDLER_RESP->error = rc ? -errno : 0; \
+ } while(0)
diff --git a/src/handlers/handle_chown.c b/src/handlers/handle_chown.c
index 0621e54..9165790 100644
--- a/src/handlers/handle_chown.c
+++ b/src/handlers/handle_chown.c
@@ -32,25 +32,24 @@ static int record_chown(char *pathname, uid_t owner, gid_t group, int follow) {
static void handle_chown_inner(char *syscall_name, HANDLER_ARGS, int follow) {
char pathname[PATH_MAX] = {0};
- uid_t owner = req->data.args[1];
- gid_t group = req->data.args[2];
+ uid_t owner = HANDLER_ARG(1);
+ gid_t group = HANDLER_ARG(2);
int rc = -1;
- if (pull_pathname(notifyfd, req, 0, pathname) == -1)
+ if (pull_pathname(HANDLER_FD, HANDLER_REQ, 0, pathname) == -1)
goto out;
- PDBGX(req->pid, "%s(\"%s\", %d, %d)", syscall_name, pathname, owner, group);
+ PDBGX(HANDLER_PID, "%s(\"%s\", %d, %d)", syscall_name, pathname, owner, group);
if (pathname[0] != '/') {
char procpath[PATH_MAX];
- if (chdir_to_fd(req->pid, AT_FDCWD, procpath))
+ if (chdir_to_fd(HANDLER_PID, AT_FDCWD, procpath))
goto out;
}
rc = record_chown(pathname, owner, group, follow);
out:
- resp->val = rc;
- resp->error = rc ? -errno : 0;
+ HANDLER_END;
}
DECL_HANDLER(chown) {
@@ -62,51 +61,50 @@ DECL_HANDLER(lchown) {
}
DECL_HANDLER(fchown) {
- int fd = req->data.args[0];
- uid_t owner = req->data.args[1];
- gid_t group = req->data.args[2];
+ int fd = HANDLER_ARG(0);
+ uid_t owner = HANDLER_ARG(1);
+ gid_t group = HANDLER_ARG(2);
- (void)notifyfd; /* unused */
+ (void)HANDLER_FD; /* unused */
int rc = -1;
char procpath[PATH_MAX];
- PDBGX(req->pid, "fchown(%d, %d, %d)", fd, owner, group);
+ PDBGX(HANDLER_PID, "fchown(%d, %d, %d)", fd, owner, group);
- if (get_fd_path(req->pid, fd, procpath) == -1)
+ if (get_fd_path(HANDLER_PID, fd, procpath) == -1)
goto out;
rc = record_chown(procpath, owner, group, 0);
out:
- resp->val = rc;
- resp->error = rc ? -errno : 0;
+ HANDLER_END;
}
DECL_HANDLER(fchownat) {
- int fd = req->data.args[0];
+ int fd = HANDLER_ARG(0);
char pathname[PATH_MAX] = {0}; int pathname_l = -1;
- uid_t owner = req->data.args[2];
- gid_t group = req->data.args[3];
- int flags = req->data.args[4];
+ uid_t owner = HANDLER_ARG(2);
+ gid_t group = HANDLER_ARG(3);
+ int flags = HANDLER_ARG(4);
int rc = -1;
- pathname_l = pull_pathname(notifyfd, req, 1, pathname);
+ pathname_l = pull_pathname(HANDLER_FD, HANDLER_REQ, 1, pathname);
if (pathname_l == -1)
goto out;
if (fd == AT_FDCWD)
- PDBGX(req->pid, "fchownat(AT_FDCWD, \"%s\", %d, %d, %d)", pathname, owner, group, flags);
+ PDBGX(HANDLER_PID, "fchownat(AT_FDCWD, \"%s\", %d, %d, %d)", pathname, owner, group, flags);
else
- PDBGX(req->pid, "fchownat(%d, \"%s\", %d, %d, %d)", fd, pathname, owner, group, flags);
+ PDBGX(HANDLER_PID, "fchownat(%d, \"%s\", %d, %d, %d)", fd, pathname, owner, group, flags);
if ((flags & (AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW)) == (AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW)) {
- PWARNX(req->pid, "not implemented: AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW");
+ PWARNX(HANDLER_PID, "not implemented: AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW");
errno = ENOSYS;
goto out;
}
char procpath[PATH_MAX] = {0};
- if (chdir_to_fd(req->pid, fd, procpath))
+ if (chdir_to_fd(HANDLER_PID, fd, procpath))
goto out;
char *fullpath = 0;
@@ -117,6 +115,5 @@ DECL_HANDLER(fchownat) {
rc = record_chown(fullpath, owner, group, !(flags & AT_SYMLINK_NOFOLLOW));
out:
- resp->val = rc;
- resp->error = rc ? -errno : 0;
+ HANDLER_END;
}
diff --git a/src/handlers/handle_stat.c b/src/handlers/handle_stat.c
index 8d2cc18..6c58f0e 100644
--- a/src/handlers/handle_stat.c
+++ b/src/handlers/handle_stat.c
@@ -17,29 +17,28 @@ static void handle_stat_inner(char *syscall_name, HANDLER_ARGS, int follow) {
int rc = -1;
- if (pull_pathname(notifyfd, req, 0, pathname) == -1)
+ if (pull_pathname(HANDLER_FD, HANDLER_REQ, 0, pathname) == -1)
goto out;
if (pathname[0] != '/') {
char procpath[PATH_MAX];
- if (chdir_to_fd(req->pid, AT_FDCWD, procpath))
+ if (chdir_to_fd(HANDLER_PID, AT_FDCWD, procpath))
goto out;
}
if (stat_upsert_path(&statbuf, pathname, follow) == -1)
goto out;
- PDBGX(req->pid, "%s(\"%s\", "STAT_FMT")", syscall_name, pathname, STAT_ARG(statbuf));
+ PDBGX(HANDLER_PID, "%s(\"%s\", "STAT_FMT")", syscall_name, pathname, STAT_ARG(statbuf));
struct iovec liov[] = {{&statbuf, sizeof(statbuf)}};
- struct iovec riov[] = {{(void *)req->data.args[1], sizeof(statbuf)}};
- if (tx_data(notifyfd, req, liov, 1, riov, 1, 1) == -1)
+ struct iovec riov[] = {{(void *)HANDLER_ARG(1), sizeof(statbuf)}};
+ if (tx_data(HANDLER_FD, HANDLER_REQ, liov, 1, riov, 1, 1) == -1)
goto out;
rc = 0;
out:
- resp->val = rc;
- resp->error = rc ? -errno : 0;
+ HANDLER_END;
}
DECL_HANDLER(stat) {
@@ -51,23 +50,22 @@ DECL_HANDLER(lstat) {
}
DECL_HANDLER(fstat) {
- int fd = req->data.args[0];
+ int fd = HANDLER_ARG(0);
struct stat statbuf;
int rc = -1;
- if (stat_upsert_fd(&statbuf, req->pid, fd) == -1)
+ if (stat_upsert_fd(&statbuf, HANDLER_PID, fd) == -1)
goto out;
- PDBGX(req->pid, "fstat(%d, "STAT_FMT")", fd, STAT_ARG(statbuf));
+ PDBGX(HANDLER_PID, "fstat(%d, "STAT_FMT")", fd, STAT_ARG(statbuf));
struct iovec liov[] = {{&statbuf, sizeof(statbuf)}};
- struct iovec riov[] = {{(void *)req->data.args[1], sizeof(statbuf)}};
- if (tx_data(notifyfd, req, liov, 1, riov, 1, 1) == -1)
+ struct iovec riov[] = {{(void *)HANDLER_ARG(1), sizeof(statbuf)}};
+ if (tx_data(HANDLER_FD, HANDLER_REQ, liov, 1, riov, 1, 1) == -1)
goto out;
rc = 0;
out:
- resp->val = rc;
- resp->error = rc ? -errno : 0;
+ HANDLER_END;
}
diff --git a/src/util.c b/src/util.c
index e658694..97e88b7 100644
--- a/src/util.c
+++ b/src/util.c
@@ -36,22 +36,22 @@ int chdir_to_fd(pid_t pid, int fd, char *procpath) {
return 0;
}
-int tx_data(int notifyfd, struct seccomp_notif *req, PROC_VM_BUFS, int push) {
+int tx_data(A_HANDLER_FD, A_HANDLER_REQ, A_PROC_VM_BUFS, int push) {
int rc = -1;
- ssize_t (*func)(pid_t pid, PROC_VM_BUFS, unsigned long flags) = 0;
+ 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(req->pid, liov, nl, riov, nr, 0)) == -1) {
- PWARN(req->pid, "tx_data");
+ 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(notifyfd, req->id)) {
- PWARNX(req->pid, "died during trace!");
+ if (seccomp_notify_id_valid(HANDLER_FD, HANDLER_ID)) {
+ PWARNX(HANDLER_PID, "died during trace!");
rc = -1;
errno = EIO;
goto out;
@@ -72,12 +72,12 @@ int check_pathname(char pathname[PATH_MAX]) {
return rc;
}
-int pull_pathname(int notifyfd, struct seccomp_notif *req, int argno, char pathname[PATH_MAX]) {
+int pull_pathname(A_HANDLER_FD, A_HANDLER_REQ, int argno, char pathname[PATH_MAX]) {
int rc = -1;
struct iovec liov[] = {{pathname, PATH_MAX+1}};
- struct iovec riov[] = {{(void *)req->data.args[argno], PATH_MAX+1}};
+ struct iovec riov[] = {{(void *)HANDLER_ARG(argno), PATH_MAX+1}};
- if ((rc = tx_data(notifyfd, req, liov, 1, riov, 1, 0)) == -1)
+ if ((rc = tx_data(HANDLER_FD, HANDLER_REQ, liov, 1, riov, 1, 0)) == -1)
goto out;
rc = check_pathname(pathname);
diff --git a/src/util.h b/src/util.h
index 5af00b7..70e1633 100644
--- a/src/util.h
+++ b/src/util.h
@@ -9,9 +9,9 @@
int get_fd_path(pid_t pid, int fd, char *procpath);
int chdir_to_fd(pid_t pid, int fd, char *procpath);
-#define PROC_VM_BUFS const struct iovec liov[], unsigned long nl, const struct iovec riov[], unsigned long nr
-int tx_data(int notifyfd, struct seccomp_notif *req, PROC_VM_BUFS, int push);
+#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 check_pathname(char pathname[PATH_MAX]);
-int pull_pathname(int notifyfd, struct seccomp_notif *req, int argno, char pathname[PATH_MAX]);
+int pull_pathname(A_HANDLER_FD, A_HANDLER_REQ, int argno, char pathname[PATH_MAX]);
void set_cloexec(int fd);