Skip to content

Commit

Permalink
chore(driver/modern_bpf,userspace/libpman): address review comments.
Browse files Browse the repository at this point in the history
Use anonymous unions in modern bpf driver. Moreover, add some debug prints to `pman_prepare_progs_before_loading`,
and always disable all unused programs autoload.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Mauro Ezequiel Moltrasio <mmoltras@redhat.com>
  • Loading branch information
2 people authored and poiana committed Feb 11, 2025
1 parent 73e96f6 commit ad06e92
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 31 deletions.
10 changes: 4 additions & 6 deletions driver/modern_bpf/helpers/store/auxmap_store_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -1558,13 +1558,12 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs,
*/
unsigned long args[5] = {0};
struct sockaddr *sockaddr = NULL;
typedef union {
union {
struct compat_msghdr compat_mh;
struct user_msghdr mh;
struct compat_mmsghdr compat_mmh;
struct mmsghdr mmh;
} mh_t;
mh_t msg_mh = {};
} msg_mh = {};

switch(input_args->evt_type) {
case PPME_SOCKET_SENDTO_X:
Expand Down Expand Up @@ -1651,11 +1650,10 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs,
port_remote = ntohs(port_remote);

if(port_remote == 0 && sockaddr != NULL) {
typedef union {
union {
struct sockaddr_in sockaddr_in;
struct sockaddr_in6 sockaddr_in6;
} sa_t;
sa_t saddr_in = {};
} saddr_in = {};
if(socket_family == AF_INET) {
bpf_probe_read_user(&saddr_in.sockaddr_in,
bpf_core_type_size(struct sockaddr_in),
Expand Down
83 changes: 61 additions & 22 deletions userspace/libpman/src/lifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,77 @@ int pman_open_probe() {
}

int pman_prepare_progs_before_loading() {
char msg[MAX_ERROR_MESSAGE_LEN];
/*
* Probe required features for each bpf program, as requested
*/
errno = 0;
for(int ev = 0; ev < PPM_EVENT_MAX; ev++) {
int num_skipped = 0;
int idx = 0;
event_prog_t *progs = event_prog_table[ev];
for(; idx < MAX_FEATURE_CHECKS && progs[idx].name != NULL; idx++) {
if(progs[idx].feat > 0) {
if(libbpf_probe_bpf_helper(BPF_PROG_TYPE_RAW_TRACEPOINT, progs[idx].feat, NULL) ==
0) {
int idx, chosen_idx = -1;
for(idx = 0; idx < MAX_FEATURE_CHECKS && progs[idx].name != NULL; idx++) {
bool should_disable = chosen_idx != -1;
if(!should_disable) {
if(progs[idx].feat > 0 &&
libbpf_probe_bpf_helper(BPF_PROG_TYPE_RAW_TRACEPOINT, progs[idx].feat, NULL) ==
0) {
snprintf(msg,
MAX_ERROR_MESSAGE_LEN,
"BPF program '%s' did not satisfy required feature [%d]",
progs[idx].name,
progs[idx].feat);
pman_print_msg(FALCOSECURITY_LOG_SEV_DEBUG, (const char *)msg);
// Required feature not present
struct bpf_program *p =
bpf_object__find_program_by_name(g_state.skel->obj, progs[idx].name);
if(p) {
bpf_program__set_autoload(p, false);
} else {
pman_print_error(" unable to find prog");
}
num_skipped++;
should_disable = true;
} else {
// We satified requested feature
snprintf(msg,
MAX_ERROR_MESSAGE_LEN,
"BPF program '%s' satisfied required feature [%d]",
progs[idx].name,
progs[idx].feat);
pman_print_msg(FALCOSECURITY_LOG_SEV_DEBUG, (const char *)msg);
chosen_idx = idx;
}
}
}
if(num_skipped > 0) {
if(num_skipped == idx) {
pman_print_error(" no program satisfies required features for event");
errno = ENXIO;
return errno;

// Disable autoloading for all programs except chosen one
if(should_disable) {
snprintf(msg, MAX_ERROR_MESSAGE_LEN, "disabling BPF program '%s'", progs[idx].name);
pman_print_msg(FALCOSECURITY_LOG_SEV_DEBUG, (const char *)msg);
struct bpf_program *p =
bpf_object__find_program_by_name(g_state.skel->obj, progs[idx].name);
if(p && bpf_program__set_autoload(p, false) == 0) {
snprintf(msg,
MAX_ERROR_MESSAGE_LEN,
"disabled BPF program '%s'",
progs[idx].name);
pman_print_msg(FALCOSECURITY_LOG_SEV_DEBUG, (const char *)msg);
} else {
snprintf(msg,
MAX_ERROR_MESSAGE_LEN,
"failed to disable prog '%s'",
progs[idx].name);
pman_print_error(msg);
}
}
// Store selected program in index 0 to be easily accessed by maps.c
progs[0] = progs[num_skipped];
}

// In case we couldn't find any program satisfying required features, give an error.
// As of today, this will never happen, but better safe than sorry.
if(chosen_idx == -1 && progs[0].name != NULL) {
snprintf(msg,
MAX_ERROR_MESSAGE_LEN,
"no program satisfies required features for event %d",
ev);
pman_print_error(msg);
errno = ENXIO;
return errno;
}

// Always move the selected program to index 0 to be easily accessed by maps.c
// If no programs are skipped, the following line expands to progs[0] = progs[0];
progs[0] = progs[chosen_idx];
}
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion userspace/libpman/src/maps.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ static int size_auxiliary_maps() {
static int size_counter_maps() {
/* We always allocate counter maps from all the CPUs, even if some of them are not online. */
if(bpf_map__set_max_entries(g_state.skel->maps.counter_maps, g_state.n_possible_cpus)) {
pman_print_error(" unable to set max entries for 'counter_maps'");
pman_print_error("unable to set max entries for 'counter_maps'");
return errno;
}
return 0;
Expand Down
4 changes: 2 additions & 2 deletions userspace/libscap/examples/01-open/scap_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -645,10 +645,10 @@ void scap_open_log_fn(const char* component,
const enum falcosecurity_log_severity sev) {
if(sev <= severity_level) {
if(component != NULL) {
printf("%s: %s", component, msg);
printf("%s: %s\n", component, msg);
} else {
// libbpf logs have no components
printf("%s", msg);
printf("%s\n", msg);
}
}
}
Expand Down

0 comments on commit ad06e92

Please sign in to comment.