An integer overflow occurs when the answer to an arithmetic operation exceeds the maximum size of the integer type used to store it. The resulting value will appear to have wrapped around the maximum value and started again at the minimum value. This would look like a clock that represents 13:00 by pointing at 1:00. An attacker can use an integer overflow during a buffer length calculation, which results in the allocated buffer being too small to hold the data copied into it, thus causing a buffer overflow.
Unless checked, the resulting number can exceed the expected range.
bcc-0.6.1/src/cc/libbpf.c
The highlighted line of code below is the trigger point of this particular Centos 7 integer weakness.
// didn't check NULL on map lookup
if (strstr(log, "invalid mem access 'map_value_or_null'") != NULL) {
fprintf(stderr, "HINT: The 'map_value_or_null' error can happen if "
"you dereference a pointer value from a map lookup without first "
"checking if that pointer is NULL.\n\n");
}
// lacking a bpf_probe_read
if (strstr(log, "invalid mem access 'inv'") != NULL) {
fprintf(stderr, "HINT: The invalid mem access 'inv' error can happen "
"if you try to dereference memory without first using "
"bpf_probe_read() to copy it to the BPF stack. Sometimes the "
"bpf_probe_read is automatic by the bcc rewriter, other times "
"you'll need to be explicit.\n\n");
}
// helper function not found in kernel
char *helper_str = strstr(log, "invalid func ");
if (helper_str != NULL) {
helper_str += strlen("invalid func ");
char *str = strchr(helper_str, '#');
if (str != NULL) {
helper_str = str + 1;
}
int helper_id = atoi(helper_str);
if (helper_id && helper_id < sizeof(helpers) / sizeof(struct bpf_helper)) {
struct bpf_helper helper = helpers[helper_id - 1];
fprintf(stderr, "HINT: bpf_%s missing (added in Linux %s).\n\n",
helper.name, helper.required_version);
}
}
}
#define ROUND_UP(x, n) (((x) + (n) - 1u) & ~((n) - 1u))
int bpf_obj_get_info(int prog_map_fd, void *info, uint32_t *info_len)
{
union bpf_attr attr;
int err;
memset(&attr, 0, sizeof(attr));
attr.info.bpf_fd = prog_map_fd;
attr.info.info_len = *info_len;
attr.info.info = ptr_to_u64(info);
err = syscall(__NR_bpf, BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr));
if (!err)
*info_len = attr.info.info_len;
return err;
}