Skip to content

Commit

Permalink
make use of bpf_probe_read_(kernel|user) functions
Browse files Browse the repository at this point in the history
Signed-off-by: grantseltzer <[email protected]>
  • Loading branch information
grantseltzer committed Dec 19, 2024
1 parent afa848c commit b2892a3
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 29 deletions.
48 changes: 38 additions & 10 deletions pkg/dynamicinstrumentation/codegen/c/dynamicinstrumentation.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,23 @@ int {{.GetBPFFuncName}}(struct pt_regs *ctx)
bpf_ringbuf_discard(event, 0);
return 0;
}

bpf_probe_read(&event->base.probe_id, sizeof(event->base.probe_id), zero_string);
bpf_probe_read(&event->base.program_counters, sizeof(event->base.program_counters), zero_string);
bpf_probe_read(&event->output, sizeof(event->output), zero_string);
bpf_probe_read(&event->base.probe_id, {{ .ID | len }}, "{{.ID}}");
long err;
err = bpf_probe_read_kernel(&event->base.probe_id, sizeof(event->base.probe_id), zero_string);
if (err != 0) {
bpf_printk("could not zero out probe id buffer");
}
err = bpf_probe_read_kernel(&event->base.program_counters, sizeof(event->base.program_counters), zero_string);
if (err != 0) {
bpf_printk("could not zero out program counter buffer");
}
err = bpf_probe_read_kernel(&event->output, sizeof(event->output), zero_string);
if (err != 0) {
bpf_printk("could not zero out output buffer");
}
err = bpf_probe_read_kernel(&event->base.probe_id, {{ .ID | len }}, "{{.ID}}");
if (err != 0) {
bpf_printk("could not write probe id to output");
}

// Get tid and tgid
u64 pidtgid = bpf_get_current_pid_tgid();
Expand All @@ -46,10 +58,17 @@ int {{.GetBPFFuncName}}(struct pt_regs *ctx)

// Collect stack trace
__u64 currentPC = PT_REGS_IP(ctx);
bpf_probe_read(&event->base.program_counters[0], sizeof(__u64), &currentPC);
err = bpf_probe_read_kernel(&event->base.program_counters[0], sizeof(__u64), &currentPC);
if (err != 0) {
bpf_printk("could not collect first program counter");
}

__u64 bp = PT_REGS_FP(ctx);
bpf_probe_read(&bp, sizeof(__u64), (void*)bp); // dereference bp to get current stack frame
err = bpf_probe_read_user(&bp, sizeof(__u64), (void*)bp); // dereference bp to get current stack frame
if (err != 0) {
bpf_printk("could not retrieve base pointer for current stack frame");
}

__u64 ret_addr = PT_REGS_RET(ctx); // when bpf prog enters, the return address hasn't yet been written to the stack

int i;
Expand All @@ -60,9 +79,18 @@ int {{.GetBPFFuncName}}(struct pt_regs *ctx)
if (bp == 0) {
break;
}
bpf_probe_read(&event->base.program_counters[i], sizeof(__u64), &ret_addr);
bpf_probe_read(&ret_addr, sizeof(__u64), (void*)(bp-8));
bpf_probe_read(&bp, sizeof(__u64), (void*)bp);
err = bpf_probe_read_kernel(&event->base.program_counters[i], sizeof(__u64), &ret_addr);
if (err != 0) {
bpf_printk("error occurred while collecting program counter for stack trace (1)");
}
err = bpf_probe_read_user(&ret_addr, sizeof(__u64), (void*)(bp-8));
if (err != 0) {
bpf_printk("error occurred while collecting program counter for stack trace (2)");
}
err = bpf_probe_read_user(&bp, sizeof(__u64), (void*)bp);
if (err != 0) {
bpf_printk("error occurred while collecting program counter for stack trace (3)");
}
}

// Collect parameters
Expand Down
3 changes: 3 additions & 0 deletions pkg/dynamicinstrumentation/codegen/c/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
#define DI_EVENT_H

#include "ktypes.h"
#include "macros.h"

struct event {
struct base_event base;
char output[PARAM_BUFFER_SIZE];
};

// expression_context contains state that is meant to be shared across location expressions
// during execution of the full bpf program.
struct expression_context {
__u64 *output_offset;
__u8 *stack_counter;
Expand Down
28 changes: 14 additions & 14 deletions pkg/dynamicinstrumentation/codegen/c/expressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ static __always_inline int read_register(struct expression_context context, __u6
{
long err;
__u64 valueHolder = 0;
err = bpf_probe_read(&valueHolder, element_size, &context.ctx->DWARF_REGISTER(reg));
err = bpf_probe_read_kernel(&valueHolder, element_size, &context.ctx->DWARF_REGISTER(reg));
if (err != 0) {
log_debug("error when reading data from register: %ld", err);
}
Expand All @@ -22,7 +22,7 @@ static __always_inline int read_stack(struct expression_context context, size_t
{
long err;
__u64 valueHolder = 0;
err = bpf_probe_read(&valueHolder, element_size, &context.ctx->DWARF_STACK_REGISTER+stack_offset);
err = bpf_probe_read_kernel(&valueHolder, element_size, &context.ctx->DWARF_STACK_REGISTER+stack_offset);
if (err != 0) {
log_debug("error when reading data from stack: %ld", err);
}
Expand All @@ -36,7 +36,7 @@ static __always_inline int read_stack(struct expression_context context, size_t
static __always_inline int read_register_value_to_output(struct expression_context context, __u64 reg, __u32 element_size)
{
long err;
err = bpf_probe_read(&context.event->output[*(context.output_offset)], element_size, &context.ctx->DWARF_REGISTER(reg));
err = bpf_probe_read_kernel(&context.event->output[*(context.output_offset)], element_size, &context.ctx->DWARF_REGISTER(reg));
if (err != 0) {
log_debug("error when reading data while reading register value to output: %ld", err);
}
Expand All @@ -49,7 +49,7 @@ static __always_inline int read_register_value_to_output(struct expression_conte
static __always_inline int read_stack_value_to_output(struct expression_context context, __u64 stack_offset, __u32 element_size)
{
long err;
err = bpf_probe_read(&context.event->output[*(context.output_offset)], element_size, &context.ctx->DWARF_STACK_REGISTER+stack_offset);
err = bpf_probe_read_kernel(&context.event->output[*(context.output_offset)], element_size, &context.ctx->DWARF_STACK_REGISTER+stack_offset);
if (err != 0) {
log_debug("error when reading data while reading stack value to output: %ld", err);
}
Expand All @@ -68,7 +68,7 @@ static __always_inline int pop(struct expression_context context, __u64 num_elem
bpf_map_pop_elem(&param_stack, &valueHolder);
*context.stack_counter -= 1;
log_debug("Popping to output: %llu", valueHolder);
err = bpf_probe_read(&context.event->output[*(context.output_offset)+i], element_size, &valueHolder);
err = bpf_probe_read_kernel(&context.event->output[*(context.output_offset)+i], element_size, &valueHolder);
if (err != 0) {
log_debug("error when reading data while popping from bpf stack: %ld", err);
return_err = err;
Expand Down Expand Up @@ -122,7 +122,7 @@ static __always_inline int dereference_to_output(struct expression_context conte
__u64 valueHolder = 0;

log_debug("Going to deref to output: 0x%llx", addressHolder);
err = bpf_probe_read(&valueHolder, element_size, (void*)addressHolder);
err = bpf_probe_read_user(&valueHolder, element_size, (void*)addressHolder);
if (err != 0) {
return_err = err;
log_debug("error when reading data while dereferencing to output: %ld", err);
Expand All @@ -131,7 +131,7 @@ static __always_inline int dereference_to_output(struct expression_context conte
__u64 encodedValueHolder = valueHolder & mask;

log_debug("Writing %llu to output (dereferenced)", encodedValueHolder);
err = bpf_probe_read(&context.event->output[*(context.output_offset)], element_size, &encodedValueHolder);
err = bpf_probe_read_kernel(&context.event->output[*(context.output_offset)], element_size, &encodedValueHolder);
if (err != 0) {
return_err = err;
log_debug("error when reading data while dereferencing into output: %ld", err);
Expand All @@ -156,7 +156,7 @@ static __always_inline int dereference_large(struct expression_context context,
__u32 chunk_size;
for (i = 0; i < num_chunks; i++) {
chunk_size = (i == num_chunks - 1 && element_size % 8 != 0) ? (element_size % 8) : 8;
err = bpf_probe_read(&context.temp_storage[i], element_size, (void*)(addressHolder + (i * 8)));
err = bpf_probe_read_user(&context.temp_storage[i], element_size, (void*)(addressHolder + (i * 8)));
if (err != 0) {
return_err = err;
log_debug("error when reading data dereferencing large: %ld", err);
Expand All @@ -175,7 +175,7 @@ static __always_inline int dereference_large(struct expression_context context,
}

// zero out shared array
err = bpf_probe_read(context.temp_storage, element_size*num_chunks, context.zero_string);
err = bpf_probe_read_kernel(context.temp_storage, element_size*num_chunks, context.zero_string);
if (err != 0) {
return_err = err;
log_debug("error when reading data zeroing out shared memory while dereferencing large: %ld", err);
Expand All @@ -192,7 +192,7 @@ static __always_inline int dereference_large_to_output(struct expression_context
__u64 addressHolder = 0;
bpf_map_pop_elem(&param_stack, &addressHolder);
*context.stack_counter -= 1;
err = bpf_probe_read(&context.event->output[*(context.output_offset)], element_size, (void*)(addressHolder));
err = bpf_probe_read_user(&context.event->output[*(context.output_offset)], element_size, (void*)(addressHolder));
if (err != 0) {
log_debug("error when reading data: %ld", err);
}
Expand Down Expand Up @@ -232,7 +232,7 @@ static __always_inline int dereference_dynamic_to_output(struct expression_conte
if (collection_size > bytes_limit) {
collection_size = bytes_limit;
}
err = bpf_probe_read(&context.event->output[*(context.output_offset)], collection_size, (void*)addressHolder);
err = bpf_probe_read_user(&context.event->output[*(context.output_offset)], collection_size, (void*)addressHolder);
if (err != 0) {
log_debug("error when doing dynamic dereference: %ld", err);
}
Expand Down Expand Up @@ -296,19 +296,19 @@ static __always_inline int read_str_to_output(struct expression_context context,
*context.stack_counter -= 1;

char* characterPointer = 0;
err = bpf_probe_read(&characterPointer, sizeof(characterPointer), (void*)(stringStructAddressHolder));
err = bpf_probe_read_user(&characterPointer, sizeof(characterPointer), (void*)(stringStructAddressHolder));
log_debug("Reading from 0x%p", characterPointer);

__u32 length;
err = bpf_probe_read(&length, sizeof(length), (void*)(stringStructAddressHolder+8));
err = bpf_probe_read_user(&length, sizeof(length), (void*)(stringStructAddressHolder+8));
if (err != 0) {
log_debug("error reading string length: %ld", err);
return err;
}
if (length > limit) {
length = limit;
}
err = bpf_probe_read(&context.event->output[*(context.output_offset)], length, (char*)characterPointer);
err = bpf_probe_read_user(&context.event->output[*(context.output_offset)], length, (char*)characterPointer);
if (err != 0) {
log_debug("error reading string: %ld", err);
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/dynamicinstrumentation/codegen/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ var headerTemplateText = `
// Name={{.Name}} ID={{.ID}} TotalSize={{.TotalSize}} Kind={{.Kind}}
// Write the kind and size to output buffer
param_type = {{.Kind}};
bpf_probe_read(&event->output[outputOffset], sizeof(param_type), &param_type);
bpf_probe_read_kernel(&event->output[outputOffset], sizeof(param_type), &param_type);
param_size = {{.TotalSize}};
bpf_probe_read(&event->output[outputOffset+1], sizeof(param_size), &param_size);
bpf_probe_read_kernel(&event->output[outputOffset+1], sizeof(param_size), &param_size);
outputOffset += 3;
`
var sliceRegisterHeaderTemplateText = `
// Name={{.Parameter.Name}} ID={{.Parameter.ID}} TotalSize={{.Parameter.TotalSize}} Kind={{.Parameter.Kind}}
// Write the slice kind to output buffer
param_type = {{.Parameter.Kind}};
bpf_probe_read(&event->output[outputOffset], sizeof(param_type), &param_type);
bpf_probe_read_kernel(&event->output[outputOffset], sizeof(param_type), &param_type);
outputOffset += 1;
Expand All @@ -42,7 +42,7 @@ var sliceStackHeaderTemplateText = `
// Name={{.Parameter.Name}} ID={{.Parameter.ID}} TotalSize={{.Parameter.TotalSize}} Kind={{.Parameter.Kind}}
// Write the slice kind to output buffer
param_type = {{.Parameter.Kind}};
bpf_probe_read(&event->output[outputOffset], sizeof(param_type), &param_type);
bpf_probe_read_kernel(&event->output[outputOffset], sizeof(param_type), &param_type);
outputOffset += 1;
Expand All @@ -53,7 +53,7 @@ var stringHeaderTemplateText = `
// Name={{.Name}} ID={{.ID}} TotalSize={{.TotalSize}} Kind={{.Kind}}
// Write the string kind to output buffer
param_type = {{.Kind}};
bpf_probe_read(&event->output[outputOffset], sizeof(param_type), &param_type);
bpf_probe_read_kernel(&event->output[outputOffset], sizeof(param_type), &param_type);
outputOffset += 1;
`

Expand Down

0 comments on commit b2892a3

Please sign in to comment.