aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2019-01-10 14:14:00 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2019-01-11 04:40:54 -0500
commit17e3ac812541f73224299d8958ddb420c2d5bbd8 (patch)
treeb6fe6e825c88f12b2e2a20f711701af97af15b86
parentbeaf3d1901f4ea46fbd5c9d857227d99751de469 (diff)
bpf: fix bpffs bitfield pretty print
Commit 9d5f9f701b18 ("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: 9d5f9f701b18 ("bpf: btf: fix struct/union/fwd types with kind_flag") Acked-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--kernel/bpf/btf.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 715f9fcf4712..a2f53642592b 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -1219,8 +1219,6 @@ static void btf_bitfield_seq_show(void *data, u8 bits_offset,
1219 u8 nr_copy_bits; 1219 u8 nr_copy_bits;
1220 u64 print_num; 1220 u64 print_num;
1221 1221
1222 data += BITS_ROUNDDOWN_BYTES(bits_offset);
1223 bits_offset = BITS_PER_BYTE_MASKED(bits_offset);
1224 nr_copy_bits = nr_bits + bits_offset; 1222 nr_copy_bits = nr_bits + bits_offset;
1225 nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits); 1223 nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits);
1226 1224
@@ -1255,7 +1253,9 @@ static void btf_int_bits_seq_show(const struct btf *btf,
1255 * BTF_INT_OFFSET() cannot exceed 64 bits. 1253 * BTF_INT_OFFSET() cannot exceed 64 bits.
1256 */ 1254 */
1257 total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data); 1255 total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data);
1258 btf_bitfield_seq_show(data, total_bits_offset, nr_bits, m); 1256 data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
1257 bits_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
1258 btf_bitfield_seq_show(data, bits_offset, nr_bits, m);
1259} 1259}
1260 1260
1261static void btf_int_seq_show(const struct btf *btf, const struct btf_type *t, 1261static 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 2001
2002 member_offset = btf_member_bit_offset(t, member); 2002 member_offset = btf_member_bit_offset(t, member);
2003 bitfield_size = btf_member_bitfield_size(t, member); 2003 bitfield_size = btf_member_bitfield_size(t, member);
2004 bytes_offset = BITS_ROUNDDOWN_BYTES(member_offset);
2005 bits8_offset = BITS_PER_BYTE_MASKED(member_offset);
2004 if (bitfield_size) { 2006 if (bitfield_size) {
2005 btf_bitfield_seq_show(data, member_offset, 2007 btf_bitfield_seq_show(data + bytes_offset, bits8_offset,
2006 bitfield_size, m); 2008 bitfield_size, m);
2007 } else { 2009 } else {
2008 bytes_offset = BITS_ROUNDDOWN_BYTES(member_offset);
2009 bits8_offset = BITS_PER_BYTE_MASKED(member_offset);
2010 ops = btf_type_ops(member_type); 2010 ops = btf_type_ops(member_type);
2011 ops->seq_show(btf, member_type, member->type, 2011 ops->seq_show(btf, member_type, member->type,
2012 data + bytes_offset, bits8_offset, m); 2012 data + bytes_offset, bits8_offset, m);