iovisor / bcc

BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more
Apache License 2.0
20.57k stars 3.88k forks source link

Overflow in string_to_leaf conversion #1454

Open mauriciovasquezbernal opened 6 years ago

mauriciovasquezbernal commented 6 years ago

Hello,

There is an overflow in the conversion from string to leaf. The following code shows the problem:

#include <bcc/BPF.h>
#include <iostream>

const std::string BPF_PROGRAM1 = R"(
BPF_TABLE("array", int, uint64_t, myarray, 1);
)";

int main(void) {
  ebpf::BPF bpf1;
  ebpf::StatusTuple res(0);

  res = bpf1.init(BPF_PROGRAM1);
  if (res.code() != 0) {
    std::cout << "error on init " << std::endl;
    return -1;
  }

  auto table = bpf1.get_table("myarray");

  //std::string value_str = "0x7FFFFFFFFFFFFFFE"; // works
  std::string value_str = "0x8000000000000000"; // doesn't work -> prints 7fffffffffffffff
  //std::string value_str = "0xFFFFFFFFFFFFFFFFF"; // doesn't work -> prints 7fffffffffffffff
  uint64_t value = 0;
  table.string_to_leaf(value_str, (void *) &value);
  std::cout << std::hex << value << std::endl;

  return 0;
}

The code prints 7fffffffffffffff for any value greater than it.

@drzaeus77 could you please have a look? Thanks.

yonghong-song commented 6 years ago

Yes, there is a bug here. I can reproduce. I will try to fix the issue soon.

yonghong-song commented 6 years ago

The following code can work around your issue:

  //std::string value_str = "0x7FFFFFFFFFFFFFFE"; // works
  //std::string value_str = "0x8000000000000000"; // doesn't work -> prints 7fffffffffffffff
  //std::string value_str = "0xFFFFFFFFFFFFFFFFF"; // doesn't work -> prints 7fffffffffffffff
  std::string value_str = "-0x8000000000000000"; // work -> prints 8000000000000000
  // std::string value_str = "-1"; // work -> prints FFFFFFFFFFFFFFFF
  uint64_t value = 0;
  table.string_to_leaf(value_str, (void *) &value);
  std::cout << std::hex << value << std::endl;

The problem is internally sscanf uses "%li" to get the value and maximum value it will print is 0x7fffffffffffffff. We cannot change to "%lu" as for "u" it only accepts base 10 number (e.g., 0x7f for "%lu" will be recognized as 0 instead of 255). "%lx" will force user to use 0x### format which is not desirable either.

I guess we may need to document this limitation somewhere.