Ilya Leoshkevich d9b8aadaff bpf: fix narrower loads on s390
The very first check in test_pkt_md_access is failing on s390, which
happens because loading a part of a struct __sk_buff field produces
an incorrect result.

The preprocessed code of the check is:

{
	__u8 tmp = *((volatile __u8 *)&skb->len +
		((sizeof(skb->len) - sizeof(__u8)) / sizeof(__u8)));
	if (tmp != ((*(volatile __u32 *)&skb->len) & 0xFF)) return 2;
};

clang generates the following code for it:

      0:	71 21 00 03 00 00 00 00	r2 = *(u8 *)(r1 + 3)
      1:	61 31 00 00 00 00 00 00	r3 = *(u32 *)(r1 + 0)
      2:	57 30 00 00 00 00 00 ff	r3 &= 255
      3:	5d 23 00 1d 00 00 00 00	if r2 != r3 goto +29 <LBB0_10>

Finally, verifier transforms it to:

  0: (61) r2 = *(u32 *)(r1 +104)
  1: (bc) w2 = w2
  2: (74) w2 >>= 24
  3: (bc) w2 = w2
  4: (54) w2 &= 255
  5: (bc) w2 = w2

The problem is that when verifier emits the code to replace a partial
load of a struct __sk_buff field (*(u8 *)(r1 + 3)) with a full load of
struct sk_buff field (*(u32 *)(r1 + 104)), an optional shift and a
bitwise AND, it assumes that the machine is little endian and
incorrectly decides to use a shift.

Adjust shift count calculation to account for endianness.

Fixes: 31fd85816dbe ("bpf: permits narrower load from bpf program context fields")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2019-07-23 13:59:33 -07:00
..
2019-07-23 13:59:33 -07:00
2019-07-12 15:13:55 -07:00
2019-07-08 18:55:42 -07:00
2019-07-08 18:55:42 -07:00
2019-07-08 18:55:42 -07:00
2019-05-28 17:46:43 -04:00
2019-07-08 19:19:37 -07:00
2019-07-11 10:09:44 -07:00
2019-06-03 11:50:18 +02:00
2019-05-24 20:16:01 +02:00
2019-05-24 20:16:01 +02:00
2019-07-10 22:17:21 -07:00
2019-07-08 09:54:55 -07:00
2019-07-10 22:17:21 -07:00
2019-07-08 19:36:47 -07:00
2019-07-08 19:36:47 -07:00
2019-04-18 14:05:51 +02:00