diff options
| author | Jakub Sitnicki <[email protected]> | 2022-03-17 12:39:20 +0100 | 
|---|---|---|
| committer | Daniel Borkmann <[email protected]> | 2022-03-18 15:46:59 +0100 | 
| commit | deb59400464468352b4d7827420e04f1add94726 (patch) | |
| tree | 0c5f7fffe2b308ba022fd0263a5cb412a88c0e09 /scripts/gdb/linux/utils.py | |
| parent | e06b5bbcf3f107fb5e148714efe2decfb3b4e0ac (diff) | |
selftests/bpf: Fix test for 4-byte load from dst_port on big-endian
The check for 4-byte load from dst_port offset into bpf_sock is failing on
big-endian architecture - s390. The bpf access converter rewrites the
4-byte load to a 2-byte load from sock_common at skc_dport offset, as shown
below.
  * s390 / llvm-objdump -S --no-show-raw-insn
  00000000000002a0 <sk_dst_port__load_word>:
        84:       r1 = *(u32 *)(r1 + 48)
        85:       w0 = 1
        86:       if w1 == 51966 goto +1 <LBB5_2>
        87:       w0 = 0
  00000000000002c0 <LBB5_2>:
        88:       exit
  * s390 / bpftool prog dump xlated
  _Bool sk_dst_port__load_word(struct bpf_sock * sk):
    35: (69) r1 = *(u16 *)(r1 +12)
    36: (bc) w1 = w1
    37: (b4) w0 = 1
    38: (16) if w1 == 0xcafe goto pc+1
    39: (b4) w0 = 0
    40: (95) exit
  * x86_64 / llvm-objdump -S --no-show-raw-insn
  00000000000002a0 <sk_dst_port__load_word>:
        84:       r1 = *(u32 *)(r1 + 48)
        85:       w0 = 1
        86:       if w1 == 65226 goto +1 <LBB5_2>
        87:       w0 = 0
  00000000000002c0 <LBB5_2>:
        88:       exit
  * x86_64 / bpftool prog dump xlated
  _Bool sk_dst_port__load_word(struct bpf_sock * sk):
    33: (69) r1 = *(u16 *)(r1 +12)
    34: (b4) w0 = 1
    35: (16) if w1 == 0xfeca goto pc+1
    36: (b4) w0 = 0
    37: (95) exit
This leads to surprises if we treat the destination register contents as a
32-bit value, ignoring the fact that in reality it contains a 16-bit value.
On little-endian the register contents reflect the bpf_sock struct
definition, where the lower 16-bits contain the port number:
	struct bpf_sock {
		...
		__be16 dst_port;	/* offset 48 */
		__u16 :16;
		...
	};
However, on big-endian the register contents suggest that field the layout
of bpf_sock struct is as so:
	struct bpf_sock {
		...
		__u16 :16;		/* offset 48 */
		__be16 dst_port;
		...
	};
Account for this quirky access conversion in the test case exercising the
4-byte load by treating the result as 16-bit wide.
Signed-off-by: Jakub Sitnicki <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
Acked-by: Martin KaFai Lau <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
Diffstat (limited to 'scripts/gdb/linux/utils.py')
0 files changed, 0 insertions, 0 deletions