Commit 17e3ac81 authored by Yonghong Song's avatar Yonghong Song Committed by Daniel Borkmann

bpf: fix bpffs bitfield pretty print

Commit 9d5f9f70 ("bpf: btf: fix struct/union/fwd types
with kind_flag") introduced kind_flag and used bitfield_size
in the btf_member to directly pretty print member values.

The commit contained a bug where the incorrect parameters could be
passed to function btf_bitfield_seq_show(). The bits_offset
parameter in the function expects a value less than 8.
Instead, the member offset in the structure is passed.

The below is btf_bitfield_seq_show() func signature:
  void btf_bitfield_seq_show(void *data, u8 bits_offset,
                             u8 nr_bits, struct seq_file *m)
both bits_offset and nr_bits are u8 type. If the bitfield
member offset is greater than 256, incorrect value will
be printed.

This patch fixed the issue by calculating correct proper
data offset and bits_offset similar to non kind_flag case.

Fixes: 9d5f9f70 ("bpf: btf: fix struct/union/fwd types with kind_flag")
Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
Signed-off-by: default avatarYonghong Song <yhs@fb.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent beaf3d19
...@@ -1219,8 +1219,6 @@ static void btf_bitfield_seq_show(void *data, u8 bits_offset, ...@@ -1219,8 +1219,6 @@ static void btf_bitfield_seq_show(void *data, u8 bits_offset,
u8 nr_copy_bits; u8 nr_copy_bits;
u64 print_num; u64 print_num;
data += BITS_ROUNDDOWN_BYTES(bits_offset);
bits_offset = BITS_PER_BYTE_MASKED(bits_offset);
nr_copy_bits = nr_bits + bits_offset; nr_copy_bits = nr_bits + bits_offset;
nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits); nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits);
...@@ -1255,7 +1253,9 @@ static void btf_int_bits_seq_show(const struct btf *btf, ...@@ -1255,7 +1253,9 @@ static void btf_int_bits_seq_show(const struct btf *btf,
* BTF_INT_OFFSET() cannot exceed 64 bits. * BTF_INT_OFFSET() cannot exceed 64 bits.
*/ */
total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data); total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data);
btf_bitfield_seq_show(data, total_bits_offset, nr_bits, m); data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
bits_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
btf_bitfield_seq_show(data, bits_offset, nr_bits, m);
} }
static void btf_int_seq_show(const struct btf *btf, const struct btf_type *t, static void btf_int_seq_show(const struct btf *btf, const struct btf_type *t,
...@@ -2001,12 +2001,12 @@ static void btf_struct_seq_show(const struct btf *btf, const struct btf_type *t, ...@@ -2001,12 +2001,12 @@ static void btf_struct_seq_show(const struct btf *btf, const struct btf_type *t,
member_offset = btf_member_bit_offset(t, member); member_offset = btf_member_bit_offset(t, member);
bitfield_size = btf_member_bitfield_size(t, member); bitfield_size = btf_member_bitfield_size(t, member);
bytes_offset = BITS_ROUNDDOWN_BYTES(member_offset);
bits8_offset = BITS_PER_BYTE_MASKED(member_offset);
if (bitfield_size) { if (bitfield_size) {
btf_bitfield_seq_show(data, member_offset, btf_bitfield_seq_show(data + bytes_offset, bits8_offset,
bitfield_size, m); bitfield_size, m);
} else { } else {
bytes_offset = BITS_ROUNDDOWN_BYTES(member_offset);
bits8_offset = BITS_PER_BYTE_MASKED(member_offset);
ops = btf_type_ops(member_type); ops = btf_type_ops(member_type);
ops->seq_show(btf, member_type, member->type, ops->seq_show(btf, member_type, member->type,
data + bytes_offset, bits8_offset, m); data + bytes_offset, bits8_offset, m);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment