• Yonghong Song's avatar
    tools/bpftool: fix a percpu_array map dump problem · 573b3aa6
    Yonghong Song authored
    I hit the following problem when I tried to use bpftool
    to dump a percpu array.
    
      $ sudo ./bpftool map show
      61: percpu_array  name stub  flags 0x0
              key 4B  value 4B  max_entries 1  memlock 4096B
      ...
      $ sudo ./bpftool map dump id 61
      bpftool: malloc.c:2406: sysmalloc: Assertion
      `(old_top == initial_top (av) && old_size == 0) || \
       ((unsigned long) (old_size) >= MINSIZE && \
       prev_inuse (old_top) && \
       ((unsigned long) old_end & (pagesize - 1)) == 0)'
      failed.
      Aborted
    
    Further debugging revealed that this is due to
    miscommunication between bpftool and kernel.
    For example, for the above percpu_array with value size of 4B.
    The map info returned to user space has value size of 4B.
    
    In bpftool, the values array for lookup is allocated like:
       info->value_size * get_possible_cpus() = 4 * get_possible_cpus()
    In kernel (kernel/bpf/syscall.c), the values array size is
    rounded up to multiple of 8.
       round_up(map->value_size, 8) * num_possible_cpus()
       = 8 * num_possible_cpus()
    So when kernel copies the values to user buffer, the kernel will
    overwrite beyond user buffer boundary.
    
    This patch fixed the issue by allocating and stepping through
    percpu map value array properly in bpftool.
    
    Fixes: 71bb428f ("tools: bpf: add bpftool")
    Signed-off-by: default avatarYonghong Song <yhs@fb.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    573b3aa6
map.c 18.6 KB