Skip to content

Commit

Permalink
runtime/track_memory_map: distinguish between seccomp and ptrace modes
Browse files Browse the repository at this point in the history
in ptrace mode we run the child to the next syscall entry/exit, while in seccomp mode we run until our seccomp policy causes a stop

this means we should never see extraneous stops in seccomp mode; we now check this
  • Loading branch information
fw-immunant committed Oct 18, 2023
1 parent 71b6b8c commit 0276fb7
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 9 deletions.
2 changes: 1 addition & 1 deletion runtime/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ int main(int argc, char **argv) {

int exit_status = 0;
struct memory_map *map = memory_map_new();
bool success = track_memory_map(pid, map, &exit_status);
bool success = track_memory_map(pid, map, &exit_status, TRACE_MODE_SECCOMP);
ptrace(PTRACE_KILL, pid, 0, 0);
memory_map_destroy(map);

Expand Down
20 changes: 14 additions & 6 deletions runtime/track_memory_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "get_inferior_pkru.h"
#include "memory_map.h"
#include "mmap_event.h"
#include "track_memory_map.h"

#ifdef DEBUG
#define debug(...) fprintf(stderr, __VA_ARGS__)
Expand Down Expand Up @@ -186,9 +187,11 @@ unsigned char pkey_for_pkru(uint32_t pkru) {
/* query pid to determine the mmap-relevant event being requested. returns true
* unless something horrible happens */
bool interpret_syscall(struct user_regs_struct *regs, unsigned char pkey,
enum mmap_event *event, union event_info *event_info) {
enum mmap_event *event, union event_info *event_info,
enum trace_mode mode) {
/* determine event from syscall # */
*event = event_from_syscall(regs->orig_rax);
unsigned long long syscall = regs->orig_rax;
*event = event_from_syscall(syscall);

debug_op("event: %s\n", event_names[*event]);

Expand Down Expand Up @@ -267,6 +270,10 @@ bool interpret_syscall(struct user_regs_struct *regs, unsigned char pkey,
case EVENT_NONE: {
/* when ptracing alone, this may occur; when we are a seccomp helper, this
should not happen */
if (mode == TRACE_MODE_SECCOMP) {
fprintf(stderr, "seccomp tracer stopped on unexpected syscall (%llu)\n", syscall);
return false;
}
break;
}
}
Expand Down Expand Up @@ -364,10 +371,11 @@ void return_syscall_eperm(pid_t pid) {
returns true if the inferior exits, false on trace error.
if true is returned, the inferior's exit status will be stored to *exit_status_out if not NULL. */
bool track_memory_map(pid_t pid, struct memory_map *map, int *exit_status_out) {
bool track_memory_map(pid_t pid, struct memory_map *map, int *exit_status_out, enum trace_mode mode) {
enum __ptrace_request continue_request = mode == TRACE_MODE_PTRACE_SYSCALL ? PTRACE_SYSCALL : PTRACE_CONT;
while (true) {
/* run until the next syscall entry */
if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
/* run until the next syscall entry or traced syscall (depending on mode) */
if (ptrace(continue_request, pid, 0, 0) < 0) {
perror("could not PTRACE_SYSCALL...");
}
/* wait for the process to get signalled */
Expand Down Expand Up @@ -408,7 +416,7 @@ bool track_memory_map(pid_t pid, struct memory_map *map, int *exit_status_out) {

union event_info event_info = {0};
enum mmap_event event = EVENT_NONE;
if (!interpret_syscall(&regs, pkey, &event, &event_info)) {
if (!interpret_syscall(&regs, pkey, &event, &event_info, mode)) {
fprintf(stderr, "could not interpret syscall!\n");
}

Expand Down
10 changes: 9 additions & 1 deletion runtime/track_memory_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@

#include "memory_map.h"

bool track_memory_map(pid_t pid, struct memory_map *map, int *exit_status_out);
enum trace_mode {
/* run the program with PTRACE_CONT and only expect interruptions at traced
syscalls or signal receipt */
TRACE_MODE_SECCOMP,
/* run the program with PTRACE_SYSCALL to step to the next syscall edge */
TRACE_MODE_PTRACE_SYSCALL,
};

bool track_memory_map(pid_t pid, struct memory_map *map, int *exit_status_out, enum trace_mode mode);
2 changes: 1 addition & 1 deletion runtime/track_memory_map_demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ int main(int argc, char **argv) {

int exit_status = 0;
struct memory_map *map = memory_map_new();
bool success = track_memory_map(pid, map, &exit_status);
bool success = track_memory_map(pid, map, &exit_status, TRACE_MODE_PTRACE_SYSCALL);
ptrace(PTRACE_KILL, pid, 0, 0);
memory_map_destroy(map);

Expand Down

0 comments on commit 0276fb7

Please sign in to comment.