Skip to content

Commit

Permalink
fix(libpman): avoid truncated verifier logs
Browse files Browse the repository at this point in the history
4096 bytes are not enough for long verifier logs, we need to use the
same dimension provided by libbpf (UINT32_MAX >> 8)

Signed-off-by: Andrea Terzolo <[email protected]>
  • Loading branch information
Andreagit97 authored and poiana committed Jun 24, 2024
1 parent dcf250a commit f286ecb
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
27 changes: 24 additions & 3 deletions userspace/libpman/src/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,23 @@ static int libbpf_print(enum libbpf_print_level level, const char* format, va_li
if(g_state.log_fn == NULL)
return vfprintf(stderr, format, args);

char buf[4096];
int rc = vsnprintf(buf, sizeof(buf), format, args);
// This should be already allocated by the caller, but if for some reason libbpf wants to log again after initialization we create a smaller buffer.
// We need a big buffer only for verifier logs at initialization time.
if(g_state.log_buf == NULL)
{
g_state.log_buf_size = 0;
// this will be freed when the global state is destroyed.
g_state.log_buf = calloc(1, BPF_LOG_SMALL_BUF_SIZE);
if(g_state.log_buf == NULL)
return -ENOMEM;
g_state.log_buf_size = BPF_LOG_SMALL_BUF_SIZE;
}
int rc = vsnprintf(g_state.log_buf, g_state.log_buf_size, format, args);
if(rc < 0)
return rc;

// don't need a component name for libbpf, it will prepend "libbpf: " to logs for us
g_state.log_fn(NULL, buf, sev);
g_state.log_fn(NULL, g_state.log_buf, sev);
return rc;
}

Expand All @@ -73,6 +83,12 @@ void pman_clear_state()
g_state.n_attached_progs = 0;
g_state.stats = NULL;
g_state.log_fn = NULL;
if(g_state.log_buf)
{
free(g_state.log_buf);
}
g_state.log_buf = NULL;
g_state.log_buf_size = 0;
}

int pman_init_state(falcosecurity_log_fn log_fn, unsigned long buf_bytes_dim, uint16_t cpus_for_each_buffer,
Expand All @@ -88,6 +104,11 @@ int pman_init_state(falcosecurity_log_fn log_fn, unsigned long buf_bytes_dim, ui

/* Set libbpf logging. */
g_state.log_fn = log_fn;
// we allocate a big buffer for verifier logs we will free it after initialization.
g_state.log_buf = calloc(1, BPF_LOG_BIG_BUF_SIZE);
if(g_state.log_buf == NULL)
return -ENOMEM;
g_state.log_buf_size = BPF_LOG_BIG_BUF_SIZE;
libbpf_set_print(libbpf_print);

/* Bump rlimit in any case. We need to do that because some kernels backport
Expand Down
7 changes: 7 additions & 0 deletions userspace/libpman/src/lifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ int pman_load_probe()
return errno;
}
pman_save_attached_progs();
// Programs are loaded so we passed the verifier we can free the 16 MB
if(g_state.log_buf)
{
free(g_state.log_buf);
g_state.log_buf = NULL;
g_state.log_buf_size = 0;
}
return 0;
}

Expand Down
6 changes: 5 additions & 1 deletion userspace/libpman/src/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ limitations under the License.
/* Pay attention this need to be bumped every time we add a new bpf program that is directly attached into the kernel */
#define MODERN_BPF_PROG_ATTACHED_MAX 9

#define BPF_LOG_BIG_BUF_SIZE (UINT32_MAX >> 8) /* Recommended log buffer size, taken from libbpf. Used for verifier logs */
#define BPF_LOG_SMALL_BUF_SIZE 8192 /* Used for libbpf non-verifier logs */

struct metrics_v2;

struct internal_state
Expand All @@ -58,7 +61,8 @@ struct internal_state
collect stats */
uint16_t n_attached_progs; /* number of attached progs */
struct metrics_v2* stats; /* array of stats collected by libpman */

char* log_buf; /* buffer used to store logs before sending them to the log_fn */
size_t log_buf_size; /* size of the log buffer */
falcosecurity_log_fn log_fn;
};

Expand Down

0 comments on commit f286ecb

Please sign in to comment.