Skip to content

Commit

Permalink
libbpf: fix access violation in libbpf_print_fn.
Browse files Browse the repository at this point in the history
libbpf_print_fn uses va_arg and explicit argument type "char*" to
retrieve arguments as strings. This assumption is incorrect.  In case
when libbpf logs a printf format string with argument being a
non-string type, the str pointer will point to memory that is not NULL
terminated. Wnen strstr is called with a non-NULL terminated string,
we hit access violation on the stack.

This change uses a temporary string allocated on the stack to be
filled with a printf formatted string with the arguments converted
into the string. The keywords search are performed on the temporary
string buffer.

Signed-off-by: Hao Xiang <haoxiang@bytedance.com>
  • Loading branch information
Hao Xiang authored and rafaeldtinoco committed Dec 12, 2022
1 parent 6950f38 commit aa91d8b
Showing 1 changed file with 20 additions and 21 deletions.
41 changes: 20 additions & 21 deletions libbpfgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,39 @@
#include <bpf/bpf.h>
#include <bpf/libbpf.h>

int libbpf_print_fn(enum libbpf_print_level level, const char *format,
va_list args) {
int libbpf_print_fn(enum libbpf_print_level level, // libbpf print level
const char *format, // format used for the msg
va_list args) { // args used by format

if (level != LIBBPF_WARN)
return 0;

// NOTE: va_list args is managed in libbpf caller
// however, these copies must be matched with va_end() in this function
va_list exclusivity_check, cgroup_check;
va_copy(exclusivity_check, args);
va_copy(cgroup_check, args);
int ret;
char str[300];
va_list check;

va_copy(check, args);
ret = vsnprintf(str, sizeof(str), format, check);
va_end(args);

// BUG: https://github.com/aquasecurity/tracee/issues/1676
if (ret <= 0) {
goto done;
}

char *str = va_arg(exclusivity_check, char *);
// BUG: https:/github.com/aquasecurity/tracee/issues/1676
if (strstr(str, "Exclusivity flag on") != NULL) {
va_end(exclusivity_check);
return 0;
}
va_end(exclusivity_check);

// AttachCgroupLegacy() will first try AttachCgroup() and it
// might fail. This is not an error and is the best way of
// probing for eBPF cgroup attachment link existence.

str = va_arg(cgroup_check, char *);
// AttachCgroupLegacy() will first try AttachCgroup() and it might fail. This
// is not an error and is the best way of probing for eBPF cgroup attachment
// link existence.
if (strstr(str, "cgroup") != NULL) {
str = va_arg(cgroup_check, char *);
if (strstr(str, "Invalid argument") != NULL) {
va_end(cgroup_check);
if (strstr(str, "Invalid argument") != NULL)
return 0;
}
}
va_end(cgroup_check);

done:
return vfprintf(stderr, format, args);
}

Expand Down

0 comments on commit aa91d8b

Please sign in to comment.