Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ steps:

- label: "quark-test on rhel 8.5 (no file)"
key: test_rhel_8_5
command: "./.buildkite/runtest_distro.sh rhel 8.5 -x t_file_bypass -x t_file"
command: "./.buildkite/runtest_distro.sh rhel 8.5 -x t_file_bypass -x t_file -x t_memfd -x t_shm_open"
depends_on:
- make_docker
agents:
Expand All @@ -266,7 +266,7 @@ steps:

- label: "quark-test on rhel 8.6 (no file)"
key: test_rhel_8_6
command: "./.buildkite/runtest_distro.sh rhel 8.6 -x t_file_bypass -x t_file"
command: "./.buildkite/runtest_distro.sh rhel 8.6 -x t_file_bypass -x t_file -x t_memfd -x t_shm_open"
depends_on:
- make_docker
agents:
Expand All @@ -277,7 +277,7 @@ steps:

- label: "quark-test on rhel 8.7 (no file)"
key: test_rhel_8_7
command: "./.buildkite/runtest_distro.sh rhel 8.7 -x t_file_bypass -x t_file"
command: "./.buildkite/runtest_distro.sh rhel 8.7 -x t_file_bypass -x t_file -x t_memfd -x t_shm_open"
depends_on:
- make_docker
agents:
Expand Down Expand Up @@ -352,9 +352,9 @@ steps:
machineType: n2-standard-2
enableNestedVirtualization: true

- label: "quark-test on rhel 9.3"
- label: "quark-test on rhel 9.3 (memfd+shmget broken)"
key: test_rhel_9_3
command: "./.buildkite/runtest_distro.sh rhel 9.3"
command: "./.buildkite/runtest_distro.sh rhel 9.3 -x t_memfd -x t_shmget"
depends_on:
- make_docker
agents:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ endef

CFLAGS?= -g -O2 -fno-strict-aliasing -fPIC
ifdef CENTOS7
CFLAGS+= -std=gnu99 -DNO_PUSH_PRAGMA
CFLAGS+= -std=gnu99 -DNO_PUSH_PRAGMA -DNO_MEMFD -DNO_SHM_OPEN
endif

CPPFLAGS+= -D_GNU_SOURCE
Expand Down
200 changes: 191 additions & 9 deletions bpf_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,6 @@ ebpf_events_to_raw(struct ebpf_event_header *ev)
}
break;
}
case EBPF_EVENT_FILE_SHMEM_OPEN:
goto drop;
break;
case EBPF_EVENT_FILE_CREATE: /* FALLTHROUGH */
case EBPF_EVENT_FILE_DELETE: /* FALLTHROUGH */
case EBPF_EVENT_FILE_MODIFY: /* FALLTHROUGH */
Expand Down Expand Up @@ -432,7 +429,7 @@ ebpf_events_to_raw(struct ebpf_event_header *ev)
old_path = field->data;
old_path_len = tmp_len + 1; /* with NUL */
}
continue;
break;
case EBPF_VL_FIELD_PIDS_SS_CGROUP_PATH: /* ignored */
break;
default:
Expand Down Expand Up @@ -490,14 +487,194 @@ ebpf_events_to_raw(struct ebpf_event_header *ev)

break;
}
case EBPF_EVENT_PROCESS_PTRACE: {
struct ebpf_process_ptrace_event *ptrace;
struct quark_ptrace *qptrace;

ptrace = (struct ebpf_process_ptrace_event *)ev;
if ((raw = raw_event_alloc(RAW_PTRACE)) == NULL)
goto bad;

raw->pid = ptrace->pids.tgid;
raw->time = ev->ts;

qptrace = &raw->ptrace.quark_ptrace;
qptrace->child_pid = ptrace->child_pid;
qptrace->request = ptrace->request;
qptrace->addr = ptrace->addr;
qptrace->data = ptrace->data;

break;
}
case EBPF_EVENT_PROCESS_LOAD_MODULE: {
struct ebpf_process_load_module_event *module;
struct quark_module_load *qml;
char *filename, *version, *src_version;

module = (struct ebpf_process_load_module_event *)ev;
if ((raw = raw_event_alloc(RAW_MODULE_LOAD)) == NULL)
goto bad;

raw->pid = module->pids.tgid;
raw->time = ev->ts;

filename = version = src_version = NULL;
FOR_EACH_VARLEN_FIELD(module->vl_fields, field) {
switch (field->type) {
case EBPF_VL_FIELD_FILENAME:
if (field->size > 0)
filename = strndup(field->data, field->size);
break;
case EBPF_VL_FIELD_MOD_VERSION:
if (field->size > 0)
version = strndup(field->data, field->size);
break;
case EBPF_VL_FIELD_MOD_SRCVERSION:
if (field->size > 0)
src_version = strndup(field->data, field->size);
break;
default:
qwarnx("unhandled field type %d", field->type);
free(filename);
free(version);
free(src_version);
goto bad;
}
}

qml = calloc(1, sizeof(*qml));
if (qml == NULL || filename == NULL ||
version == NULL || src_version == NULL) {
free(qml);
free(filename);
free(version);
free(src_version);
qwarn("alloc module load event");
goto bad;
}

qml->name = filename;
qml->version = version;
qml->src_version = src_version;
raw->module_load.quark_module_load = qml;

break;
}
case EBPF_EVENT_PROCESS_SHMGET: {
struct ebpf_process_shmget_event *shm;
struct quark_shm *qshm;

shm = (struct ebpf_process_shmget_event *)ev;
if ((raw = raw_event_alloc(RAW_SHM)) == NULL)
goto bad;

raw->pid = shm->pids.tgid;
raw->time = ev->ts;

if ((qshm = calloc(1, sizeof(*qshm))) == NULL)
goto bad;
qshm->kind = QUARK_SHM_SHMGET;
qshm->shmget_key = shm->key;
qshm->shmget_size = shm->size;
qshm->shmget_shmflg = shm->shmflg;
raw->shm.quark_shm = qshm;

break;
}
case EBPF_EVENT_PROCESS_MEMFD_CREATE: {
struct ebpf_process_memfd_create_event *memfd;
struct quark_shm *qshm;
char *path;

memfd = (struct ebpf_process_memfd_create_event *)ev;
if ((raw = raw_event_alloc(RAW_SHM)) == NULL)
goto bad;

raw->pid = memfd->pids.tgid;
raw->time = ev->ts;

path = NULL;
FOR_EACH_VARLEN_FIELD(memfd->vl_fields, field) {
if (field->type == EBPF_VL_FIELD_FILENAME &&
field->size > 0) {
path = strndup(field->data, field->size);
break;
}
}
if (path == NULL) {
qwarnx("invalid memfd_create event");
goto bad;
}

if ((qshm = calloc(1, sizeof(*qshm))) == NULL) {
free(path);
goto bad;
}
qshm->kind = QUARK_SHM_MEMFD_CREATE;
qshm->memfd_create_flags = memfd->flags;
qshm->path = path;
raw->shm.quark_shm = qshm;

break;
}
case EBPF_EVENT_FILE_SHMEM_OPEN: /* FALLTHROUGH */
case EBPF_EVENT_FILE_MEMFD_OPEN: {
struct ebpf_file_create_event *create;
struct quark_shm *qshm;
char *path;

/*
* Path from MEMFD_OPEN is broken, see:
* https://github.com/elastic/quark/issues/255
*/
if (ev->type == EBPF_EVENT_FILE_MEMFD_OPEN)
goto bad;

create = (struct ebpf_file_create_event *)ev;
if ((raw = raw_event_alloc(RAW_SHM)) == NULL)
goto bad;

raw->pid = create->pids.tgid;
raw->time = ev->ts;

path = NULL;
FOR_EACH_VARLEN_FIELD(create->vl_fields, field) {
if (field->type == EBPF_VL_FIELD_PATH &&
field->size > 0) {
path = strndup(field->data, field->size);
break;
}
}
if (path == NULL) {
qwarnx("invalid {shmem,memfd}_create event");
goto bad;
}

if ((qshm = calloc(1, sizeof(*qshm))) == NULL) {
free(path);
goto bad;
}
if (ev->type == EBPF_EVENT_FILE_SHMEM_OPEN)
qshm->kind = QUARK_SHM_SHM_OPEN;
else if (ev->type == EBPF_EVENT_FILE_MEMFD_OPEN)
qshm->kind = QUARK_SHM_MEMFD_OPEN;
qshm->path = path;
raw->shm.quark_shm = qshm;

break;
}
default:
qwarnx("unhandled type %lu", ev->type);
goto bad;
}

if (unlikely(raw->pid == 0)) {
qwarnx("raw->pid is not set, did you forget me :( ?");
goto bad;
}

return (raw);

drop:
bad:
if (raw != NULL)
raw_event_free(raw);
Expand Down Expand Up @@ -866,12 +1043,9 @@ bpf_queue_open1(struct quark_queue *qq, int use_fentry)
bpf_program__set_autoload(p->progs.recvmsg4, 1);
}

if (qq->flags & QQ_MEMFD) {
if (qq->flags & QQ_SHM) {
bpf_program__set_autoload(p->progs.tracepoint_syscalls_sys_enter_memfd_create, 1);
bpf_program__set_autoload(p->progs.tracepoint_syscalls_sys_enter_shmget, 1);
bpf_program__set_autoload(p->progs.module_load, 1);
bpf_program__set_autoload(p->progs.kprobe__ptrace_attach, 1);
bpf_program__set_autoload(p->progs.kprobe__arch_ptrace, 1);
}

if (qq->flags & QQ_TTY) {
Expand All @@ -881,6 +1055,14 @@ bpf_queue_open1(struct quark_queue *qq, int use_fentry)
bpf_program__set_autoload(p->progs.kprobe__tty_write, 1);
}

if (qq->flags & QQ_PTRACE) {
bpf_program__set_autoload(p->progs.kprobe__arch_ptrace, 1);
bpf_program__set_autoload(p->progs.kprobe__ptrace_attach, 1);
}

if (qq->flags & QQ_MODULE_LOAD)
bpf_program__set_autoload(p->progs.module_load, 1);

/*
* These are probes that are not attached to a feature and not currently
* used in quark, but we need to maintain compatibility in BYPASS.
Expand Down
16 changes: 12 additions & 4 deletions init.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,28 @@ main(int argc, char *argv[])
if (pid == 0) {
if (setenv("PATH", "/bin", 1) != 0)
err(1, "setenv PATH");

if (mount("devtmpfs", "/dev", "devtmpfs", 0, NULL) == -1)
err(1, "mount /dev");

if (mkdir("/dev/shm", 0777) == -1)
err(1, "mkdir /dev/shm");
if (mkdir("/tmp", 0777) == -1)
err(1, "mkdir /tmp");
if (mkdir("/proc", 0666) == -1)
err(1, "mkdir /proc");
if (mkdir("/sys", 0666) == -1)
err(1, "mkdir /sys");

if (mount(NULL, "/tmp", "tmpfs", 0, NULL) == -1)
if (mount("tmpfs", "/dev/shm", "tmpfs", MS_NODEV, NULL) == -1)
err(1, "mount /dev/shm");
if (mount("tmpfs", "/tmp", "tmpfs", 0, NULL) == -1)
err(1, "mount /tmp");
if (mount("proc", "/proc", "proc", 0, NULL) == -1)
err(1, "mount /proc");
if (mount(NULL, "/sys", "sysfs", 0, NULL) == -1)
if (mount("sysfs", "/sys", "sysfs", 0, NULL) == -1)
err(1, "mount /sys");
if (mount(NULL, "/sys/kernel/tracing", "tracefs",
if (mount("tracefs", "/sys/kernel/tracing", "tracefs",
0, NULL) == -1) {
warn("mount /sys/kernel/tracing");
warnx("trying debugfs...");
Expand All @@ -128,7 +136,7 @@ main(int argc, char *argv[])
errx(1, "couldn't mount tracefs or debugfs");
}
}
if (mount(NULL, "/sys/fs/cgroup", "cgroup2", 0, NULL) == -1)
if (mount("cgroup2", "/sys/fs/cgroup", "cgroup2", 0, NULL) == -1)
err(1, "mount /sys/fs/cgroup");

net_up();
Expand Down
8 changes: 7 additions & 1 deletion quark-mon.8
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
.Nd monitor and print quark events
.Sh SYNOPSIS
.Nm quark-mon
.Op Fl BbDEeFkMNSstv
.Op Fl BbDEeFHhkMNSsTtv
.Op Fl C Ar filename
.Op Fl K Ar kubeconfig
.Op Fl l Ar maxlength
Expand Down Expand Up @@ -70,6 +70,8 @@ Enable file events (experimental).
Use minimal aggregation, fork, exec and exit will
.Em not
be aggregated.
.It Fl H
Enable SHMGET events.
.It Fl h
Display this manpage.
.It Fl K Ar kubeconfig
Expand All @@ -79,6 +81,8 @@ is the path to the kubernetes configuration, usually
.Pa $HOME/.kube/config .
.It Fl k
Attempt kprobe as the backend.
.It Fl L
Enable module loading events.
.It Fl l Ar maxlength
Maximum lenght of the quark queue, essentially how much quark is willing to
buffer, refer to
Expand Down Expand Up @@ -108,6 +112,8 @@ Display only events where parent pid is
Enable socket events (experimental).
.It Fl s
Don't send the initial snapshot of existing processes.
.It Fl T
Enable ptrace event tracing.
.It Fl t
Don't supress thread events, this is only useful for debugging and will likely
be zapped in the future.
Expand Down
Loading