Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new(driver): update exit events PPME_SYSCALL_READ_X and PPME_SYSCALL_PREAD_X with enter params #2176

Merged
merged 11 commits into from
Dec 5, 2024
2 changes: 1 addition & 1 deletion driver/SCHEMA_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.23.0
3.0.0
72 changes: 56 additions & 16 deletions driver/bpf/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,28 +407,30 @@ FILLER(sys_read_e, true) {
}

FILLER(sys_read_x, true) {
unsigned long bufsize;
unsigned long val;
long retval;
int res;

/* Parameter 1: res (type: PT_ERRNO) */
retval = bpf_syscall_get_retval(data->ctx);
res = bpf_push_s64_to_ring(data, (int64_t)retval);
long retval = bpf_syscall_get_retval(data->ctx);
int res = bpf_push_s64_to_ring(data, (int64_t)retval);
CHECK_RES(res);

if(retval < 0) {
/* Parameter 2: data (type: PT_BYTEBUF) */
return bpf_push_empty_param(data);
// We will use it for dynamic snaplen calculation and we will push it also to the buffer.
data->fd = bpf_syscall_get_argument(data, 0);

/* Parameter 2: data (type: PT_BYTEBUF) */
if(retval > 0) {
unsigned long val = bpf_syscall_get_argument(data, 1);
res = __bpf_val_to_ring(data, val, retval, PT_BYTEBUF, -1, true, USER);
} else {
res = bpf_push_empty_param(data);
}
CHECK_RES(res);

val = bpf_syscall_get_argument(data, 1);
bufsize = retval;
/* Parameter 3: fd (type: PT_FD) */
res = bpf_push_s64_to_ring(data, (int64_t)data->fd);
CHECK_RES(res);

/* Parameter 2: data (type: PT_BYTEBUF) */
data->fd = bpf_syscall_get_argument(data, 0);
return __bpf_val_to_ring(data, val, bufsize, PT_BYTEBUF, -1, true, USER);
;
/* Parameter 4: size (type: PT_UINT32) */
size_t size = bpf_syscall_get_argument(data, 2);
return bpf_push_u32_to_ring(data, size);
}

FILLER(sys_write_e, true) {
Expand Down Expand Up @@ -4753,6 +4755,44 @@ FILLER(sys_pread64_e, true) {
return bpf_push_u64_to_ring(data, val);
}

FILLER(sys_pread64_x, true) {
// This is due to the `pos` parameter
#ifndef CAPTURE_64BIT_ARGS_SINGLE_REGISTER
#error Implement this
#endif
unsigned long val = 0;

/* Parameter 1: res (type: PT_ERRNO) */
long retval = bpf_syscall_get_retval(data->ctx);
int res = bpf_push_s64_to_ring(data, (int64_t)retval);
CHECK_RES(res);

// We will use it for dynamic snaplen calculation and we will push it also to the buffer.
data->fd = bpf_syscall_get_argument(data, 0);

/* Parameter 2: data (type: PT_BYTEBUF) */
if(retval > 0) {
val = bpf_syscall_get_argument(data, 1);
res = __bpf_val_to_ring(data, val, retval, PT_BYTEBUF, -1, true, USER);
} else {
res = bpf_push_empty_param(data);
}
CHECK_RES(res);

/* Parameter 3: fd (type: PT_FD) */
res = bpf_push_s64_to_ring(data, (int64_t)data->fd);
CHECK_RES(res);

/* Parameter 4: size (type: PT_UINT32) */
size_t size = bpf_syscall_get_argument(data, 2);
res = bpf_push_u32_to_ring(data, size);
CHECK_RES(res);

/* Parameter 5: pos (type: PT_UINT64) */
val = bpf_syscall_get_argument(data, 3);
return bpf_push_u64_to_ring(data, val);
}

FILLER(sys_pwrite64_e, true) {
#ifndef CAPTURE_64BIT_ARGS_SINGLE_REGISTER
#error Implement this
Expand Down
23 changes: 15 additions & 8 deletions driver/event_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,17 @@ const struct ppm_event_info g_event_info[] = {
{{"res", PT_ERRNO, PF_DEC}}},
[PPME_SYSCALL_READ_E] = {"read",
EC_IO_READ | EC_SYSCALL,
EF_USES_FD | EF_READS_FROM_FD,
EF_USES_FD | EF_READS_FROM_FD | EF_TMP_CONVERTER_MANAGED,
2,
{{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}}},
[PPME_SYSCALL_READ_X] = {"read",
EC_IO_READ | EC_SYSCALL,
EF_USES_FD | EF_READS_FROM_FD,
2,
{{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA}}},
EF_USES_FD | EF_READS_FROM_FD | EF_TMP_CONVERTER_MANAGED,
4,
{{"res", PT_ERRNO, PF_DEC},
{"data", PT_BYTEBUF, PF_NA},
{"fd", PT_FD, PF_DEC},
{"size", PT_UINT32, PF_DEC}}},
[PPME_SYSCALL_WRITE_E] = {"write",
EC_IO_WRITE | EC_SYSCALL,
EF_USES_FD | EF_WRITES_TO_FD,
Expand Down Expand Up @@ -549,16 +552,20 @@ const struct ppm_event_info g_event_info[] = {
{"unlinkat", EC_FILE | EC_SYSCALL, EF_OLD_VERSION, 1, {{"res", PT_ERRNO, PF_DEC}}},
[PPME_SYSCALL_PREAD_E] = {"pread",
EC_IO_READ | EC_SYSCALL,
EF_USES_FD | EF_READS_FROM_FD,
EF_USES_FD | EF_READS_FROM_FD | EF_TMP_CONVERTER_MANAGED,
3,
{{"fd", PT_FD, PF_DEC},
{"size", PT_UINT32, PF_DEC},
{"pos", PT_UINT64, PF_DEC}}},
[PPME_SYSCALL_PREAD_X] = {"pread",
EC_IO_READ | EC_SYSCALL,
EF_USES_FD | EF_READS_FROM_FD,
2,
{{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA}}},
EF_USES_FD | EF_READS_FROM_FD | EF_TMP_CONVERTER_MANAGED,
5,
{{"res", PT_ERRNO, PF_DEC},
{"data", PT_BYTEBUF, PF_NA},
{"fd", PT_FD, PF_DEC},
{"size", PT_UINT32, PF_DEC},
{"pos", PT_UINT64, PF_DEC}}},
[PPME_SYSCALL_PWRITE_E] = {"pwrite",
EC_IO_WRITE | EC_SYSCALL,
EF_USES_FD | EF_WRITES_TO_FD,
Expand Down
2 changes: 1 addition & 1 deletion driver/fillers_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = {
[PPME_SYSCALL_UNLINKAT_E] = {FILLER_REF(sys_autofill), 2, APT_REG, {{0}, {1}}},
[PPME_SYSCALL_UNLINKAT_X] = {FILLER_REF(sys_single_x)},
[PPME_SYSCALL_PREAD_E] = {FILLER_REF(sys_pread64_e)},
[PPME_SYSCALL_PREAD_X] = {FILLER_REF(sys_read_x)},
[PPME_SYSCALL_PREAD_X] = {FILLER_REF(sys_pread64_x)},
[PPME_SYSCALL_PWRITE_E] = {FILLER_REF(sys_pwrite64_e)},
[PPME_SYSCALL_PWRITE_X] = {FILLER_REF(sys_write_x)},
[PPME_SYSCALL_READV_E] = {FILLER_REF(sys_readv_e)},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ int BPF_PROG(pread64_x, struct pt_regs *regs, long ret) {
auxmap__store_empty_param(auxmap);
}

/* Parameter 3: fd (type: PT_FD) */
int32_t fd = (int32_t)extract__syscall_argument(regs, 0);
auxmap__store_s64_param(auxmap, (int64_t)fd);

/* Parameter 4: size (type: PT_UINT32) */
uint32_t size = (uint32_t)extract__syscall_argument(regs, 2);
auxmap__store_u32_param(auxmap, (uint32_t)size);

/* Parameter 5: pos (type: PT_UINT64) */
uint64_t pos = (uint64_t)extract__syscall_argument(regs, 3);
auxmap__store_u64_param(auxmap, pos);

/*=============================== COLLECT PARAMETERS ===========================*/

auxmap__finalize_event_header(auxmap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ int BPF_PROG(read_x, struct pt_regs *regs, long ret) {
/* Parameter 1: res (type: PT_ERRNO) */
auxmap__store_s64_param(auxmap, ret);

/* Parameter 2: data (type: PT_BYTEBUF) */
if(ret > 0) {
/* We read the minimum between `snaplen` and what we really
* have in the buffer.
Expand All @@ -65,14 +66,20 @@ int BPF_PROG(read_x, struct pt_regs *regs, long ret) {
snaplen = ret;
}

/* Parameter 2: data (type: PT_BYTEBUF) */
unsigned long data_pointer = extract__syscall_argument(regs, 1);
auxmap__store_bytebuf_param(auxmap, data_pointer, snaplen, USER);
} else {
/* Parameter 2: data (type: PT_BYTEBUF) */
auxmap__store_empty_param(auxmap);
}

/* Parameter 3: fd (type: PT_FD) */
int32_t fd = (int32_t)extract__syscall_argument(regs, 0);
auxmap__store_s64_param(auxmap, (int64_t)fd);

/* Parameter 4: size (type: PT_UINT32) */
uint32_t size = (uint32_t)extract__syscall_argument(regs, 2);
auxmap__store_u32_param(auxmap, size);

/*=============================== COLLECT PARAMETERS ===========================*/

auxmap__finalize_event_header(auxmap);
Expand Down
107 changes: 79 additions & 28 deletions driver/ppm_fillers.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,45 +403,34 @@ int f_sys_read_x(struct event_filler_arguments *args) {
unsigned long val;
int res;
int64_t retval;
unsigned long bufsize;

/*
* Retrieve the FD. It will be used for dynamic snaplen calculation.
*/
// Retrieve the FD. It will be used for dynamic snaplen calculation.
syscall_get_arguments_deprecated(args, 0, 1, &val);
args->fd = (int)val;

/*
* res
*/
/* Parameter 1: res (type: PT_ERRNO) */
retval = (int64_t)(long)syscall_get_return_value(current, args->regs);
res = val_to_ring(args, retval, 0, false, 0);
CHECK_RES(res);

/*
* data
*/
if(retval < 0) {
/*
* The operation failed, return an empty buffer
*/
val = 0;
bufsize = 0;
} else {
/* Parameter 2: data (type: PT_BYTEBUF) */
if(retval > 0) {
// val now contains the pointer to the buffer
syscall_get_arguments_deprecated(args, 1, 1, &val);

/*
* The return value can be lower than the value provided by the user,
* and we take that into account.
*/
bufsize = retval;
args->enforce_snaplen = true;
res = val_to_ring(args, val, retval, true, 0);
} else {
res = push_empty_param(args);
}
CHECK_RES(res);

/*
* Copy the buffer
*/
args->enforce_snaplen = true;
res = val_to_ring(args, val, bufsize, true, 0);
/* Parameter 3: fd (type: PT_FD) */
res = val_to_ring(args, (int64_t)args->fd, 0, false, 0);
CHECK_RES(res);

/* Parameter 4: size (type: PT_UINT32) */
syscall_get_arguments_deprecated(args, 2, 1, &val);
res = val_to_ring(args, val, 0, false, 0);
CHECK_RES(res);

return add_sentinel(args);
Expand Down Expand Up @@ -3688,6 +3677,68 @@ int f_sys_pread64_e(struct event_filler_arguments *args) {
return add_sentinel(args);
}

int f_sys_pread64_x(struct event_filler_arguments *args) {
unsigned long val;
int res;
int64_t retval;
unsigned long pos64;

// Retrieve the FD. It will be used for dynamic snaplen calculation.
syscall_get_arguments_deprecated(args, 0, 1, &val);
args->fd = (int)val;

/* Parameter 1: res (type: PT_ERRNO) */
retval = (int64_t)(long)syscall_get_return_value(current, args->regs);
res = val_to_ring(args, retval, 0, false, 0);
CHECK_RES(res);

/* Parameter 2: data (type: PT_BYTEBUF) */
if(retval > 0) {
// val now contains the pointer to the buffer
syscall_get_arguments_deprecated(args, 1, 1, &val);
args->enforce_snaplen = true;
res = val_to_ring(args, val, retval, true, 0);
} else {
res = push_empty_param(args);
}
CHECK_RES(res);

/* Parameter 3: fd (type: PT_FD) */
res = val_to_ring(args, (int64_t)args->fd, 0, false, 0);
CHECK_RES(res);

/* Parameter 4: size (type: PT_UINT32) */
syscall_get_arguments_deprecated(args, 2, 1, &val);
res = val_to_ring(args, val, 0, false, 0);
CHECK_RES(res);

/* Parameter 5: pos (type: PT_UINT64) */
#ifndef CAPTURE_64BIT_ARGS_SINGLE_REGISTER
{
unsigned long pos0;
unsigned long pos1;
#if defined CONFIG_X86
syscall_get_arguments_deprecated(args, 3, 1, &pos0);
syscall_get_arguments_deprecated(args, 4, 1, &pos1);
#elif defined CONFIG_ARM && CONFIG_AEABI
syscall_get_arguments_deprecated(args, 4, 1, &pos0);
syscall_get_arguments_deprecated(args, 5, 1, &pos1);
#else
#error This architecture/abi not yet supported
#endif

pos64 = merge_64(pos1, pos0);
}
#else
syscall_get_arguments_deprecated(args, 3, 1, &pos64);
#endif

res = val_to_ring(args, pos64, 0, false, 0);
CHECK_RES(res);

return add_sentinel(args);
}

int f_sys_pwrite64_e(struct event_filler_arguments *args) {
unsigned long val;
unsigned long size;
Expand Down
1 change: 1 addition & 0 deletions driver/ppm_fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ or GPL2.txt for full copies of the license.
FN(sys_process_vm_readv_x) \
FN(sys_process_vm_writev_x) \
FN(sys_delete_module_x) \
FN(sys_pread64_x) \
FN(terminate_filler)

#define FILLER_ENUM_FN(x) PPM_FILLER_##x,
Expand Down
11 changes: 10 additions & 1 deletion test/drivers/test_suites/syscall_exit_suite/pread64_x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,18 @@ TEST(SyscallExit, preadX_fail) {
/* Parameter 2: data (type: PT_BYTEBUF) */
evt_test->assert_empty_param(2);

/* Parameter 3: fd (type: PT_FD) */
evt_test->assert_numeric_param(3, int64_t(-1));

/* Parameter 4: size (type: PT_UINT32) */
evt_test->assert_numeric_param(4, uint32_t(size));

/* Parameter 5: pos (type: PT_UINT64) */
evt_test->assert_numeric_param(5, uint64_t(pos));

/*=============================== ASSERT PARAMETERS ===========================*/

evt_test->assert_num_params_pushed(2);
evt_test->assert_num_params_pushed(5);
}

#endif
Loading
Loading